python - 信号未从线程传递到 GUI

标签 python multithreading qml pyqt5

该遥测程序从 USB 端口传入的串行字符串中读取数据。 GUI 在 QML 文件中定义,并通过字符串读取串行端口。 GUI 加载并正常工作。 GUI 发送上的按钮有一个事件处理程序,可以将信号发送回 GUI。效果很好。串行读取线程启动并正确运行。它读取并解析数据并将其打印到屏幕上。然而,信号并没有返回到 GUI。

这让我发疯,感谢您的帮助。

main.py

import sys
import serial
from io import StringIO
import csv
from openpyxl import Workbook
import datetime
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QThread

global ser
#define and open the serial port
ser=serial.Serial('COM6')

class Dash(QObject):
    def __init__(self):
        QObject.__init__(self)

    ampHourvalue = pyqtSignal(int, arguments=['amphour'])


    @pyqtSlot(int)
    def reset(self, value):

        value=100  #put amp hour capacity here
        self.ampHourvalue.emit(value)

class ThreadClass(QThread):
    # Create the signal
    auxVoltage = pyqtSignal(str, arguments=['auxvolt'])
    mainVoltage = pyqtSignal(int, arguments=['mainvolt'])
    arrayCurrent = pyqtSignal(int, arguments=['arraycurrent'])
    motorCurrent = pyqtSignal(int, arguments=['motorcurrent'])


    def __init__(self, parent=None):
        super(ThreadClass, self).__init__(parent)

    def run(self):
        try:
            wb=load_workbook("History.xls") #attemps to open the history excel file
        except:
            wb=Workbook() #creates and empty excel workbook if histortory is not found

        WorkSheetName=datetime.date.today() #get todays date
        ws = wb.create_sheet("%s" %WorkSheetName) #create worksheet with the date as tittle

        while True:
            data=ser.readline(120) #read the stream
            print(data)
            data=data.decode() #convert stream from bytes to characters
            data=StringIO(data)#convert a stream of characters into string
            dataset=csv.reader(data, delimiter= ',') #read the CSV string into individual array
            dataset=list(dataset) #convert the array to list

            ws.append(dataset[0])
            wb.save("History.xls")

            #extract individual data points
            aux=dataset[0][1]
            print("Aux ", aux)
            mainvolt=dataset[0][2]
            print("Main ", mainvolt)
            arraycurrent=dataset[0][3]
            motorcurrent=dataset[0][4]

            # Emit the signals
            self.auxVoltage.emit(aux)
            self.mainVoltage.emit(mainvolt)
            self.arrayCurrent.emit(arraycurrent) 
            self.motorCurrent.emit(motorcurrent) 

            pass       


def main():
    import sys
    # Create an instance of the application
    app = QGuiApplication(sys.argv)

    #start the thread
    threadclass=ThreadClass()
    threadclass.start()


    # Create QML engine
    engine = QQmlApplicationEngine()
    # Create a Dash object
    dashboard = Dash()
    # And register it in the context of QML
    engine.rootContext().setContextProperty("dashboard", dashboard)
    # Load the qml file into the engine
    engine.load("take2.qml")

    engine.quit.connect(app.quit)
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

take2.qml

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
import QtQuick.Extras 1.4


