如何从一个函数将数据插入PyQt5中的多个小部件中

问题描述 投票:0回答:1

我的接口连接了一个设备,并希望将数据插入QlineEdit小部件

此功能def getdevice_data(self):从设备接收数据并将其作为字符串返回

使用self.get_output__button.clicked.connect(self.getdevice_data)我“启动”功能

并使用self.custom_attribute.connect(self.device_input1.setText)将输出发送到QLineEdit小部件

如何保持功能运行并将功能中的新数据插入到空行编辑小部件中,而无需添加多个按钮来一次又一次地启动该功能?

完整代码

import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg

import serial
import time


class CustmClass(qtw.QWidget):
    '''
    description einfügen
    '''

    # Attribut Signal
    custom_attribute = qtc.pyqtSignal(str)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # your code will go here


        # Interface
        self.resize(300, 210)
        # button
        self.get_output__button = qtw.QPushButton("start function ?")
        # lineEdit
        self.device_input1 = qtw.QLineEdit()
        self.device_input2 = qtw.QLineEdit()
        # Layout
        vboxlaout = qtw.QVBoxLayout()
        vboxlaout.addWidget(self.get_output__button)
        vboxlaout.addWidget(self.device_input1)
        vboxlaout.addWidget(self.device_input2)

        self.setLayout(vboxlaout)


        self.show()

        # Funktionalität

        self.get_output__button.clicked.connect(self.getdevice_data)

        self.custom_attribute.connect(self.device_input1.setText)
        # self.custom_attribute.connect(self.device_input2.setText)

    def getdevice_data(self):
        try:
            # Serial() opens a serial port
            my_serial = serial.Serial(port='COM6', baudrate=2400, bytesize=7,
                                      parity=serial.PARITY_NONE, timeout=None, stopbits=1)

            if my_serial.is_open:  
                print("port open")
                # log einfügen
                while my_serial.is_open:  

                    data = my_serial.read()  # wait forever till data arives
                    time.sleep(1)  # delay 

                    data_left = my_serial.inWaiting()  
                    data += my_serial.read(data_left)  

                    data = data.decode("utf-8", "strict")

                    if type(data) == str:
                        print(data)
                        return self.custom_attribute.emit(data)
            else:
                print("zu")

        except serial.serialutil.SerialException:
            print("not open")
            # logger hinzufügen


if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = CustmClass()
    sys.exit(app.exec_())
python pyqt pyqt5 pyserial
1个回答
0
投票
您不应该在主线程中执行耗时或耗时的循环,因为它们会阻塞事件循环。您要做的是在辅助线程上执行它,并通过信号发送信息。要顺序获取数据,您可以创建一个迭代器并通过next()函数访问每个元素。

import sys import threading import time import serial from PyQt5 import QtWidgets as qtw from PyQt5 import QtCore as qtc from PyQt5 import QtGui as qtg class SerialWorker(qtw.QObject): dataChanged = qtw.pyqtSignal(str) def start(self): threading.Thread(target=self._execute, daemon=True).start() def _execute(self): try: my_serial = serial.Serial( port="COM6", baudrate=2400, bytesize=7, parity=serial.PARITY_NONE, timeout=None, stopbits=1, ) while my_serial.is_open: data = my_serial.read() # wait forever till data arives time.sleep(1) # delay data_left = my_serial.inWaiting() data += my_serial.read(data_left) data = data.decode("utf-8", "strict") print(data) self.dataChanged.emit(data) except serial.serialutil.SerialException: print("not open") class Widget(qtw.QWidget): def __init__(self, parent=None): super().__init__(parent) self.resize(300, 210) self.get_output__button = qtw.QPushButton("start function ?") self.device_input1 = qtw.QLineEdit() self.device_input2 = qtw.QLineEdit() # Layout vboxlaout = qtw.QVBoxLayout(self) vboxlaout.addWidget(self.get_output__button) vboxlaout.addWidget(self.device_input1) vboxlaout.addWidget(self.device_input2) self.serial_worker = SerialWorker() self.device_iterator = iter([self.device_input1, self.device_input2]) self.get_output__button.clicked.connect(self.serial_worker.start) self.serial_worker.dataChanged.connect(self.on_data_changed) @qtw.pyqtSlot(str) def on_data_changed(self, data): try: device = next(self.device_iterator) device.setText(data) except StopIteration: pass if __name__ == "__main__": app = qtw.QApplication(sys.argv) w = CustmClass() w.show() sys.exit(app.exec_())

© www.soinside.com 2019 - 2024. All rights reserved.