Соединитесь с последовательным интерфейсом из PyQt GUI - PullRequest
2 голосов
/ 08 марта 2019

Я пишу программу для отправки и получения данных из последовательного порта, но у меня возникла проблема, я хочу создать функцию «connect ()» или класс, и когда я нажимаю кнопку, функция выполняется, но если я создам эту функцию в классе «MainWindow», переменная «ser» из класса «TestThread» станет неинициализированной, вы можете мне помочь?

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()

1 Ответ

1 голос
/ 09 марта 2019

Вместо использования потока 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_())
...