ApplicationWindow {
id: applicationWindow
visible: true
width: 1000
height: 500
color: "black"
title: "I like Telemetry"

Text {
    id: text1
    x: 300
    y: 6
    width: 353
    height: 34
    text: qsTr("Solar Car Telemetry System")
    anchors.horizontalCenter: parent.horizontalCenter
    horizontalAlignment: Text.AlignHCenter
    font.family: "Times New Roman"
    font.pixelSize: 30
    color: "grey"
}


CircularGauge {
    id: circularGauge
    x: 55
    y: 111
    width: 308
    height: 279
    anchors.verticalCenter: rowLayout.verticalCenter

    Text {
        id: text2
        x: 143
        y: 226
        text: qsTr("Speed")
        anchors.horizontalCenter: parent.horizontalCenter
        horizontalAlignment: Text.AlignHCenter
        font.pixelSize: 12
        color: "grey"
    }
}

CircularGauge {
    id: auxvoltgauge
    x: 381
    y: 92
    width: 151
    height: 141
    stepSize: .5
    maximumValue: 15
    value:1


Text {
    id: text3
    x: 445
    width: 69
    text: qsTr("Aux Battery")
    anchors.top: parent.top
    anchors.topMargin: -17
    horizontalAlignment: Text.AlignHCenter
    anchors.horizontalCenter: parent.horizontalCenter
    font.pixelSize: 12
    color: "grey"
}

Text {
    id: text5
    x: 64
    y: 106
    text: qsTr("Volts")
    anchors.bottom: parent.bottom
    anchors.bottomMargin: 10
    font.pixelSize: 12
    color: "grey"
}
}

CircularGauge {
    id: circularGauge2
    x: 381
    y: 288
    width: 151
    height: 141
    visible: true


Text {
    id: text4
    x: 445
    y: 259
    text: qsTr("Main Battery")
    anchors.top: parent.top
    anchors.topMargin: -17
    fontSizeMode: Text.FixedSize
    horizontalAlignment: Text.AlignHCenter
    anchors.horizontalCenter: parent.horizontalCenter
    font.pixelSize: 12
    color: "grey"
}
Text {
    id: text6
    x: 64
    y: 106
    text: qsTr("Volts")
    anchors.bottom: parent.bottom
    anchors.bottomMargin: 10
    font.pixelSize: 12
    color: "grey"
}
}

Gauge {
    id: amphourgauge
    x: 803
    y: 103
    width: 114
    height: 294
    anchors.verticalCenterOffset: 0
    anchors.verticalCenter: parent.verticalCenter
    value: 50

    Text {
        id: text7
        x: 30
        y: 260
        text: qsTr("AMP HOURS")
        anchors.bottom: parent.bottom
        anchors.bottomMargin: -25
        anchors.horizontalCenter: parent.horizontalCenter
        font.pixelSize: 18
        color: "grey"
    }

}



Button {
    id: amphourreset
    objectName: amphourreset
    x: 795
    y: 434
    text: qsTr("Reset")

    onClicked: dashboard.reset(amphourgauge.value)
}



Gauge {
    id: arraycurrent
    x: 621
    y: 160

    Text {
        id: text10
        text: qsTr("Array Current")
        font.pixelSize: 12
        color: "grey"
        anchors.top: parent.top
        anchors.topMargin: -17
        fontSizeMode: Text.FixedSize
        horizontalAlignment: Text.AlignHCenter
        anchors.horizontalCenter: parent.horizontalCenter
    }
}

Gauge {
    id: motorcurrent
    x: 710
    y: 160

    Text {
        id: text9
        text: qsTr("Motor Current")
        font.pixelSize: 12
        color: "grey"
        anchors.top: parent.top
        anchors.topMargin: -17
        fontSizeMode: Text.FixedSize
        horizontalAlignment: Text.AlignHCenter
        anchors.horizontalCenter: parent.horizontalCenter
    }
}

Connections {
    target: dashboard

    onAmpHourvalue: {
    // sub was set through arguments=['amphour']
        amphourgauge.value = amphour
        }

    onAuxVoltage: {
    // sub was set through arguments=['auxvolt']
        auxvoltgauge.value = auxvolt
        }
}

}

最佳答案

@daegontaven 是正确的。问题是该线程未连接到包含 GUI 的线程。连接两个线程即可解决问题。我重新排序了一些代码。

class ThreadClass(QThread):
    # Create the signal
    ampHourvalue = pyqtSignal(float, arguments=['amphour'])
    auxVoltage = pyqtSignal(float, arguments=['auxvolt'])
    mainVoltage = pyqtSignal(float, arguments=['mainvolt'])
    arrayCurrent = pyqtSignal(float, arguments=['arraycurrent'])
    motorCurrent = pyqtSignal(float, arguments=['motorcur'])


    def __init__(self, parent=None):
        super(ThreadClass, self).__init__(parent)
        #connects  the signals from the thread to the signals in the thread that is running the GUI

        self.auxVoltage.connect(dashboard.auxVoltage)
        self.mainVoltage.connect(dashboard.mainVoltage)
        self.motorCurrent.connect(dashboard.motorCurrent)
        self.arrayCurrent.connect(dashboard.arrayCurrent)
        self.ampHourvalue.connect(dashboard.ampHourvalue)

关于python - 信号未从线程传递到 GUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46483545/

相关文章:

python - 如何使用python(Anaconda)使用vba在指定的单元格位置将图片插入到Excel中

Python:list的类似dict.get()的方法

java - 实现HIkariCP时出现ResultSetImpl错误

C#:关于成员变量线程安全的问题

android - Qt QML Camera 到 Android 上的 C++ QImage

python - 将值应用于列并按这些值对所有列进行分组

python - Pandas 将文本列导出为单个未转义的文本文件

linux - 关于pthread_cond_wait的原子性操作的问题

c++ - 最简单的 Qt 对话框

c++ - Qt 样式表是做什么用的,它们是如何工作的?