之前的一些东西:
这里都是基于wxTerminal.py Link
(Pyserial 微型端口和 WxPython GUI 的组合)
使用: Python:2.7.14。 WxPython:4.0.0b2
我的问题是我有一个线程从我的设备读取串行数据, 并尝试使用事件更新 GUI:
class TerminalFrame(wx.Frame):
....
....
def ComPortThread(self):
"""\
Thread that handles the incoming traffic. Does the basic input
transformation (newlines) and generates an SerialRxEvent
"""
while self.alive.isSet():
b = self.serial.read(self.serial.in_waiting or 1)
if b:
# newline transformation
if self.settings.newline == NEWLINE_CR:
b = b.replace(b'\r', b'\n')
elif self.settings.newline == NEWLINE_LF:
pass
elif self.settings.newline == NEWLINE_CRLF:
b = b.replace(b'\r\n', b'\n')
event = SerialRxEvent(self.GetId(), b)
**ERROR!** >>> self.GetEventHandler().AddPendingEvent(event)
我收到错误:
File "C:/Users/DIMA/Desktop/pyserial-master/pyserial-master/examples/wxTerminal.py", line 349, in ComPortThread
self.GetEventHandler().AddPendingEvent(event)
wxAssertionError: C++ assertion "event" failed at ..\..\src\common\event.cpp(1246) in wxEvtHandler::QueueEvent(): NULL event can't be posted
缺少什么?
SERIALRX = wx.NewEventType()
# bind to serial data receive events
EVT_SERIALRX = wx.PyEventBinder(SERIALRX, 0)
class SerialRxEvent(wx.PyCommandEvent):
eventType = SERIALRX
def __init__(self, windowID, data):
wx.PyCommandEvent.__init__(self, self.eventType, windowID)
self.data = data
def Clone(self):
self.__class__(self.GetId(), self.data)
最佳答案
这也曾经让我感到困惑。
出于某种原因,Clone
方法永远不会在 wxPython classic 中被调用(尝试插入 raise
)。 pyserial 的作者似乎弄错了。根据the docs Clone
方法应返回一个新事件!
当使用 Phoenix(通过 pip 安装获得的)时,将调用 Clone
方法。并且因为您返回 None
,AddPendingEvent
会提示。
编辑事件类中的 Clone 方法(wxTerminal 中的 SerialRxEvent),使其正确返回:
def Clone(self):
# raise # uncomment this to show that this will not get called in classic
# instead of this
# self.__class__(self.GetId(), self.data)
# do this
return self.__class__(self.GetId(), self.data)
关于python - WxPython PySerial 和 Wx.Terminal - 线程无法更新 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48113110/