python - Creating Toplevel widgets that are thread safe -


i'm trying learn how use thread module. followed along instructions here: http://effbot.org/zone/tkinter-threads.htm

my hope test script will:

  1. print out "count" every 2 seconds
  2. show pop-up dialog window (also every 2 seconds)
  3. the pop-ups should allowed accumulate (if don't click "ok" while, there should multiple pop-ups)

however, when run script freeze main window , after while crash. think i'm not implementing thread module correctly.

could please have , point out i'm doing wrong?

here i've tried far:

from tkinter import * import thread import queue import time  class testapp:     def __init__(self, parent):         self.super_parent = parent         self.main_container = frame(parent)         self.main_container.pack()         self.top_frame = frame(self.main_container)         self.top_frame.pack(side=top)         self.bottom_frame = frame(self.main_container)         self.bottom_frame.pack(side=top)         self.text_box = text(self.top_frame)         self.text_box.config(height=20, width=20)         self.text_box.pack()         self.queue = queue.queue()         self.update_me()      def show_popup(self):         self.my_popup = toplevel(self.main_container)         self.my_popup.geometry('100x100')         self.popup_label = label(self.my_popup, text="hello!")         self.popup_label.pack(side=top)         self.pop_button = button(self.my_popup, text="ok", command=self.my_popup.destroy)         self.pop_button.pack(side=top)      def write(self, line):         self.queue.put(line)      def update_me(self):         try:             while 1:                 line = self.queue.get_nowait()                 if line none:                     self.text_box.delete(1.0, end)                 else:                     self.text_box.insert(end, str(line))                 self.text_box.see(end)                 self.text_box.update_idletasks()         except queue.empty:             pass         self.text_box.after(100, self.update_me)  def pipetowidget(input, widget):     widget.write(input)  def start_thread():     thread.start_new(start_test, (widget,))  def start_test(widget):     count = 0     while true:         pipetowidget(str(count) + "\n", widget)         count += 1         time.sleep(2)         widget.show_popup()  root = tk() widget = testapp(root) start_button = button(widget.bottom_frame, command=start_thread) start_button.configure(text="start test") start_button.pack(side=left) root.title("testing thread module") root.mainloop() 

i can't reproduce problem, can see why happen.

you're using queue pass messages background thread main thread updating text_box, correct. you're calling widget.show_popup() background thread, means creates , displays new toplevel in background thread. that's not correct.

all ui code must run in same thread—not ui code each top-level window, ui code period. on platforms, may away running each window in own thread (or free-threading everything), isn't supposed work, , crash or improper things on platforms. (also, single ui thread has initial thread on platforms, isn't relevant here.)


so, fix this, need same dance creating popups updating textbox.

the obvious way move widget.show_popup() loop in update_me(). if want happen 2 seconds after textbox updates, add self.top_frame.after(2000, self.show_popup) method.

but i'm guessing you're trying teach how have multiple independent updating mechanisms, telling "just use single update queue everything" may not answer. in case, create 2 queues, , separate update method servicing each queue. then, pipetowidget, sleep 2 seconds, pipetopopup.


another way around use mttkinter. you're doing, makes automatic, pushing each actual tk gui call onto queue run later main loop. of course objects have thread-safe, , means have deal gui calls 1 thread getting interleaved calls thread. long neither of problem (and don't seem in case), it's magic.


if want know why freezing and/or crashing on win7 , not me on os x 10.8… well, need mess of tcl, c, , python code, , @ how each thing built. and, unless it's simple (like tk build isn't free-threaded), wouldn't tell anyway. code isn't supposed work, , if seems work me… means work every time until important demo of career, @ point fail.


Comments

Popular posts from this blog

ios - iPhone/iPad different view orientations in different views , and apple approval process -

java Extracting Zip file -

C# WinForm - loading screen -