как сделать так, чтобы серийный номер работал хорошо, а также на переднем плане - PullRequest
1 голос
/ 25 октября 2019

у меня есть последовательное приложение, класс Robot должен всегда получать последовательное сообщение, а затем, чтобы что-то сделать, графический интерфейс Demo должен взаимодействовать с Robot и получать Robot.handle_readData, если нет данных, нужночтобы получить снова и снова, пока не было данных. Теперь я понятия не имел, как решить эту проблему, нужно, чтобы кто-нибудь дал мне хорошую идею.

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSerialPort import *

class Robot(QObject):
    def __init__(self):
        super().__init__()
        self.serial = QSerialPort()
        self.serial.setPortName('COM2')
        self.serial.setBaudRate(QSerialPort.Baud115200)
        self.serial.readyRead.connect(self.handle_readData)
        self.serial.open(QIODevice.ReadWrite)

    #background message auto process
    def handle_readData(self):
        data = self.serial.readAll()
        self.do_something(data)

        return data

    def do_something(self, data):pass

class Demo(QDialog):
    def __init__(self):
        super().__init__()
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.search_bn = QPushButton('query', clicked=self.get_query_info)
        layout.addStretch(1)
        layout.addWidget(self.search_bn)

        main_layout = QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addWidget(QTextEdit('msg'))
        self.setLayout(main_layout)

        #robot object
        self.robot = Robot()

    #forground message process, pseudo code
    def get_query_info(self, checked):
        self.robot.serial.write('show version')
        #how to get Robot.handle_readData  data,
        data = Robot.handle_readData() # need to get this data
        #if data is None, need to get again and again until data have some meaningful msg.
        do_someting(data)


        self.robot.serial.write('show system info')
        # how to get Robot.handle_readData  data,
        data = Robot.handle_readData()  # need to get this data
        # if data is None, need to get again and again until data have some meaningful msg.
        do_someting1(data)


app = QApplication([])
demo = Demo()
demo.show()
app.exec()

1 Ответ

2 голосов
/ 25 октября 2019

Qt разработан для асинхронной работы, и вместо этого ваша возможная реализация сделана для синхронной логики. Решение для этих случаев состоит в том, чтобы преобразовать реализацию, и в этом случае, например, с помощью флагов.

С другой стороны, не обрабатывайте информацию, где вы получаете информацию, вместо этого он испускает сигнал так, чтобыэто может использоваться в другом месте.

from enum import Enum, auto


from PyQt5.QtCore import pyqtSignal, pyqtSlot, QIODevice, QObject
from PyQt5.QtWidgets import (
    QApplication,
    QDialog,
    QHBoxLayout,
    QPushButton,
    QVBoxLayout,
    QTextEdit,
)
from PyQt5.QtSerialPort import QSerialPort


class Robot(QObject):
    dataChanged = pyqtSignal(bytes)

    def __init__(self):
        super().__init__()
        self.serial = QSerialPort()
        self.serial.setPortName("COM2")
        self.serial.setBaudRate(QSerialPort.Baud115200)
        self.serial.readyRead.connect(self.handle_readData)
        self.serial.open(QIODevice.ReadWrite)

        self.dataChanged.connect(self.do_something)

    @pyqtSlot()
    def handle_readData(self):
        data = self.serial.readAll()
        self.dataChanged.emit(data)

    @pyqtSlot(bytes)
    def do_something(self, data):
        pass


class State(Enum):
    NoneState = auto()
    VersionState = auto()
    InfoState = auto()


class Demo(QDialog):
    def __init__(self):
        super().__init__()
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.search_bn = QPushButton("query", clicked=self.get_query_info)
        layout.addStretch(1)
        layout.addWidget(self.search_bn)

        main_layout = QVBoxLayout(self)
        main_layout.addLayout(layout)
        main_layout.addWidget(QTextEdit("msg"))

        self.current_state = State.NoneState

        self.robot = Robot()
        self.robot.dataChanged.connect(self.process_data)

    @pyqtSlot()
    def get_query_info(self):
        self.robot.serial.write(b"show version")
        self.current_state = State.VersionState

    @pyqtSlot(bytes)
    def process_data(self, data):
        if self.current_state == State.VersionState:
            do_someting(data)
            self.robot.serial.write(b"show system info")
            self.current_state = State.InfoState
        elif self.current_state == State.InfoState:
            do_someting1(data)
            self.current_state = State.NoneState


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())
...