Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2"""
3@file
5@brief building windows to use a function and specify its parameter based on a python function
6"""
7import os
8import warnings
9import tkinter
10import tkinter.tix as ttix # pylint: disable=W0402
11from tkinter import TclError
12from .tk_window import create_tixtk
13from .frame_function import FrameFunction
14from .storing_functions import get_icon
17class MainFrame(tkinter.Frame):
19 """
20 Creates a Frame window to select within a list of functions,
21 @see cl FrameFunction.
22 The class requires to run ``tix.Tk()`` and not ``tkinter.Tk()``.
23 Otherwise, you will see the following error:
25 ::
27 _tkinter.TclError: invalid command name "tixComboBox"
29 It is required by the use of ``ComboBox``.
30 @see fn main_loop_functions to see what the window will look like.
31 """
33 def __init__(self, parent, functions, first=None, restore=True, width=100,
34 raise_exception=False, overwrite=None, hide=False):
35 """
36 @param parent window parent
37 @param functions dictionary with a list of functions { name: function }
38 @param first first function to select
39 @param restore if True, check if existing saved parameters are present
40 @param width number of characters in every Entry field
41 @param raise_exception raise an exception instead of catching it
42 @param overwrite parameters to overwrite
43 @param hide if True, hide the window after clicking on OK
44 """
45 if overwrite is None:
46 overwrite = {}
47 tkinter.Frame.__init__(self, parent)
48 self.kparent = parent
49 self.fsel = tkinter.Frame(self)
50 self.ffun = tkinter.Frame(self)
51 hline = tkinter.Frame(self, height=10, width=800, bg="blue")
52 self.fsel.pack()
53 hline.pack()
54 self.ffun.pack()
55 self.parent = parent
57 self.varcombo = ttix.StringVar()
58 self.combo = ttix.ComboBox(self.fsel, editable=1, dropdown=1, variable=self.varcombo,
59 command=self.change_selection,
60 options="listbox.height %d label.width %d entry.width %d" % (25, 30, 50))
61 # put the text zone in read only mode
62 self.combo.entry.config(state='readonly')
63 for i, k in enumerate(sorted(functions)):
64 self.combo.insert(i, k)
65 self.combo.pack()
66 self.functionsDict = functions
68 if first is None:
69 keys = sorted(functions.keys())
70 first = keys[0]
71 firstFunction = functions[first]
73 self.params = {"restore": restore, "width": width,
74 "raise_exception": raise_exception,
75 "overwrite": overwrite, "hide": hide}
77 self.varcombo.set(first)
78 self.change_frame_function(firstFunction)
80 def run_cancel(self, *args):
81 """
82 cancel
83 """
84 try:
85 self.kparent.destroy()
86 except Exception as e:
87 if "application has been destroyed" in str(e):
88 return
89 else:
90 raise e
92 if "selected" in self.__dict__ and "server" in self.selected.__name__:
93 # trick: the server does not close itself
94 # forcing to close
95 # sys.exit() can only be used from the main thread
96 os._exit(0)
98 def get_title(self):
99 """
100 Returns the default title.
101 @return string
102 """
103 return self.frameWindow.get_title()
105 def change_frame_function(self, function):
106 """
107 Updates the frame @see cl FrameFunction to select a new function.
109 @param function a function (a pointer)
110 """
111 if "selected" not in self.__dict__ or function != self.selected:
112 self.selected = function
114 if hasattr(self, "frameWindow"):
115 self.frameWindow.pack_forget()
117 self.frameWindow = FrameFunction(self.ffun, function,
118 restore=self.params["restore"],
119 width=self.params["width"],
120 raise_exception=self.params[
121 "raise_exception"],
122 overwrite=self.params["overwrite"],
123 hide=self.params["hide"],
124 command_leave=self.run_cancel)
125 self.frameWindow.pack()
126 self.frameWindow.focus_set()
128 def change_selection(self, event):
129 """
130 Functions called when the selection changes.
131 """
132 st = self.varcombo.get()
133 if "functionsDict" in self.__dict__:
134 self.change_frame_function(self.functionsDict[st])
137def main_loop_functions(functions, first=None, restore=True, width=100,
138 raise_exception=False, overwrite=None, hide=False, title=None,
139 ico=None, init_pos=None, mainloop=True):
140 """
141 Uses @see cl MainFrame as the main window.
143 @param functions dictionary with a list of functions { name: function }
144 @param first first function to select
145 @param restore if True, check if existing saved parameters are present
146 @param width number of characters in every Entry field
147 @param raise_exception raise an exception instead of catching it
148 @param overwrite parameters to overwrite
149 @param hide if True, hide the window after clicking on OK
150 @param title if not None, overwrite the default title
151 @param ico (str) an icon or None
152 @param init_pos location of the window *(x,y)* or None
153 @param mainloop run the mainloop
154 @return main window
156 .. exref::
157 :title: Open a window to run a function from a predefined list of functions
159 ::
161 functions = {"test_regular_expression":test_regular_expression,
162 "test_edit_distance":file_grep,
163 "file_head":file_head }
164 main_loop_functions(functions, title="title: TestMakeWindow2")
166 @image images/open_functionl.png
167 """
168 if overwrite is None:
169 overwrite = {}
171 ico = get_icon() if ico is None else ico
172 root = create_tixtk()
173 try:
174 root.iconbitmap(ico)
175 except TclError:
176 warnings.warn("Unable to load icon '{0}'".format(ico))
177 fr = MainFrame(parent=root, functions=functions, first=first, restore=restore,
178 width=width, raise_exception=raise_exception, overwrite=overwrite,
179 hide=hide)
180 fr.pack()
181 root.title(fr.get_title() if title is None else title)
182 if init_pos is not None:
183 root.geometry('+%d+%d' % init_pos)
184 if mainloop:
185 fr.mainloop()
186 return fr