【问题标题】:wx.Frame and threading in the same classwx.Frame 和线程在同一个类中
【发布时间】:2017-11-27 13:15:20
【问题描述】:

我正在尝试创建一个同时处理 wx.Frame 和 Threading 的类(我也尝试使用 Visual(threadins.Thread, wx.Frame),但没有成功。我真的不会想使用 wx.CallAfter 并且我想只在一个类中处理它。当我运行代码时,一切正常,但是 Close 方法使程序崩溃并且框架保持打开状态。我错在哪里?

import threading
import wx

class Visual(threading.Thread):
    def __init__(self, title):
            screenWidth = 500
            screenHeight = 400
            screenSize = (screenWidth,screenHeight)
            self.app = wx.App(False)
            self.frame = wx.Frame(None, wx.ID_ANY,title, size=screenSize)
            panel = wx.Panel(self.frame)
            self.list_ctrl = wx.ListCtrl(panel, size=(-1,100),
                     style=wx.LC_REPORT
                     |wx.BORDER_SUNKEN
                     )
            self.list_ctrl.InsertColumn(0, 'Name', width=125)
            self.list_ctrl.InsertColumn(1, 'DDD')
            self.list_ctrl.InsertColumn(2, 'Phone')
            self.list_ctrl.InsertColumn(3, 'Desc', width=125)
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
            panel.SetSizer(sizer)

            self.ready = False

            threading.Thread.__init__(self)
            self.frame.Bind(wx.EVT_CLOSE, self.close)
            self.start()
    def close(self, event):
        print("Close")
        self.frame.Destroy()
        self.app.Destroy()
        self.app.ExitMainLoop()

    def run(self):
            self.frame.Show(True)
            self.ready = True
            self.app.MainLoop()
if __name__ == '__main__':
   visu = Visual(title='Test')

谢谢。

【问题讨论】:

  • 我同意 MikeDriscoll 的回答,但我想建议,一旦你在 wx 对象上调用 Destroy(),你就不应该再使用它了。每个 wx 对象都由一个 C++ 代理对象支持,该对象在调用 Destroy 后可能已死或处于不可用状态。您的 close 方法中的代码在您销毁它后使用 self.app 。有时您可能会侥幸逃脱,但这不是一个好主意。

标签: python multithreading wxpython


【解决方案1】:

wxPython 要求它的主循环位于主线程中,就像所有其他桌面 GUI 工具包(即 PyQt、Tkinter 等)一样。你应该只在 wxPython 的主循环启动后才启动线程。换句话说,线程应该从 wxPython 内部启动。

wxPython 有三个线程安全的方法。它们如下:

  • wx.CallAfter
  • wx.PostEvent
  • wx.CallLater

无论如何,这几乎肯定需要你有一个线程类和一个或多个 wxPython 相关的类。这是正常的,也是推荐的做法。有关详细信息,请参阅以下链接:

【讨论】:

  • 呸,我大部分都是打出来的(你必须有某种关于 wx ;P 的警报)......可能值得一提的是 wx.CallAfter (尽管我确信所有这些链接都是如此)旁边的@bruno Mikes 博客(见第二个链接)是 wx 的所有东西的绝佳资源!
  • 我很幸运......但我相信你的回答也会很棒!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多