Python 3 线程和队列

Python 3 threading and queueing

我一直在为两个 class 之间的线程、队列和传递数据的概念而苦恼。我在这里和互联网上搜索过,但没有找到任何能满足我需要的东西。

基本上我有一些代码可以在一个线程中打开一个图形用户界面,当你点击开始时它会打开另一个重要的线程。

我最大的两个问题是:

  1. 如何更新 GUI class 中的标签以显示其他 class 的输出?
  2. 如何停止计数线程并重新启动它?

这是我所能得到的:

import tkinter as tk
import threading
import queue
import time

class GUI(object):
    """GUI Object"""
    def __init__(self):        
        self.root = tk.Tk()
        self.root.title("Window")

        self.root.status_lbl = tk.Label(self.root, text = "Label", width = 30)
        self.root.status_lbl.grid(row = 0, column = 0)

        self.root.start = tk.Button(self.root, text = "Start", width = 30, command = self.doing_things)
        self.root.start.grid(row = 1, column = 0)

        self.root.stop = tk.Button(self.root, text = "Stop", width = 30, command = None)
        self.root.stop.grid(row = 2, column = 0)

        self.root.mainloop()

    def doing_things(self):
        self.root.start.config(state = 'disabled')
        Other_thread = threading.Thread(None, Other)
        Other_thread.start()

class Other(object):
    """Something Else"""
    def __init__(self):   
        self.msg2 = "Other Thread"

        self.doing_things()

    def doing_things(self):
        count = 0
        while 1 == 1:
            count += 1
            data = (self.msg2 + " " + str(count))
            print(data)
            time.sleep(1)

GUI_thread = threading.Thread(None, GUI)

GUI_thread.start()

任何帮助都会很棒,这让我发疯。

更新:

所以这回答了我的两个问题并且做得很好:

import tkinter as tk
import threading
import queue
import time

class GUI(object):
    """GUI Object"""
    def __init__(self):        
        self.root = tk.Tk()
        self.root.title("Window")

        self.stop_flag = str

        self.status = tk.StringVar()
        self.status.set("plop")
        self.root.status_lbl = tk.Label(self.root, textvariable=self.status, width = 30)
        self.root.status_lbl.grid(row = 0, column = 0)

        self.root.start = tk.Button(self.root, text = "Start", width = 30, command = self.doing_things)
        self.root.start.grid(row = 1, column = 0)

        self.root.stop = tk.Button(self.root, text = "Stop", width = 30, command = self.stop)
        self.root.stop.grid(row = 2, column = 0)

        self.root.mainloop()

    def doing_things(self):
        self.stop_flag = False
        self.root.start.config(state = 'disabled')
        Other_thread = threading.Thread(None, Other, args=(self,))
        Other_thread.start()

    def stop(self):
        self.root.start.config(state = 'normal')
        self.stop_flag = True


class Other(object):
    """Something Else"""
    def __init__(self, gui):
        self.count = 0

        self.gui = gui
        self.msg2 = "Other Thread"

        self.doing_things()

    def doing_things(self):
        count = self.count
        while not self.gui.stop_flag:
            count += 1
            data = (self.msg2 + " " + str(count))
            print(data)
            self.gui.status.set(data)
            time.sleep(1)

GUI_thread = threading.Thread(None, GUI)

GUI_thread.start()

唯一让我感到困惑的是 self 后面需要逗号:

Other_thread = threading.Thread(None, Other, args=(self,))

这是从其他线程更改标签的简单方法。 使用 StringVar 而不是固定字符串。然后在启动时将 GUI 实例传递给另一个线程。最后,您可以从其他线程设置文本。

import tkinter as tk
import threading
import queue
import time

class GUI(object):
    """GUI Object"""
    def __init__(self):        
        self.root = tk.Tk()
        self.root.title("Window")

        self.status = tk.StringVar()
        self.status.set("plop")
        self.root.status_lbl = tk.Label(self.root, textvariable=self.status, width = 30)
        self.root.status_lbl.grid(row = 0, column = 0)

        self.root.start = tk.Button(self.root, text = "Start", width = 30, command = self.doing_things)
        self.root.start.grid(row = 1, column = 0)

        self.root.stop = tk.Button(self.root, text = "Stop", width = 30, command = None)
        self.root.stop.grid(row = 2, column = 0)

        self.root.mainloop()

    def doing_things(self):
        self.root.start.config(state = 'disabled')
        Other_thread = threading.Thread(None, Other, args=(self,))
        Other_thread.start()

class Other(object):
    """Something Else"""
    def __init__(self, gui):   
        self.gui = gui
        self.msg2 = "Other Thread"

        self.doing_things()

    def doing_things(self):
        count = 0
        while 1 == 1:
            count += 1
            data = (self.msg2 + " " + str(count))
            print(data)
            self.gui.status.set(data)
            time.sleep(1)

GUI_thread = threading.Thread(None, GUI)

GUI_thread.start()