简体   繁体   English

PyQt5 QThread将变量传递给main

[英]PyQt5 QThread passing variables to main

I am trying to make a GUI which will interact with a serial device. 我正在尝试制作将与串行设备交互的GUI。

As of right now, I have successfully made a very simple GUI which can open and close the serial connection. 到目前为止,我已经成功制作了一个非常简单的GUI,可以打开和关闭串行连接。

Below is my code: 下面是我的代码:

import sys
from PyQt5.QtCore import *

from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QMessageBox,      QAction, qApp, QPushButton

from PyQt5.QtGui import QIcon

import serial

ser = serial.Serial()
ser.baudrate = 115200
ser.port = 2

class MainUI(QMainWindow):

def __init__(self):
    super().__init__()
    self.initUI()
    self.workerThread = SerialRead()
    self.connect(self.workerThread, QtCore.SIGNAL("mysignal(QString)"),self.on_change, QtCore.Qt.QueuedConnection)

def initUI(self):
    btn1 = QPushButton('Open Serial', self)
    btn1.clicked.connect(self.openSerial)
    btn1.resize(btn1.sizeHint())
    btn1.move(50,50)

    btn2 = QPushButton('Close Serial', self)
    btn2.clicked.connect(self.closeSerial)
    btn2.resize(btn2.sizeHint())
    btn2.move(50,100)

    exitAction = QAction(QIcon('exit.png'), '&Exit', self)
    exitAction.setShortcut('Alt+F4')
    exitAction.setStatusTip('Exit application')
    exitAction.triggered.connect(self.closeEvent)

    self.statusBar()
    menubar = self.menuBar()
    fileMenu = menubar.addMenu('&File')
    fileMenu.addAction(exitAction)

    self.statusBar().showMessage('Ready')
    self.setGeometry(300,300,250,150)
    self.setWindowTitle('Motor Driver')

    self.show()

def openSerial(self):
    ser.open()
    self.workerThread.start()

def closeSerial(self):
    ser.close()
    self.workerThread.terminate()

def closeEvent(self, event):
    reply = QMessageBox.question(self, 'Message', "Are you sure you want to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
    if reply == QMessageBox.Yes:
        event.accept()
    else:
        event.ignore()

class SerialRead(QThread):
def __init__(self):
    super().__init__()
    self.data = []

def run(self):
    while True:
        x = ser.readline()
        # if x != b'\n':
        #   self.data.append(str(x))
        # else:
        self.emit(QtCore.SIGNAL("mysignal(Qstring)"), (x.decode("utf-8")))
            # self.data = []



if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainUI()
sys.exit(app.exec_())

My question would be on how to pass a variable from my serialRead thread to my MainUI? 我的问题是如何将变量从serialRead线程传递到MainUI? As you can see on my code, I have tried the solutions which I can found online, which is by using: 如您在我的代码上看到的,我已经尝试通过在线使用以下方法找到解决方案:

self.connect(self.workerThread, QtCore.SIGNAL("mysignal(QString)"),self.on_change, QtCore.Qt.QueuedConnection)

on my MainUI class and by using: 在我的MainUI类上,并使用:

self.emit(QtCore.SIGNAL("mysignal(Qstring)"), (x.decode("utf-8")))

on my thread. 在我的线程上。

However, this gives me this error: 'MainUI' object has no attribute 'connect' 但是,这给了我这个错误:'MainUI'对象没有属性'connect'

So how should I pass a variable from my thread to my MainUI? 那么如何将变量从线程传递到MainUI?

It has been almost 2 years since I last touched python and I just started this project about 2 days ago, but is there anyway I can improve my code? 自从我上一次接触python以来已经快2年了,大约2天前我才开始这个项目,但是无论如何我可以改善我的代码吗? Are there any subtle or obvious errors that I made? 我是否有任何细微或明显的错误?

On PyQt5, you have to use the new style signal and slot 在PyQt5上,您必须使用新样式的信号和插槽

self.workerThread.mySignal.connect(self.on_change)

class SerialRead(QThread):
    mySignal = pyqtSignal(str) 

    def __init__(self):    
        super().__init__()

    def run(self):
        self.mySignal.emit(some_string)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM