python - 从 PyQt GUI 连接到串口
问题描述
我编写了一个程序来从串行发送和接收数据,但是我有一个问题,我想创建一个函数“connect()”或一个类,当我按下一个按钮时,该函数被执行,但是如果我创建“MainWindow”类中的这个函数,“TestThread”类中的变量“ser”变得未初始化,你能帮帮我吗?
import sys
import serial
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.uic import loadUi
ser = serial.Serial('/dev/tty.usbmodem14201', 9600, timeout=1)
class TestThread(QThread):
serialUpdate = pyqtSignal(str)
def run(self):
while ser.is_open:
QThread.sleep(1)
value = ser.readline().decode('ascii')
self.serialUpdate.emit(value)
ser.flush()
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
loadUi('/Users/bogdanvesa/P2A_GUI/mainwindow.ui', self)
self.thread = TestThread(self)
self.thread.serialUpdate.connect(self.handleSerialUpdate)
self.connect_btn.clicked.connect(self.connectSer)
self.lcd_EBtn.clicked.connect(self.startThread)
def startThread(self):
self.thread.start()
def handleSerialUpdate(self, value):
print(value)
self.lcd_lineEdit.setText(value)
def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
解决方案
与其使用 pySerial + 线程,不如使用QSerialPort
它与 Qt 事件循环一起使用:
from PyQt5 import QtCore, QtWidgets, QtSerialPort
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.message_le = QtWidgets.QLineEdit()
self.send_btn = QtWidgets.QPushButton(
text="Send",
clicked=self.send
)
self.output_te = QtWidgets.QTextEdit(readOnly=True)
self.button = QtWidgets.QPushButton(
text="Connect",
checkable=True,
toggled=self.on_toggled
)
lay = QtWidgets.QVBoxLayout(self)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(self.message_le)
hlay.addWidget(self.send_btn)
lay.addLayout(hlay)
lay.addWidget(self.output_te)
lay.addWidget(self.button)
self.serial = QtSerialPort.QSerialPort(
'/dev/tty.usbmodem14201',
baudRate=QtSerialPort.QSerialPort.Baud9600,
readyRead=self.receive
)
@QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.output_te.append(text)
@QtCore.pyqtSlot()
def send(self):
self.serial.write(self.message_le.text().encode())
@QtCore.pyqtSlot(bool)
def on_toggled(self, checked):
self.button.setText("Disconnect" if checked else "Connect")
if checked:
if not self.serial.isOpen():
if not self.serial.open(QtCore.QIODevice.ReadWrite):
self.button.setChecked(False)
else:
self.serial.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
推荐阅读
- python - Plotly Dash:选择 DataTable 中的行作为回调输出 + 过滤器
- sql-server - 将 SQL 查询转换为 SQL 函数?
- regex - 为一个非常大的文件添加一个正则表达式
- python - 如何从 Mac OS 中删除 LaunchDaemon
- mysql - 在 ColdFusion 中更新数据库
- python - 在 Python 3 中查找并获取未知大 RAM 分配的回溯
- python-3.x - Python3苹果mobileconfig下载服务器
- yugabyte-db - 主引导过程如何工作以及如何调试它?
- php - 如何使用 where 子句在 cakephp 中正确嵌套查询?
- reactjs - 从 yarn build 编辑静态文件(index.html)