python - wxpython - 在不阻塞 GUI 的情况下按顺序运行线程

标签 python multithreading wxpython

我有一个 GUI 脚本,里面有我所有的 wxPython 代码,还有一个单独的 testSequences 模块,它有一堆我根据来自 GUI 的输入运行的任务。这些任务需要很长时间才能完成(从 20 秒到 3 分钟),所以我想对它们进行线程化,否则 GUI 在它们运行时会锁定。我还需要它们一个接一个地运行,因为它们都使用相同的硬件。 (我在线程背后的基本原理只是为了防止 GUI 锁定。)我想要一条“正在运行”的消息(后面有不同数量的句点,即“正在运行”、“正在运行。”、“正在运行...... "等)这样用户就知道正在发生进展,即使它是不可见的。我希望此脚本在单独的线程中按顺序运行测试序列,以便在第一个线程完成之前不会创建和运行第二个线程。由于这与线程的目的有点相反,我真的找不到任何关于如何做到这一点的信息...任何帮助将不胜感激。

提前致谢!

GUI.py

import testSequences
from threading import Thread

#wxPython code for setting everything up here...
for j in range(5):
    testThread = Thread(target=testSequences.test1)
    testThread.start()
    while testThread.isAlive():
        #wait until the previous thread is complete
        time.sleep(0.5)
        i = (i+1) % 4
        self.status.SetStatusText("Running"+'.'*i)

测试序列.py

import time
def test1():
    for i in range(10):
        print i
        time.sleep(1)

(显然这不是实际的测试代码,但思路是一样的。)

最佳答案

您不能在 GUI 线程中使用 while 循环等待,因为您阻塞了事件队列的处理。一种解决方案是使用计时器轮询线程的状态:

import wx 
import time
from threading import Thread

def test1():
    for i in range(10):
        print i
        time.sleep(1)

class TestFrame(wx.Frame): 
    def __init__(self): 
        wx.Frame.__init__(self, None, -1, "Test") 
        panel = wx.Panel(self, -1) 
        sizer = wx.BoxSizer(wx.VERTICAL) 
        panel.SetSizer(sizer) 

        self.button = wx.Button(panel, 0, "Start")
        sizer.Add(self.button, 0, wx.ALIGN_LEFT) 
        self.button.Bind(wx.EVT_BUTTON, self.OnButton)

        self.text = wx.StaticText(panel, 0, "No test is running")
        sizer.Add(self.text, 0, wx.ALIGN_LEFT) 

        self.timer = wx.Timer(self)

    def OnButton(self, event):
        self.testThread = Thread(target=test1)
        self.testThread.start()
        self.text.SetLabel("Running")
        self.button.Disable()
        self.Bind(wx.EVT_TIMER, self.PollThread)
        self.timer.Start(20, oneShot=True)
        event.Skip()

    def PollThread(self, event):
        if self.testThread.isAlive():
            self.Bind(wx.EVT_TIMER, self.PollThread)
            self.timer.Start(200, oneShot=True)
            self.text.SetLabel(self.text.GetLabel() + ".")
        else:
            self.button.Enable()
            self.text.SetLabel("Test completed")


app = wx.PySimpleApp() 
TestFrame().Show() 
app.MainLoop()

关于python - wxpython - 在不阻塞 GUI 的情况下按顺序运行线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12867138/

相关文章:

python - 用 Python 控制音乐和视频

wxpython - wxWidgets 的间距/空边框

linux - wxPython -- 转义的 & 符号在 Linux 中仍然不显示

python - 将固定长度的单词与未知字符的已知顺序进行匹配

python - 从 sqlite 查询中删除格式

python - 如何使用 VisPy 库实时绘图?

multithreading - 在多线程中使用没有 Arc 的 Mutex 是否安全?

Python OpenCV 绘制线宽

c# - 使我的 COM 程序集调用异步

java - RxJava2多线程或者出现问题