QML仪表未从Python更新

2024-06-26 13:42:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我还在努力解决问题。。。我制作了一个python文件和一个QML文件。Python文件根据它通过UDP获得的数据更新仪表的值。你知道吗

但这只起作用一次。。。第一个UDP数据包进入并更新仪表,但是当它得到下一个数据包时,尽管值更新了,仪表本身却没有。你知道吗

质量管理

 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

在线程方法receivedata()中,我从UDP获取数据,对其进行处理,然后将其发送到仪表,如下所示:

view.rootContext().setContextProperty("itt1value", itt)

receivedata()中有一个while循环,其中包含上述细节,但仪表实际上只更新一次。如果我在QML文件中放入一个语句来显示itt1值,它总是具有正确的值,那么我是否需要放入一个方法来检测对该值的更改并重新绘制仪表?你知道吗

编辑:有人问我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)


Tags: 文件theviewvalue仪表socketqmlfile
1条回答
网友
1楼 · 发布于 2024-06-26 13:42:22

您有以下错误:

  • 不能直接从另一个线程修改GUI。

  • 可以使用setContextProperty()再次导出值,除非重新加载QML,否则这不会更改以前的值。

  • 如果希望“itt”修改QML中的任何值,那么它必须是兼容的类型,在这种情况下,CircularGauge的值是“real”,因此python支持的数据类型是float。

考虑到上述情况,我创建了一个QObject,因为它可以通过信号通知更改,因为它是线程安全的,并使用连接导出QObject以建立连接。你知道吗

主.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
    }
}

相关问题 更多 >