使用 wxpython 从串行读取的开始/停止按钮
Start / Stop buttons for reading from serial with wxpython
我用 wxpython 创建了一个简单的 GUI 来从串口读取数据。根据几篇文章,当我按下 Connect 按钮时,我能够连接到串行端口并在我按下 [=20= 时打印数据]Start 按钮但我按下 Stop 按钮我无法停止打印数据。
这是我的代码(里面是之前引用的帖子的链接):
# -*- coding: utf-8 -*-
import wx
import wx.xrc
import serial
import time
import threading
class MyFrame ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.connectBtn = wx.Button( self, wx.ID_ANY, u"Connect", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer2.Add( self.connectBtn, 0, wx.ALL, 5 )
self.startBtn = wx.Button( self, wx.ID_ANY, u"Start", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer2.Add( self.startBtn, 0, wx.ALL, 5 )
self.stopBtn = wx.Button( self, wx.ID_ANY, u"Stop", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer2.Add( self.stopBtn, 0, wx.ALL, 5 )
bSizer1.Add( bSizer2, 0, wx.EXPAND, 5 )
bSizer3 = wx.BoxSizer( wx.VERTICAL )
self.m_textCtrl1 = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer3.Add( self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5 )
self.ser = None
self.settings = {'PORT':'COM3' , 'BAUDRATE':9600}
self.connected = False
bSizer1.Add( bSizer3, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
# Connect Events
self.connectBtn.Bind( wx.EVT_BUTTON, self.connectBtnOnButtonClick )
self.startBtn.Bind( wx.EVT_BUTTON, self.startBtnOnButtonClick )
self.stopBtn.Bind( wx.EVT_BUTTON, self.stopBtnOnButtonClick )
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def connectBtnOnButtonClick( self, event ):
#
try:
if self.ser == None:
self.ser = serial.Serial(self.settings['PORT'],
self.settings['BAUDRATE'],timeout=10)
# print "Successfully connected to port %r." % self.ser.port
self.connectBtn.SetLabel('Disconnect')
self.connected = True
return True
else:
if self.ser.isOpen():
self.ser.close()
self.connected = False
self.connectBtn.SetLabel('Connect')
# print "Disconnected."
return False
else:
self.ser.open()
self.connected = True
self.connectBtn.SetLabel('Disconnect')
# print "Connected."
return True
except serial.SerialException, e:
return False
def startBtnOnButtonClick( self, event ):
while self.connected:
self.connected = True
while True:
if (self.ser.inWaiting() > 0):
data_str = self.ser.read(self.ser.inWaiting())
print(data_str.strip())
time.sleep(0.1)
def stopBtnOnButtonClick( self, event ):
self.connected = False
# self.connected = False
#
if __name__ == "__main__":
app = wx.App(redirect=False)
frame = MyFrame(None)
#app.SetTopWindow(frame)
frame.Show(True)
app.MainLoop()
谢谢。
伊沃
基本上,我认为您的 startBtnOnButtonClick
是一个 "long running process",您需要在 sleep
之前或之后调用 wx.Yield()
。
这将允许您的程序使用 main loop
检查是否发生了其他任何事情,即您按下了停止按钮。
参见:https://wiki.wxpython.org/LongRunningTasks
更改 startBtnOnButtonClick
以删除双 while
循环
def startBtnOnButtonClick( self, event ):
while self.connected:
if (self.ser.inWaiting() > 0):
data_str = self.ser.read(self.ser.inWaiting())
print(data_str.strip())
time.sleep(0.1)
wx.Yield()
我用 wxpython 创建了一个简单的 GUI 来从串口读取数据。根据几篇文章,当我按下 Connect 按钮时,我能够连接到串行端口并在我按下 [=20= 时打印数据]Start 按钮但我按下 Stop 按钮我无法停止打印数据。
这是我的代码(里面是之前引用的帖子的链接):
# -*- coding: utf-8 -*-
import wx
import wx.xrc
import serial
import time
import threading
class MyFrame ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
bSizer2 = wx.BoxSizer( wx.VERTICAL )
self.connectBtn = wx.Button( self, wx.ID_ANY, u"Connect", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer2.Add( self.connectBtn, 0, wx.ALL, 5 )
self.startBtn = wx.Button( self, wx.ID_ANY, u"Start", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer2.Add( self.startBtn, 0, wx.ALL, 5 )
self.stopBtn = wx.Button( self, wx.ID_ANY, u"Stop", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer2.Add( self.stopBtn, 0, wx.ALL, 5 )
bSizer1.Add( bSizer2, 0, wx.EXPAND, 5 )
bSizer3 = wx.BoxSizer( wx.VERTICAL )
self.m_textCtrl1 = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer3.Add( self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5 )
self.ser = None
self.settings = {'PORT':'COM3' , 'BAUDRATE':9600}
self.connected = False
bSizer1.Add( bSizer3, 1, wx.EXPAND, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
# Connect Events
self.connectBtn.Bind( wx.EVT_BUTTON, self.connectBtnOnButtonClick )
self.startBtn.Bind( wx.EVT_BUTTON, self.startBtnOnButtonClick )
self.stopBtn.Bind( wx.EVT_BUTTON, self.stopBtnOnButtonClick )
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def connectBtnOnButtonClick( self, event ):
#
try:
if self.ser == None:
self.ser = serial.Serial(self.settings['PORT'],
self.settings['BAUDRATE'],timeout=10)
# print "Successfully connected to port %r." % self.ser.port
self.connectBtn.SetLabel('Disconnect')
self.connected = True
return True
else:
if self.ser.isOpen():
self.ser.close()
self.connected = False
self.connectBtn.SetLabel('Connect')
# print "Disconnected."
return False
else:
self.ser.open()
self.connected = True
self.connectBtn.SetLabel('Disconnect')
# print "Connected."
return True
except serial.SerialException, e:
return False
def startBtnOnButtonClick( self, event ):
while self.connected:
self.connected = True
while True:
if (self.ser.inWaiting() > 0):
data_str = self.ser.read(self.ser.inWaiting())
print(data_str.strip())
time.sleep(0.1)
def stopBtnOnButtonClick( self, event ):
self.connected = False
# self.connected = False
#
if __name__ == "__main__":
app = wx.App(redirect=False)
frame = MyFrame(None)
#app.SetTopWindow(frame)
frame.Show(True)
app.MainLoop()
谢谢。 伊沃
基本上,我认为您的 startBtnOnButtonClick
是一个 "long running process",您需要在 sleep
之前或之后调用 wx.Yield()
。
这将允许您的程序使用 main loop
检查是否发生了其他任何事情,即您按下了停止按钮。
参见:https://wiki.wxpython.org/LongRunningTasks
更改 startBtnOnButtonClick
以删除双 while
循环
def startBtnOnButtonClick( self, event ):
while self.connected:
if (self.ser.inWaiting() > 0):
data_str = self.ser.read(self.ser.inWaiting())
print(data_str.strip())
time.sleep(0.1)
wx.Yield()