#python #python-3.x #serial-port #wxpython #pyserial
Вопрос:
У меня проблема с разработкой программы, которая использует графический интерфейс wxPython для последовательной связи.
Когда я нажимаю кнопку «ОТКРЫТЬ», открывается серийный порт с последовательным портом, выбранным в выпадающем списке, и скоростью, введенной в TextCtrl, и я хочу отобразить данные, введенные в этот порт, на экране терминала.
В этом коде нам удалось открыть и закрыть последовательный порт с помощью кнопок «ОТКРЫТЬ» и «Закрыть», но мы хотели бы знать, как отображать данные, поступающие через Последовательный порт, на экране терминала в режиме реального времени.
import wx
import serial
import serial.tools.list_ports as SerialPort
class MyApp(wx.Frame):
portList = []
portSelect = ''
ser = serial.Serial()
def __init__(self):
self.SearchSerialPort()
wx.Frame.__init__(self, parent = None, id = -1, title = "SerialCSV", size = (500, 150), style =wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)
panel = wx.Panel(self)
# PORT list text
self.select = wx.StaticText(panel, label = "PORT Select : ")
self.select.SetPosition((10, 10))
# BaudRate text
self.select = wx.StaticText(panel, label = "PORT BaudRate : ")
self.select.SetPosition((10, 40))
# PORT list comboBox
self.Combo = wx.ComboBox(panel, -1, "Select", (106, 7), (110,22), self.portList)
self.Bind(wx.EVT_COMBOBOX, self.PortSelect)
# BaudRate inputBox
self.BR = wx.TextCtrl(panel, -1, size = (110, 22), pos=(106,37))
# Connect Button
self.ConnectButton = wx.Button(panel, label="OPEN", size = (80, 52), pos=(230, 7))
self.ConnectButton.Bind(wx.EVT_BUTTON,self.SerialConnect)
# DisConnect Button
self.DisConnectButton = wx.Button(panel, label="Close", size = (80, 52), pos=(310, 7))
self.DisConnectButton.Bind(wx.EVT_BUTTON, self.SerialDisConnect)
def SearchSerialPort(self) :
ports = SerialPort.comports()
for p in ports :
self.portList.append(p.device)
def PortSelect(self, event) :
self.portSelect = self.portList[event.GetSelection()]
def SerialConnect(self, event) :
if self.ser.is_open == False :
ReadBaudrate = self.BR.GetValue()
print(ReadBaudrate)
if ReadBaudrate == '' :
print("!! Input BaudRate !!")
else :
self.ser = serial.Serial(port = self.portSelect, baudrate = ReadBaudrate)
print(self.portSelect " PORT Open")
else :
print("already open... [ " self.portSelect " ]" )
def SerialRead(self) :
if self.ser.is_open == True :
if self.ser.readable():
res = self.ser.readline()
print(res.decode()[:len(res)-1])
def SerialDisConnect(self, event) :
self.ser.close()
print("PORT Close")
if __name__=="__main__":
app = wx.App()
frame = MyApp()
frame.Show()
app.MainLoop()
Комментарии:
1. Вам нужно использовать какой-то таймер, чтобы регулярно вызывать
SerialRead()
метод. Какие таймерыwxPython
предлагает структура?2. Wxpyton предоставляет таймер под названием wxTimer. Это был мой первый проект, в котором я использовал графический интерфейс, поэтому я не думал о «Таймере», и я думал о том, как использовать «в то время как», «для» или «поток». Спасибо вам за ваши ответы.
3. Да, со всеми графическими фреймворками (и некоторыми другими фреймворками), которые управляются событиями, не очень хорошая идея иметь длительные циклы. Гораздо лучше использовать событие, предоставляемое платформой, для повторного вызова вашего собственного кода. (И этот код должен что-то сделать и вернуться как можно быстрее)
4. Кажется, есть пример программы под названием wxTerminal.py в писериале. Вы пробовали или исследовали это?