在wxpython中进行线程化

时间:2015-09-05 06:51:38

标签: python-2.7 wxpython python-multithreading

您好我是python的新手,并已开始使用wxpython开发GUI。我只想知道wxpython中的基本线程操作。我有一个主要的过程,有好的&使用“确定”和“取消”按钮取消按钮和从main派生的子进程。我想实现线程,以便在主进程上单击OK按钮必须向子进程发送消息,并且子进程必须查找其进程是否正在运行,如果是,则必须等待该进程完成然后从主进程接收消息。与主进程中的取消按钮类似。 基本上我想看看子进程如何从主进程接收消息并且两者并行工作。 我正在尝试wx.CallAfter和wx.PostEvent,我在这里与线程概念混淆。请有人帮助我。 提前致谢

2 个答案:

答案 0 :(得分:0)

wxpython中的多线程与python中的不同。 wx.CallAfter and threading example显示了您如何使用它们。 wx.CallAfter等待事件完成并在主线程中运行处理程序。此外,您可以使用计时器(wx.Timer)来检查子进程并发送/接收数据。

以下是显示如何使用它的wx.PostEvent链接。在此示例中,您将创建自定义事件,将其绑定到主线程中的处理程序。之后,您将事件发布到工作线程中并附加一些数据。您的事件处理程序接收事件并在主线程中执行一些操作。

因此,使用多线程时会出现一些重要问题

  1. 何时启动子线程,
  2. 线程之间使用哪种通信机制
  3. 如何在必要时以安全的方式停止线程,
  4. 我更喜欢wx.Timer + Queue模块。我可以定期用计时器或用户事件检查队列,并通过队列发送一些东西(即无)来停止线程。

    注意:主线程中长时间运行的作业可能会使GUI无响应。

答案 1 :(得分:0)

我做对了。感谢@ozy

import threading
import wx
from threading import Thread

ID_RUN = 101
ID_RUN2 = 102


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

    def run(self):
        wx.CallAfter(self.myframe.AfterRun, 'Ok 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(myframe=self)
        self.child.daemon = True
        self.child.start()

    def onRun2(self, event):
        self.child2 = threading.Thread(None, self.__run)
        self.child2.daemon = True
        self.child2.start()

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

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


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()