Python 信号未从线程传递到GUI
该遥测程序从USB端口上输入的串行字符串中读取数据。GUI在QML文件中定义,读取串行端口由字符串负责。GUI加载并正常工作。GUI send上的按钮具有一个事件处理程序,该事件处理程序可将信号发送回GUI。那很好用。串行读取线程启动并正常运行。它读取和解析数据并将其打印到屏幕上。但是,这些信号并没有返回到GUI 这快把我逼疯了,谢谢你的帮助 main.pyPython 信号未从线程传递到GUI,python,multithreading,qml,pyqt5,Python,Multithreading,Qml,Pyqt5,该遥测程序从USB端口上输入的串行字符串中读取数据。GUI在QML文件中定义,读取串行端口由字符串负责。GUI加载并正常工作。GUI send上的按钮具有一个事件处理程序,该事件处理程序可将信号发送回GUI。那很好用。串行读取线程启动并正常运行。它读取和解析数据并将其打印到屏幕上。但是,这些信号并没有返回到GUI 这快把我逼疯了,谢谢你的帮助 main.py import sys import serial from io import StringIO import csv from open
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)
您认为将其标记为“Java”会有帮助吗?嗯,我看到了python、多线程qml和PyQT5。@JarrettDunn我尝试运行您的代码,但失败了。但是试着这样做,
threadclass.auxVoltage.connect(lambda aux:print(aux))
insidemain()
。告诉我它是否有效。@JarrettDunn我删除了标记:)@daegontaven我在创建线程后将其添加到main()代码中。它可以工作,但打印的是一个随机数。如果您注释掉ser=serial.serial('COM6'),代码应该会运行。当然,没有输入,但您不知道是否有任何变化。b'7:44:11,0.0000,0,225,213,2124.8047N,15746.0610W,0.0\r\n'Aux 0.0000主管道0 174163984 b'7:44:12,0.0000,0,178,162,2124.8047N,15746.0610W,0.0\r\n'Aux 0.0000主管道0 174178688 b'7:44:13,0.0000,0,0,0,202,187,2124.8047N,15746.0610W,0\r\n'Aux 0.35361740主管道0