MacOs中带WxPython事件的线程

MacOs中带WxPython事件的线程,python,events,wxpython,Python,Events,Wxpython,我在MacOs X上的WxPython工作,并使用pyCharm。我想做的是,当我点击界面上的一个按钮时,它生成一个新线程,然后这个新线程执行我的代码 我明白了,但它崩溃了,我不知道为什么 我得到的错误如下: 2016-02-22 14:13:36.641 Python[5694:698370] NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds 2016-02-22 14:13:36.643 Pyt

我在MacOs X上的WxPython工作,并使用pyCharm。我想做的是,当我点击界面上的一个按钮时,它生成一个新线程,然后这个新线程执行我的代码

我明白了,但它崩溃了,我不知道为什么

我得到的错误如下:

2016-02-22 14:13:36.641 Python[5694:698370] NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds
2016-02-22 14:13:36.643 Python[5694:698370] (
0   CoreFoundation                      0x00007fff91234ae2 __exceptionPreprocess + 178
1   libobjc.A.dylib                     0x00007fff977d973c objc_exception_throw + 48
2   CoreFoundation                      0x00007fff9123498d +[NSException raise:format:] + 205
3   Foundation                          0x00007fff9035bb32 -[NSMutableRLEArray replaceObjectsInRange:withObject:length:] + 156
4   UIFoundation                        0x00007fff919be488 -[NSLayoutManager removeTemporaryAttribute:forCharacterRange:] + 299
5   AppKit                              0x00007fff98a6a053 -[NSTextView _markForTextCheckingAfterChange] + 432
6   CoreFoundation                      0x00007fff911444ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
7   CoreFoundation                      0x00007fff91136165 __CFRunLoopDoBlocks + 341
8   CoreFoundation                      0x00007fff91135954 __CFRunLoopRun + 948
9   CoreFoundation                      0x00007fff91135338 CFRunLoopRunSpecific + 296
10  HIToolbox                           0x00007fff9fc27935 RunCurrentEventLoopInMode + 235
11  HIToolbox                           0x00007fff9fc2776f ReceiveNextEventCommon + 432
12  HIToolbox                           0x00007fff9fc275af _BlockUntilNextEventMatchingListInModeWithFilter + 71
13  AppKit                              0x00007fff988230ee _DPSNextEvent + 1067
14  AppKit                              0x00007fff98bef943 -[NSApplication _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 454
15  AppKit                              0x00007fff98818fc8 -[NSApplication run] + 682
16  libwx_osx_cocoau-3.0.0.2.0.dylib    0x0000000103d25418 _ZN14wxGUIEventLoop8OSXDoRunEv + 248
17  libwx_osx_cocoau-3.0.0.2.0.dylib    0x0000000103bf260f _ZN13wxCFEventLoop5DoRunEv + 31
18  libwx_osx_cocoau-3.0.0.2.0.dylib    0x0000000103b2b0e1 _ZN15wxEventLoopBase3RunEv + 65
19  libwx_osx_cocoau-3.0.0.2.0.dylib    0x0000000103af0787 _ZN16wxAppConsoleBase8MainLoopEv + 103
20  _core_.so                           0x00000001038033dc _ZN7wxPyApp8MainLoopEv + 76
21  _core_.so                           0x000000010384dd8f _wrap_PyApp_MainLoop + 79
22  Python                              0x00000001000c2d32 PyEval_EvalFrameEx + 20898
23  Python                              0x00000001000c4f93 PyEval_EvalCodeEx + 2115
24  Python                              0x000000010003e990 function_call + 176
25  Python                              0x000000010000cde2 PyObject_Call + 98
26  Python                              0x000000010001f43d instancemethod_call + 365
27  Python                              0x000000010000cde2 PyObject_Call + 98
28  Python                              0x00000001000c0c10 PyEval_EvalFrameEx + 12416
29  Python                              0x00000001000c3bcf PyEval_EvalFrameEx + 24639
30  Python                              0x00000001000c4f93 PyEval_EvalCodeEx + 2115
31  Python                              0x00000001000c50b6 PyEval_EvalCode + 54
32  Python                              0x00000001000e993e PyRun_FileExFlags + 174
33  Python                              0x00000001000e9bda PyRun_SimpleFileExFlags + 458
34  Python                              0x0000000100100bfd Py_Main + 3101
35  Python                              0x0000000100000f14 Python + 3860
36  ???                                 0x0000000000000002 0x0 + 2
)
但有时,当这种情况发生时,我会等待,代码会同时执行

当我再次这样做(点击按钮)它崩溃。。。我想这是因为我没有关闭线程,但我不知道这是否是必要的

这是我用来创建线程的代码:

class CountingThread(threading.Thread):
    def __init__(self, parent):
        threading.Thread.__init__(self)
        self._parent = parent

    def run(self):
        """
        Overrided method.
        """
        self._parent.experiment_button()
该类由该事件函数调用:

def OnButton(self, evt):
    worker = CountingThread(self)
    worker.start()
我不知道为什么会这样


提前谢谢你

似乎是一个典型的例子。请参阅最后一个示例,它是最容易实现的,但也可以查看其他可能性

抱歉,我对您的情况不够具体:您必须将长时间运行的部分移动到线程中。当触发实验按钮事件时,剥离线程并在线程完成期间/之后报告结果

def run(self):
    """
    Overrided method.
    """
    # put long running part here
    # ... long running task
    # sprinkle with CallAfter as seen fit
    # ... continue task

    # signal the end result back thread-safely
    wx.CallAfter(self._parent.update_result, result)

我看到的第一个问题是,从线程回调到
wxPython
不是线程安全的。您不应该直接从线程调用GUI的方法,因为
wxPython
不是这样设计的。然而,要安全地调用
wx
线程,只需将该方法包装在调用
wx.CallAfter
中,如下所示:
wx.CallAfter(self.\u parent.experiment\u按钮)
@nepix32我已经修改了它,并且知道我没有得到那个错误,但它没有按照我需要的方式工作,当我按下按钮时,代码正在执行,但按钮仍然被按下(似乎新线程不存在)。。。我想做的是,在计算机处理算法时继续使用接口…我知道你说什么,但我认为我必须改变我的代码结构。。。我有一个方法调用按钮,它在一些算法之间执行。这个方法直到有结果才结束,所以。。。我认为在那一刻之前界面会冻结。。。我不知道这个问题是否有解决办法。如果不是,我想我必须改变我的结构。。。。非常感谢@nepix32