Abd*_*had 5 python multithreading tkinter python-multithreading python-3.x
按下按钮后我的界面冻结了。我正在使用线程,但我不确定为什么仍然挂起。任何帮助将不胜感激。提前致谢
class magic:
def __init__(self):
self.mainQueue=queue.Queue()
def addItem(self,q):
self.mainQueue.put(q)
def startConverting(self,funcName):
if(funcName=="test"):
while not self.mainQueue.empty():
t = Thread(target = self.threaded_function)
t.start()
t.join()
def threaded_function(self):
time.sleep(5)
print(self.mainQueue.get())
m=magic()
def helloCallBack():
m.addItem("asd")
m.startConverting("test") //this line of code is freezing
B = tkinter.Button(top, text ="Hello", command = helloCallBack)
B.pack()
top.mainloop()
Run Code Online (Sandbox Code Playgroud)
这是使用基于 tkinter 的 GUI 执行异步任务的秘诀。我根据所引用的书中的食谱改编了它。您应该能够修改它来执行您需要的操作。
\n为了保持 GUI 的响应能力,不需要mainloop()通过执行诸如join()后台线程\xe2\x80\x94 之类的操作来干扰它,这会使 GUI“挂起”直到线程完成。这是通过使用通用after()小部件方法定期轮询a来完成的。Queue
# from "Python Coobook 2nd Edition", section 11.9, page 439.\n# Modified to work in Python 2 & 3.\nfrom __future__ import print_function\n\ntry:\n import Tkinter as tk, time, threading, random, Queue as queue\nexcept ModuleNotFoundError: # Python 3\n import tkinter as tk, time, threading, random, queue\n\nclass GuiPart(object):\n def __init__(self, master, queue, end_command):\n self.queue = queue\n # Set up the GUI\n tk.Button(master, text=\'Done\', command=end_command).pack()\n # Add more GUI stuff here depending on your specific needs\n\n def processIncoming(self):\n """ Handle all messages currently in the queue, if any. """\n while self.queue.qsize():\n try:\n msg = self.queue.get_nowait()\n # Check contents of message and do whatever is needed. As a\n # simple example, let\'s print it (in real life, you would\n # suitably update the GUI\'s display in a richer fashion).\n print(msg)\n except queue.Empty:\n # just on general principles, although we don\'t expect this\n # branch to be taken in this case, ignore this exception!\n pass\n\n\nclass ThreadedClient(object):\n """\n Launch the main part of the GUI and the worker thread. periodic_call()\n and end_application() could reside in the GUI part, but putting them\n here means that you have all the thread controls in a single place.\n """\n def __init__(self, master):\n """\n Start the GUI and the asynchronous threads. We are in the main\n (original) thread of the application, which will later be used by\n the GUI as well. We spawn a new thread for the worker (I/O).\n """\n self.master = master\n # Create the queue\n self.queue = queue.Queue()\n\n # Set up the GUI part\n self.gui = GuiPart(master, self.queue, self.end_application)\n\n # Set up the thread to do asynchronous I/O\n # More threads can also be created and used, if necessary\n self.running = True\n self.thread1 = threading.Thread(target=self.worker_thread1)\n self.thread1.start()\n\n # Start the periodic call in the GUI to check the queue\n self.periodic_call()\n\n def periodic_call(self):\n """ Check every 200 ms if there is something new in the queue. """\n self.master.after(200, self.periodic_call)\n self.gui.processIncoming()\n if not self.running:\n # This is the brutal stop of the system. You may want to do\n # some cleanup before actually shutting it down.\n import sys\n sys.exit(1)\n\n def worker_thread1(self):\n """\n This is where we handle the asynchronous I/O. For example, it may be\n a \'select()\'. One important thing to remember is that the thread has\n to yield control pretty regularly, be it by select or otherwise.\n """\n while self.running:\n # To simulate asynchronous I/O, create a random number at random\n # intervals. Replace the following two lines with the real thing.\n time.sleep(rand.random() * 1.5)\n msg = rand.random()\n self.queue.put(msg)\n\n def end_application(self):\n self.running = False # Stops worker_thread1 (invoked by "Done" button).\n\nrand = random.Random()\nroot = tk.Tk()\nclient = ThreadedClient(root)\nroot.mainloop()\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
4947 次 |
| 最近记录: |