0

我有一个图形用户界面的按钮'确定'和'取消'点击其中创建一个子线程弹出一个对话框说'确定/取消按钮被按下'。现在当我点击确定按钮时,我想要子线程调用它必须等待另一个进程(可能是另一个对话框说等待),然后必须弹出消息'确定按钮被按下'。 我用wx.timer为childthread等待,但无法得到它的工作。wxpython中的多处理

如何让子线程暂停并在进程完成后继续(如中断)? 下面找到我的试验!

import wx, time 
from threading import Thread 

ID_RUN = 101 
ID_RUN2 = 102 


class ChildThread_OK(Thread): 
    def __init__(self, myframe): 
    """Init Worker Thread Class.""" 
     Thread.__init__(self) 
     self.myframe = myframe 
     self._want_abort = True 

    def run(self): 
     if self._want_abort is True: 
     self.waitevent() 
     wx.CallAfter(self.myframe.AfterRun, 'Ok button pressed') 

    def waitevent(self): 
     wx.CallAfter(self.myframe.message,"Oops!!there is another process running wait for it to finish. Closing this dialog box in 2s...") 

    def closeit(self, event): 
     self.dialogBox.Destroy() 

class ChildThread_Cancel(Thread): 
    def __init__(self, myframe): 
     Thread.__init__(self) 
     self.myframe = myframe 

    def run(self): 
     wx.CallAfter(self.myframe.AfterRun, "Cancel button pressed") 


class MyFrame(wx.Frame): 
    def __init__(self, parent, ID, title): 
     wx.Frame.__init__(self, parent, ID, title) 
     panel = wx.Panel(self, -1) 
     mainSizer = wx.BoxSizer(wx.HORIZONTAL) 
     mainSizer.Add(wx.Button(panel, ID_RUN, "OK")) 
     mainSizer.Add(wx.Button(panel, ID_RUN2, "Cancel")) 
     panel.SetSizer(mainSizer) 
     mainSizer.Fit(self) 
     wx.EVT_BUTTON(self, ID_RUN, self.onRun) 
     wx.EVT_BUTTON(self, ID_RUN2, self.onRun2) 

    def onRun(self, event): 
     self.child = ChildThread_OK(myframe=self) 
     self.child.daemon = True 
     self.child.start() 

    def onRun2(self, event): 
     self.child2 = ChildThread_Cancel(myframe = self) 
     self.child2.daemon = True 
     self.child2.start() 

    def AfterRun(self, msg): 
     dlg = wx.MessageDialog(self, msg, "Message", wx.OK | wx.ICON_INFORMATION) 
     dlg.ShowModal() 
     dlg.Destroy() 

    def message(self,msg): 
     dlg = wx.BusyInfo(msg) 
     time.sleep(5) 

class MyApp(wx.App): 
    def OnInit(self): 
     frame = MyFrame(None, -1, "My GUI") 
     frame.Show(True) 
     frame.Centre() 
     return True 

app = MyApp(0) 
app.MainLoop() 
+0

是啊如何让一个子线程暂停它的执行一段时间,然后继续? – PythonDev

回答

0

第一:您不能在子线程中使用计时器或消息框,您只能在主线程中使用它们。所以下面的方法是没有意义的。

def waitevent(self): 
    self.timer = wx.Timer(self, 1) 
    self.Bind(wx.EVT_TIMER, self.closeit, self.timer) 
    self.timer.Start(2000, wx.TIMER_ONE_SHOT) 
    wx.CallAfter(self.AfterRun, 'Ok button pressed') 
    print 'Oops!!there is another process running wait for it to finish. Closing this dialog box in 2s...' 

def closeit(self, event): 
    self.dialogBox.Destroy() 

第二:如果您使用消息框来显示的东西,主线程挂起,消息框关闭后,消息框后您的代码运行。您可以在主面板上使用wx.StaticText或wx.TextCtrl来显示消息,或者您可以创建模仿消息框的新框架,并且它们不暂停程序并且可以轻松销毁,或者可以使自定义消息对话框等待变量改变(例如,真/假)。 wxPython演示中有一个自定义消息对话框示例。

第三:你应该学习python的多线程模块中的事件和队列来帮助你控制子线程。子线程可以休眠直到事件被设置,或者可以等到队列中有东西。

+0

我正在学习多线程模块中的队列和事件。如果我有任何疑问,只要实现它,我会尽快回复您。感谢您的建议。 – PythonDev

+0

我的另一个问题是,是否有可能使整个执行停止一段时间然后继续??例如,我们在调试中使用的断点。直到断点运行的过程但在此之后不运行。如果你不介意,你可以用例子给我看这个概念! – PythonDev

+0

不要考虑暂停GUI应用程序的主线程,因为它变得没有响应。如果你想暂停子线程或其他控制台程序,最好的方法就是使用时间模块的睡眠功能。如果你想暂停你的子线程,你可以在run方法中放一个循环并调用sleep函数,或者你可以等待一个事件集(在线程模块中)。您可以暂停执行,直到设置了事件。如果你谷歌它有很多的例子。这里有一个[link](https://pymotw.com/2/threading/) – ozy