我仍在处理QT ...我制作了一个python文件和一个QML文件。 Python文件从通过UDP获取的数据中更新量规的值。
这只能工作一次...第一个UDP数据包进入并更新量规,但是当它获取下一个数据包时,尽管值进行了更新,但量规本身却没有。
QML
CircularGauge {
id: circularGauge
x: 30
y: 30
value: itt1value
minimumValue: 0
maximumValue: 1200
tickmarksVisible: false
style: CircularGaugeStyle {
maximumValueAngle: 400
minimumValueAngle: 90
}
}
Python:
def configureApplication():
# Set up the application window
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
view.setTitle("my title")
# Load the QML file
qml_file = os.path.join(os.path.dirname(__file__), "maingui.qml")
view.setSource(QUrl.fromLocalFile(os.path.abspath(qml_file)))
# load the slots into the QML file
view.rootContext().setContextProperty("itt1value", 0)
t = threading.Thread(target=receivedata, args=(view,))
t.start()
# Show the window
if view.status() == QQuickView.Error:
sys.exit(-1)
view.show()
# execute and cleanup
app.exec_()
del view
在线程方法receiveata()中,我从UDP获取数据,对其进行处理,然后将其发送到仪表,如下所示:
view.rootContext().setContextProperty("itt1value", itt)
receivedata()中有一个带有以上详细信息的while循环,但量规实际上仅更新一次。如果我在QML文件中放置一条语句以显示itt1value,则它始终具有正确的值,那么我是否需要使用一种方法来检测对该值的更改并重新绘制量规?
编辑:我被要求提供Receivedata()的详细信息,所以我将其附加在这里:
def receivedata(view):
print("Starting UDP server...")
UDP_IP = "192.168.0.14"
UDP_PORT = 49000
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
olditt = 0
loopruns = 0 # for debugging
while True:
rawstring = sock.recv(1024)
hexarray = []
#lots of irrelevent formatting here, result is int(value)
itt = float(hextoint(value, olditt))
olditt = itt
itt = format(itt, '.3f')
current = str(loopruns) # for debugging
view.setTitle(current) # for debugging
view.rootContext().setContextProperty("itt1value", itt)
loopruns = loopruns + 1
print(itt)
答案 0 :(得分:1)
您遇到以下错误:
您不能直接从另一个线程修改GUI。
可以使用setContextProperty()
再次导出值,除非重新加载QML,否则不会更改以前的值。
如果要“ itt”修改QML中的任何值,它必须是兼容类型,在这种情况下,CircularGauge的值是“ real”,因此python支持的数据类型是float。 p>
考虑到上述情况,我创建了一个QObject,因为它是线程安全的,它可以通过信号通知更改,并使用Connections导出建立连接的QObject。
main.py
import os
import random
import sys
import threading
import time
from PySide2.QtCore import QObject, QUrl, Signal
from PySide2.QtGui import QGuiApplication
from PySide2.QtQuick import QQuickView
class Connections(QObject):
titleChanged = Signal(str, arguments=["title"])
valueChanged = Signal(float, arguments=["value"])
def receivedata(connector):
# configurations
loopruns = 0
while True:
# other stuff
time.sleep(0.1)
itt = random.uniform(0.0, 1200.0)
connector.valueChanged.emit(itt)
connector.titleChanged.emit(str(loopruns))
loopruns += 1
def main(args):
app = QGuiApplication(args)
view = QQuickView(title="my title", resizeMode=QQuickView.SizeRootObjectToView)
connector = Connections()
connector.titleChanged.connect(view.setTitle)
view.rootContext().setContextProperty("connector", connector)
# Load the QML file
qml_file = os.path.join(os.path.dirname(__file__), "maingui.qml")
view.setSource(QUrl.fromLocalFile(os.path.abspath(qml_file)))
# start thread
threading.Thread(target=receivedata, args=(connector,)).start()
# Show the window
if view.status() == QQuickView.Error:
return -1
view.show()
# execute and cleanup
ret = app.exec_()
del view
return ret
if __name__ == "__main__":
sys.exit(main(sys.argv))
maingui.qml
import QtQml 2.13
import QtQuick.Extras 1.4
import QtQuick.Controls.Styles 1.4
CircularGauge {
id: circularGauge
value: 100
minimumValue: 0
maximumValue: 1200
tickmarksVisible: false
style: CircularGaugeStyle {
maximumValueAngle: 400
minimumValueAngle: 90
}
Connections{
target: connector
onValueChanged: circularGauge.value = value
}
}