TextCtrl在wxPython中提供越界异常
我是WX新手,所以我决定制作一个程序,根据外部输入定期向屏幕写入一行文本。程序的基础包含一个基本窗口,多行文本控件覆盖整个窗口。我在框架中唯一的另一种方法是将方法TextCtrl在wxPython中提供越界异常,python,macos,wxpython,Python,Macos,Wxpython,我是WX新手,所以我决定制作一个程序,根据外部输入定期向屏幕写入一行文本。程序的基础包含一个基本窗口,多行文本控件覆盖整个窗口。我在框架中唯一的另一种方法是将方法listen\u event得到的内容打印出来,作为多行TextCtrl的新行。就这样,代码如下: class Frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title = 'Program',
listen\u event
得到的内容打印出来,作为多行TextCtrl的新行。就这样,代码如下:
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None,
title = 'Program',
size = (640, 480),
style = wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX)
panel = wx.Panel(self)
self.textArea = wx.TextCtrl(parent = panel,
id = -1,
pos = (0, 0),
size = (-1, -1),
style = wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_AUTO_URL)
def listen_event(self, data):
self.textArea.AppendText(data)
侦听事件从另一个线程定期调用。一切似乎都很好,程序运行正常,但是,每隔一段时间(比我希望的更频繁),我就会收到大量的ObjectiveC错误消息:
2013-06-21 20:11:47.820 Python[85638:420b] An uncaught exception was raised
2013-06-21 20:11:47.821 Python[85638:420b] NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds
2013-06-21 20:11:47.824 Python[85638:420b] (
0 CoreFoundation 0x00007fff92e2bf56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8fc0bd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff92e2bd8a +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff92e2bd14 +[NSException raise:format:] + 116
4 Foundation 0x00007fff8fe93b20 -[NSMutableRLEArray replaceObjectsInRange:withObject:length:] + 132
5 AppKit 0x00007fff8d3e33f8 -[NSLayoutManager addTemporaryAttribute:value:forCharacterRange:] + 500
6 AppKit 0x00007fff8d7f9716 -[NSTextView _markTextEditedForRange:] + 1025
7 AppKit 0x00007fff8d7f8392 -[NSTextView insertText:replacementRange:] + 2400
8 AppKit 0x00007fff8d7f7a25 -[NSTextView insertText:] + 320
9 libwx_osx_cocoau-2.9.4.0.0.dylib 0x0000000101953b71 _ZN19wxNSTextViewControl9WriteTextERK8wxString + 257
10 libwx_osx_cocoau-2.9.4.0.0.dylib 0x00000001018bfb53 _ZN11wxTextEntry9WriteTextERK8wxString + 67
11 _core_.so 0x00000001014dec57 _wrap_TextEntryBase_AppendText + 199
12 Python 0x00000001000c1112 PyEval_EvalFrameEx + 22626
13 Python 0x00000001000c2d29 PyEval_EvalCodeEx + 2137
14 Python 0x00000001000c0b6a PyEval_EvalFrameEx + 21178
15 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
16 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
17 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
18 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
19 Python 0x00000001000c2d29 PyEval_EvalCodeEx + 2137
20 Python 0x00000001000c0b6a PyEval_EvalFrameEx + 21178
21 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
22 Python 0x00000001000c2d29 PyEval_EvalCodeEx + 2137
23 Python 0x000000010003da80 function_call + 176
24 Python 0x000000010000c5e2 PyObject_Call + 98
25 Python 0x000000010001ebcb instancemethod_call + 363
26 Python 0x000000010000c5e2 PyObject_Call + 98
27 Python 0x00000001000ba5f7 PyEval_CallObjectWithKeywords + 87
28 Python 0x0000000100100a63 t_bootstrap + 67
29 libsystem_c.dylib 0x00007fff933008bf _pthread_start + 335
30 libsystem_c.dylib 0x00007fff93303b75 thread_start + 13
)
2013-06-21 20:11:47.825 Python[85638:420b] *** Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff92e2bf56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8fc0bd5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff92e2bd8a +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff92e2bd14 +[NSException raise:format:] + 116
4 Foundation 0x00007fff8fe93b20 -[NSMutableRLEArray replaceObjectsInRange:withObject:length:] + 132
5 AppKit 0x00007fff8d3e33f8 -[NSLayoutManager addTemporaryAttribute:value:forCharacterRange:] + 500
6 AppKit 0x00007fff8d7f9716 -[NSTextView _markTextEditedForRange:] + 1025
7 AppKit 0x00007fff8d7f8392 -[NSTextView insertText:replacementRange:] + 2400
8 AppKit 0x00007fff8d7f7a25 -[NSTextView insertText:] + 320
9 libwx_osx_cocoau-2.9.4.0.0.dylib 0x0000000101953b71 _ZN19wxNSTextViewControl9WriteTextERK8wxString + 257
10 libwx_osx_cocoau-2.9.4.0.0.dylib 0x00000001018bfb53 _ZN11wxTextEntry9WriteTextERK8wxString + 67
11 _core_.so 0x00000001014dec57 _wrap_TextEntryBase_AppendText + 199
12 Python 0x00000001000c1112 PyEval_EvalFrameEx + 22626
13 Python 0x00000001000c2d29 PyEval_EvalCodeEx + 2137
14 Python 0x00000001000c0b6a PyEval_EvalFrameEx + 21178
15 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
16 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
17 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
18 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
19 Python 0x00000001000c2d29 PyEval_EvalCodeEx + 2137
20 Python 0x00000001000c0b6a PyEval_EvalFrameEx + 21178
21 Python 0x00000001000c1ebe PyEval_EvalFrameEx + 26126
22 Python 0x00000001000c2d29 PyEval_EvalCodeEx + 2137
23 Python 0x000000010003da80 function_call + 176
24 Python 0x000000010000c5e2 PyObject_Call + 98
25 Python 0x000000010001ebcb instancemethod_call + 363
26 Python 0x000000010000c5e2 PyObject_Call + 98
27 Python 0x00000001000ba5f7 PyEval_CallObjectWithKeywords + 87
28 Python 0x0000000100100a63 t_bootstrap + 67
29 libsystem_c.dylib 0x00007fff933008bf _pthread_start + 335
30 libsystem_c.dylib 0x00007fff93303b75 thread_start + 13
)
terminate called throwing an exception
有什么好处?我找不到这些错误的押韵或原因。有时,它对一对夫妇连续工作,然后崩溃。有时它会在第一次运行时崩溃。我是否错误地实现了文本控制框?这可能是您崩溃的原因,也可能不是,但如果确实会导致崩溃,并且很可能正是您看到的那种崩溃(有时有效,有时失败,有时有效一段时间,然后突然失败,即使没有任何可见的变化…) 不能从其他线程调用对UI对象进行操作的方法。每次从另一个线程调用
self.textArea.AppendText
,都有可能导致崩溃,或者更有趣的是,会破坏内存或其他资源,导致以后崩溃
有几种不同的解决方法:
- 用于将主UI线程的事件排队(事件处理程序中的实际UI更改代码)
- 使用或调度要在主UI线程上调用的函数(该函数中的实际UI更改代码)
- 使用
框架pubsub
- 使用一些wx机制的外部(例如,从
模块,或管道,或其他)向主UI线程发送信号线程
- 以上不止一项
CallAfter
是围绕PostEvent
的包装,而CallLater
是围绕计时器加CallAfter
的包装,计时器和threading
都是围绕同一个本机线程API的包装,依此类推,所以这并不像看上去那么多不同的可能性…)
无论如何,对代码最微不足道的更改是:
def listen_event(self, data):
wx.CallAfter(self.textArea.AppendText, data)
最重要的是,您违反了多线程编程的第一条规则:共享可变对象只能在锁下访问
我不认为这是你的问题所在。由于
self
在创建之后将永远不会更改属性,并且(假设您使用的是CPython,或者其他一些带有GIL的Python实现),没有任何其他非原子性的情况会影响您,因此您可以在这里逃脱。但是,如果您不理解为什么代码(除了wx
调用)是线程安全的,您就不应该指望它。我在运行程序时也遇到了同样的问题。这将是非常有帮助的,如果你能看看我的代码,并建议一些修改要做。我已经在这里发布了我的问题:
. 感谢您的帮助。它之所以让您想起ObjC崩溃转储,是因为它是ObjC崩溃转储<代码> WXPython 是围绕每个平台本地窗口对象的C++包装器的Python包装器,在MAC上,这意味着Objc。如您所见,实际崩溃是ObjC代码中的一个
NSException
…