【问题标题】:QML text doesn't update unless I resize window除非我调整窗口大小,否则 QML 文本不会更新
【发布时间】:2023-03-24 07:20:01
【问题描述】:

我有以下 Python 代码

import sys
import os
import threading
from time import sleep

from PySide2.QtCore import QObject
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine


def add_text(log_text):
    i = 1
    while True:
        text = log_text.property("text")
        log_text.setProperty("text", text + "\n" + str(i))
        i += 1
        sleep(1)


app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(os.path.join(os.path.dirname(__file__), "main.qml"))

root = engine.rootObjects()[0]
log_text = root.findChild(QObject, 'log_text')
x = threading.Thread(target=add_text, args=(log_text,))
x.start()

if not engine.rootObjects():
    sys.exit(-1)
sys.exit(app.exec_())

还有下面的 QML 文件

import QtQuick 2.13
import QtQuick.Window 2.13
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.13


Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    RowLayout {
        id: main_row
        anchors.fill: parent
        spacing: 0

        Rectangle {
            id: log_background
            width: 250
            height: 480
            color: "#515151"
            Layout.fillHeight: true

            Text {
                id: log_text
                objectName: "log_text"
                color: "#ffffff"
                anchors.fill: parent
                font.pixelSize: 12
                verticalAlignment: Text.AlignBottom
            }
        }

        ColumnLayout {
            id: image_buttons_column
            width: 100
            height: 100
            spacing: 0

            Image {
                id: image
                width: 504
                height: 429
                source: "qrc:/qtquickplugin/images/template_image.png"
                Layout.fillHeight: true
                Layout.fillWidth: true
                cache: true
                smooth: true
                mirror: false
                mipmap: false
                autoTransform: false
                asynchronous: false
                fillMode: Image.PreserveAspectFit
            }

            RowLayout {
                id: buttons_row
                width: 100
                height: 100
                spacing: 0

                Button {
                    id: button_yes
                    objectName: "button_yes"
                    Layout.fillWidth: true
                    palette {
                        button: "#64e764"
                    }
                    font.pointSize: 16
                    text: "Yes"
                    signal pressed
                    onClicked: pressed()
                }
                Button {
                    id: button_maybe
                    objectName: "button_maybe"
                    Layout.fillWidth: true
                    palette {
                        button: "#ffff00"
                    }
                    font.pointSize: 16
                    text: "Maybe"
                    signal pressed
                    onClicked: pressed()
                }
                Button {
                    id: button_no
                    objectName: "button_no"
                    Layout.fillWidth: true
                    palette {
                        button: "#ff726f"
                    }
                    font.pointSize: 16
                    text: "No"
                    signal pressed
                    onClicked: pressed()
                }
            }
        }
    }
}

当我运行上述 python 脚本时,文本会自行更新一次,显示数字 1,然后停止。每当我调整窗口大小时,所有应该添加的数字都会突然显示出来。每当文本更改而不是调整窗口大小时,如何让文本区域自行更新?

【问题讨论】:

    标签: python python-3.x qt qml qtquick2


    【解决方案1】:

    您正试图从主线程以外的线程操作 Qt。这将不起作用,并且可能会导致崩溃。几乎所有的 GUI 工具包都只能在主线程中操作。

    在这种特殊情况下,我会在您的 QML 文件中使用 QML Timer 对象。它将在主线程上执行并达到相同的目的。像这样:

                Text {
                    id: log_text
                    objectName: "log_text"
                    color: "#ffffff"
                    anchors.fill: parent
                    font.pixelSize: 12
                    verticalAlignment: Text.AlignBottom
    
                    Timer {
                        interval: 1000
                        running: true
                        repeat: true
    
                        property int i: 1
                        onTriggered: {
                            log_text.text += `\n${i}`;
                            i += 1;
                        }
                    }
                }
    
    

    如果出于其他原因必须在单独的线程中完成此操作,则需要从该线程调用主线程上的处理程序,以通过信号实际操作 Qt。 Qt 信号机制检测信号何时跨线程并在其事件队列中正确调度接收端的信号。

    【讨论】:

    • 您能否提供一个示例,说明我如何使用 QML 计时器实现这一目标,我在互联网上找到的示例根本不起作用。
    • 好的,为你添加了一个 Timer 示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多