TextCtrl在wxPython中提供了超出范围的异常 [英] TextCtrl providing an out of bound exception in wxPython

查看:109
本文介绍了TextCtrl在wxPython中提供了超出范围的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是WX的新手,所以我决定制作一个程序,该程序将根据外部输入定期将一行文本写到屏幕上.该程序的基础包含一个基本窗口,多行文本控件覆盖整个窗口.我在框架中唯一的其他方法是将方法listen_event获得的内容打印为多行TextCtrl的新行.就是这样,作为证明代码如下:

I am new to WX, so I decided to make a program that will periodically write out a line of text to the screen based on an outside input. The basis of the program contains a basic window with the multiline text control covering the entire window. The only other method I have in the frame is to print out what ever the method listen_event gets as a new line for the multiline TextCtrl. Thats it, as proof the code is below:

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)

定期从另一个线程调用listen事件.一切似乎都很好,该程序正常运行,但是,每隔一段时间(比我想要的更多),我就会得到大量关于让我想起ObjectiveC错误消息的信息:

The listen event is is called periodically from another thread. All seems to be fine, the program works, however, every so often (more often than I would like) I get a massive dump of what reminds me of ObjectiveC error messages:

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

有什么作用?我找不到这些错误的押韵或原因.有时它会连续几个工作,然后崩溃.有时它在第一次尝试时就崩溃了.我是否错误地实现了文本控制框?

What gives? I cannot find a rhyme or reason for these errors. On occasion it works for a couple in a row, then crashes. And sometimes it crashes on the first go. Am I implementing the text control box incorrectly?

推荐答案

这可能是崩溃的原因,也可能不是崩溃的原因,但是如果确实会导致崩溃,那么它们很可能就是您的崩溃类型重新看到(有时它可以工作,有时它会失败,有时它会工作一会儿,然后即使没有可见的变化也突然失败了……).

This may or may not be the reason for your crash, but if definitely will cause crashes, and they're likely to be exactly the kind of crash you're seeing (sometimes it works, sometimes it fails, sometimes it works for a while and then suddenly fails even though nothing visible has changed…).

您不能从其他线程调用对UI对象进行操作的方法.每次从另一个线程调用self.textArea.AppendText时,都有崩溃的可能,或者更有趣的是,损坏内存或其他资源导致以后崩溃.

You cannot call methods that operate on UI objects from other threads. Every time you call self.textArea.AppendText from another thread, there is a chance of crashing—or, more fun, corrupting memory or other resources leading to a crash later.

有几种不同的解决方法:

There are a few different ways around this:

  • 使用 PostEvent 将事件排入队列主UI线程(在事件处理程序中具有实际的更改UI的代码).
  • 使用 CallAfter
  • Use PostEvent to queue an event for the main UI thread (with the actual UI-changing code in the event handler).
  • Use CallAfter or CallLater to schedule a function to be called on the main UI thread (with the actual UI-changing code inside that function).
  • Use the pubsub framework.
  • Use some external-to-wx mechanism (e.g., from the threading module, or a pipe, or whatever) to signal the main UI thread.
  • More than one of the above.

(在幕后,CallAfterPostEvent的包装器,CallLater是计时器加CallAfter的包装器,并且timer和threading都是相同的本机线程API的包装器,依此类推,所以这种可能性似乎并不多...)

(Under the covers, CallAfter is a wrapper around PostEvent, and CallLater is a wrapper around a timer plus CallAfter, and the timer and threading are both wrappers around the same native thread APIs, and so on, so this isn't as many different possibilities as it seems…)

无论如何,对代码最微不足道的更改是:

Anyway, the most trivial change to your code is:

def listen_event(self, data):
    wx.CallAfter(self.textArea.AppendText, data)


最重要的是,您违反了多线程编程的第一条规则:共享的可变对象只能在锁下访问.


On top of that, you're violating the first rule of multithreaded programming: shared mutable objects must only be accessed under locks.

我认为这不是造成您的问题的原因.由于self在创建后将永远不会更改属性,并且(假设您使用的是CPython或其他使用GIL的其他Python实现),那么就不会发生其他会影响您的非原子性事情,您就可以摆脱它这里.但是,如果您不理解为什么代码(除了wx调用之外)是线程安全的,则不要指望它.

I don't think this is causing your problem here. Since self will never change attributes after creation, and (assuming you're using CPython, or some other Python implementation with a GIL) there's nothing else that can happen non-atomically that can affect you, you'll get away with it here. But if you don't understand why your code (other than the wx calls) is thread-safe, you shouldn't count on it.

这篇关于TextCtrl在wxPython中提供了超出范围的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