10 import threading, Queue
31 tk.Frame.__init__(self, parent, *args, **kw)
34 self.columnconfigure(0, weight=1)
35 self.rowconfigure(0, weight=1)
37 vscrollbar = tk.Scrollbar(self, orient=tk.VERTICAL)
38 vscrollbar.grid(column=1, row=0, sticky=tk.E+tk.N+tk.S)
40 canvas = tk.Canvas(self, bd=0, highlightthickness=0, yscrollcommand=vscrollbar.set)
41 canvas.grid(column=0, row=0, sticky=tk.W+tk.E+tk.N+tk.S)
42 vscrollbar.config(command=canvas.yview)
44 canvas.xview_moveto(0)
45 canvas.yview_moveto(0)
51 interior_id = canvas.create_window(0, 0, window=interior, anchor=tk.NW)
56 def _configure_interior(event):
59 size = (interior.winfo_reqwidth(), interior.winfo_reqheight())
60 canvas.config(scrollregion=
"0 0 %s %s" % size)
61 if interior.winfo_reqwidth() != canvas.winfo_width():
63 canvas.config(width=interior.winfo_reqwidth())
64 interior.bind(
'<Configure>', _configure_interior)
67 def _configure_canvas(event):
69 if interior.winfo_reqwidth() != canvas.winfo_width():
71 canvas.itemconfigure(interior_id, width=canvas.winfo_width())
72 canvas.bind(
'<Configure>', _configure_canvas)
88 def __init__(self, symbol, dict_input, master=None):
89 tk.Frame.__init__(self, master)
90 self.
_logger_ = logging.getLogger(
'SP.ValidationtTk')
91 self._logger_.debug(
"init ValidationTkinter")
100 top=self.winfo_toplevel()
102 top.protocol(
"WM_DELETE_WINDOW", self.
quit_app)
105 top.columnconfigure(0, weight=1)
106 top.rowconfigure(0, weight=1)
107 self.columnconfigure(0, weight=1)
111 self.grid(sticky=tk.N+tk.S+tk.E+tk.W)
114 self.master.title(
'User validation')
133 min_win_width = self.winfo_reqwidth()
134 min_win_height = self.winfo_reqheight()
136 self.master.minsize(width=min_win_width, height=min_win_height)
140 self._logger_.debug(
"Entry createWidgets")
148 for key_action, value_action
in self._dict_input.iteritems():
149 self._logger_.debug(
"key_action %s" % key_action)
155 label_frame = tk.LabelFrame(self, text=key_action)
156 label_frame.grid(sticky=tk.E+tk.W+tk.N+tk.S, pady=8,padx=5)
160 if 0
in value_action:
164 self._logger_.debug(
"scrollable %s" % scrollable)
170 self.rowconfigure(row_action_nb, weight=1)
172 label_frame.columnconfigure(0, weight=1)
174 label_frame.rowconfigure(0, weight=1)
178 self.
action_frame[key_action].interior.columnconfigure(0, weight=1)
182 label_frame.columnconfigure(2, weight=1,minsize=100 )
186 self.
action_frame[key_action].grid(sticky=tk.E+tk.W+tk.N+tk.S)
190 for key_value, value_value
in value_action.iteritems():
193 state = value_value[
'repl_add']
207 self._logger_.debug(
"Valid")
209 for key_action, value_action
in self._var_radiob.iteritems():
210 for value
in self.
_var_radiob[key_action].values():
212 if not ((value.get() == 0) | (value.get() == 2)):
214 self.
popupmsg(
"All entries must be selected as Accepted or Rejected to continue,\nor press Quit to validate the default")
218 for key_action
in self._var_radiob.keys():
222 self.
_dict_input[key_action][name][
'repl_add'] = value.get()
235 self._logger_.debug(
"i value: %d, %s" % (i, values))
242 tk.Label( action_frame, text=key_value).grid(column=0, row=i, sticky=tk.W, padx=5, pady=2)
243 tk.Label( action_frame, text=values[
'xml_value']).grid(column=1, row=i, sticky=tk.W, padx=5, pady=2)
245 tk.Label( action_frame, text=values[
'new_value']).grid(column=2, row=i, sticky=tk.W, padx=5, pady=2)
247 tk.Radiobutton( action_frame, text=
'Rej.', variable=var, value=0).grid(column=3, row=i, sticky=tk.E)
248 tk.Radiobutton( action_frame, text=
'Acc.', variable=var, value=2).grid(column=4, row=i, sticky=tk.E)
271 one_entry_frame = tk.Frame( action_frame.interior )
273 one_entry_frame.columnconfigure(2, weight=1, minsize=80 )
274 one_entry_frame.grid( row=i, sticky=tk.W+tk.E+tk.N+tk.S, pady=5, padx=5 )
277 tk.Label( one_entry_frame, text=
'from %s' % values[
'first_date']) .grid()
280 f = values[
'first_values']
281 format_values =
'%7.2f %7.2f %7.2f %7.2f %9.2e' % (f[1], f[2], f[3], f[4], f[5])
282 tk.Label( one_entry_frame, text=format_values ).grid(column=1, row=0, sticky=tk.E)
284 tk.Label( one_entry_frame, text=
' to %s' % values[
'last_date']).grid(sticky=tk.E)
285 f = values[
'last_values']
286 format_values =
'%7.2f %7.2f %7.2f %7.2f %9.2e' % (f[1], f[2], f[3], f[4], f[5])
287 tk.Label( one_entry_frame, text=format_values ).grid(column=1, row=1, sticky=tk.E)
290 tk.Label( one_entry_frame, text=values[
'error'], fg=color_lab).grid(column=2, row=0, rowspan=2, sticky=tk.W)
293 tk.Radiobutton( one_entry_frame, text=
'Rej.', variable=var, value=0).grid(column=3, row=0, rowspan=2, sticky=tk.W)
294 tk.Radiobutton( one_entry_frame, text=
'Acc..', variable=var, value=2).grid(column=4, row=0, rowspan=2, sticky=tk.W)
299 tk.Label(self,text=title,font=(
'Helvetica',12,
'bold'), padx=5,pady=5).grid()
304 frame_button = tk.Frame(self, pady=10)
307 tk.Button(frame_button, text=
'Valid', command=self.
valid).grid(column=0, row=0)
308 tk.Button(frame_button, text=
'Quit', command=self.
quit_app).grid(column=1, row=0)
313 tkMessageBox.showwarning(
"warning", msg)
351 self._logger_.debug(
"init ManagerTk")
371 self.queue.put(new_entry)
375 assert self.queue_answer.qsize() <= 1,
"Error in queue size "
376 return self.queue_answer.get()
388 self._logger_.debug(
"Entry update_me")
392 new_entry = self.queue.get()
394 if new_entry[0] ==
"QUIT":
404 self._logger_.debug(
"return from mainloop, put result in answer queue")
407 self.queue_answer.put( dict )
411 self._logger_.debug(
"stop the manager")
412 assert self.queue.empty() ==
True,
"Error with queue"
413 assert self.queue_answer.empty() ==
True,
"Error with queue"
417 if __name__ ==
"__main__":
421 logging.basicConfig(level=logging.DEBUG)
422 logging.getLogger(
'SP')
423 m_logger = logging.getLogger(
"SP.main")
427 'Info': {
'Sector': {
'xml_value':
'Energy',
'new_value':
'Utilities',
'date':
'2015-03-03',
'source':
'YQL',
'repl_add': 0},
428 'StockExchange': {
'xml_value':
None,
'new_value':
'Paris',
'date':
'2015-03-03',
'source':
'YQL',
'repl_add': 2}
430 'Other': {
'Industry': {
'xml_value':
None,
'new_value':
'Diversified Utilities',
'date':
'2015-03-03',
'source':
'YQL',
'repl_add': 2},
431 'Name': {
'xml_value':
'Toto',
'new_value':
'GDF SUEZ',
'date':
'2015-03-03',
'source':
'YQL',
'repl_add': 1}
508 def m_run_thread(stock, man_tk):
509 print "Start thread name", threading.current_thread().name
510 print "tk_app ref", man_tk
513 print "send new message to the queue"
514 man_tk.write( [ stock, m_test ])
515 print "thread waiting answer", threading.current_thread().name
516 new_dict = man_tk.read_answer()
517 print "modified dict ", new_dict
519 def m_thd_pool_run(list_stock, man_tk):
520 print "Entry thd_pool_run name", threading.current_thread().name
523 print "thd_pool creates a pool of thread"
525 for stock
in list_stock:
527 t = threading.Thread(target=m_run_thread, name=
"thread_"+stock, args = (stock, man_tk))
528 thread_list.append(t)
530 for th
in thread_list:
534 for th
in thread_list:
537 print "thd_pool all joined, send quit signal"
538 man_tk.write([
"QUIT"])
539 print "thd_pool will die..."
541 print "\n== Starting program, master create Tk app"
544 print "manager_tk ", m_manager_tk
545 m_list_stock = [
"GSZ",
"CAC40"]
547 print "\n== master creates thread pool"
548 m_thd_pool = threading.Thread(target=m_thd_pool_run, args=(m_list_stock, m_manager_tk))
552 print "\n== master after sleep, run the manager"
555 m_manager_tk.update_me()
557 print "\n==master app has been killed"
558 print "thd_pool alive ?", m_thd_pool.is_alive()
560 print "end of test, quit"
def create_title
Label with stock symbol.
Manage and serialize the access to a ValidationTkinter application, necessary when UpdateStock is run...
def update_me
Check regularly and indefinitely, the queue.
def _check_stop
Check state of the object before stopping.
def create_one_input_xml
Fill the frame specific to xml data: Info / Fundamental.
A pure Tkinter scrollable frame that actually works!.
_root_tk
store a Tk main environment.
def valid
Check all radio buttons have been selected and update repl_add entry with _var_radiob.
queue_answer
new result data.
def create_button_valid
Create Valid and Quit buttons at the bottom of the main window.
queue
Queue to receive and send data (dict_interactive and stock symbol).
def popupmsg
Message indicating that some entries have not been validated.
_var_radiob
store in dictionary all IntVar associated to radio buttons.
def create_one_input_csv
Fill the frame for list_csv : HistPrice Last version, group similar entries.
GUI interface to validate the update and saving of data.
def create_widgets
Create the main window with the data from dict_input.
def read_answer
Return the updated dict_interactive.
def write
Write a new input to the queue.