【问题标题】:Start / Stop buttons for reading from serial with wxpython使用 wxpython 从串行读取的开始/停止按钮
【发布时间】:2017-05-17 14:43:44
【问题描述】:

我用 wxpython 创建了一个简单的 GUI 来从串行端口读取数据。根据几篇文章,当我按下 Connect 按钮时,我能够连接到串行端口,并在按下 Start 时打印数据> 按钮,但我按下 停止 按钮我无法停止打印数据。

这是我的代码(里面是之前提到的帖子的链接):

# -*- 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 ):
        # http://stackoverflow.com/questions/11092417/reconnecting-to-device-with-pyserial
        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
        # http://stackoverflow.com/questions/17553543/pyserial-non-blocking-read-loop

if __name__ == "__main__":
    app = wx.App(redirect=False)
    frame = MyFrame(None)
    #app.SetTopWindow(frame)
    frame.Show(True)
    app.MainLoop()

谢谢。 伊沃

【问题讨论】:

    标签: python user-interface wxpython pyserial


    【解决方案1】:

    基本上,我认为您的startBtnOnButtonClick 是一个“长期运行的过程”,您需要在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()
    

    【讨论】:

    • 效果很好!!!感谢您提供的所有帮助,即代码和链接。亲切的问候。伊沃
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    相关资源
    最近更新 更多