Python 如何更新Pyside2 GUI上的进度条?

Python 如何更新Pyside2 GUI上的进度条?,python,multithreading,multiprocessing,qml,pyside2,Python,Multithreading,Multiprocessing,Qml,Pyside2,我一直试图在我的GUI上更新我的进度条,但我不知道怎么做。。。我提供的代码显示了更新的进度-我也只需要这个值来更新GUI上的进度条!这是来自Qt Creator的QML文件 main.py import os import sys import time from PySide2.QtGui import QGuiApplication from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType from PySide2.Q

我一直试图在我的GUI上更新我的进度条,但我不知道怎么做。。。我提供的代码显示了更新的进度-我也只需要这个值来更新GUI上的进度条!这是来自Qt Creator的QML文件

main.py

import os
import sys
import time

from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide2.QtCore import QObject, Slot, Signal, QTimer, QUrl, QThread
from pathlib import Path

from multiprocessing.pool import ThreadPool

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

    @Slot()
    def thread_progress(self):
        print("Worker")
        self.worker = Worker()
        self.thread = QThread()
        self.worker.moveToThread(self.thread)
        self.thread.start()
        self.worker.run()
        

class Worker(QObject):
    progress_value = Signal(float)

    @Slot()
    def run(self):
        self.progress = 0
        self.total = 100
        for i in range(0, self.total):
            self.update_progress()

    def update_progress(self):
        print(f"{self.progress} / {self.total}")
        self.progress += 1
        self.progress_value.emit(self.progress)
        time.sleep(1)

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    # Get Context
    main = MainWindow()
    engine.rootContext().setContextProperty("backend", main)
    # Set App Extra Info
    app.setOrganizationName("zardoss")
    app.setOrganizationDomain("N/A")

    engine.load(os.fspath(Path(__file__).resolve().parent / "main.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec_())
main.py文件与main.qml文件连接。GUI有一个按钮、进度条和一个文本输入元素。我只关心在按下generate按钮后进度条是否填满。 按下generate按钮后,您可以从控制台中看到,1-100的值正在填充,但它没有填充进度条,因为我不确定如何填充

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15
import QtQuick.Shapes 1.15

Window {
    id: mainWindow
    width: 750
    height: 500
    visible: true
    color: "#00000000"

    // Remove title bar
    flags: Qt.Window | Qt.FramelessWindowHint

    // Properties
    property int windowStatus: 0
    property int windowMargin: 10

    title: qsTr("Progress Bar")
    Rectangle {
        id: bg
        color: "#2c313c"
        border.color: "#f12c313c"
        border.width: 1
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.rightMargin: windowMargin
        anchors.leftMargin: windowMargin
        anchors.bottomMargin: windowMargin
        anchors.topMargin: windowMargin
        z:1

        Rectangle {
            id: appContainer
            height: 480
            color: "#00000000"
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            anchors.rightMargin: 1
            anchors.leftMargin: 1
            anchors.bottomMargin: 1
            anchors.topMargin: 1

            Rectangle {
                id: content
                color: "#00000000"
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.top: topBar.bottom
                anchors.bottom: parent.bottom
                anchors.topMargin: 0

                Button {
                    id: btnGenerate
                    x: 265
                    y: 44
                    width: 200
                    height: 50
                    text: "Generate"
                    anchors.verticalCenter: parent.verticalCenter
                    anchors.right: parent.right
                    anchors.horizontalCenterOffset: 0
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.verticalCenterOffset: 165
//                    colorPressed: "#1e5425"
//                    colorMouseOver: "#42b852"
                    font.pointSize: 14
                    display: AbstractButton.TextBesideIcon
                    font.bold: false
//                    colorDefault: "#328a3f"
                    anchors.rightMargin: 250
                    onPressed: {
                        // backend.generate()
                        backend.thread_progress()
                    }
                }

                ProgressBar{
                    id: progressBar
                    x: 239
                    y: 64
                    visible: true
                    width: 661
                    height: 250
//                    text: "%"
                    anchors.verticalCenter: parent.verticalCenter
                    value: 0
                    //bgColor: "#00000/*000"
                    //dropShadowColor: "#20000000"
                    //samples: 16
                    anchors.verticalCenterOffset: -15
                    anchors.horizontalCenter: parent.horizontalCenter
                    
                }
            }
        }
    }
    DropShadow{
        anchors.fill: bg
        horizontalOffset: 0
        verticalOffset: 0
        radius: 10
        samples: 16
        color: "#80000000"
        source:bg
        z: 0
    }

    Connections{
        target: backend

        function onLinkValid(valid)  {
            if(valid === true)    {
                textField.textColor = "#00FF00"
            } else {
                textField.textColor = "#FF00FF"
            }
        }
    }
}

您案例中的问题是,具有进度值的信号未连接到GUI的任何元素

在这种情况下,必须在与ProgressBar连接的、暴露于QML的类中创建一个信号,并且该信号必须接收来自工作者的信号的信息。另一方面,您不应该直接调用“run()”方法,因为它将在调用它的线程中执行,在您的情况下,该线程是主线程,因此它将阻止GUI,相反,您必须通过信号或使用QTimer间接调用它

导入操作系统
导入系统
导入时间
从pathlib导入路径
从PySide2.QtGui导入qgui应用程序
从PySide2.QtQml导入QQmlApplicationEngine
从PySide2.QtCore导入QObject、Slot、Signal、QTimer、QUrl、QThread
类后端(QObject):
进度变化=信号(浮动,名称=“进度变化”)
def uuu init uuu(self,parent=None):
super()。\uuuu init\uuuu(父级)
self.worker=worker()
self.worker.progress\u已更改。连接(self.progress\u已更改)
self.worker_thread=QThread()
self.worker.moveToThread(self.worker\u线程)
self.worker_thread.start()
@槽()
def start_工作人员(自身):
QTimer.singleShot(0,self.worker.run)
班级工作人员(QObject):
进度变化=信号(浮动)
@槽()
def运行(自):
self.progress=0
总数=100
对于范围内的i(0,自身总数):
self.update_progress()
def更新_进度(自我):
打印(f“{self.progress}/{self.total}”)
自我进步+=1
self.progress\u changed.emit(self.progress)
时间。睡眠(1)
如果名称=“\uuuuu main\uuuuuuuu”:
app=qgui应用程序(sys.argv)
引擎=QQmlApplicationEngine()
backend=backend()
engine.rootContext().setContextProperty(“后端”,后端)
engine.load(os.fspath(路径(_文件__).resolve().parent/“main.qml”))
如果不是engine.rootObjects():
系统出口(-1)
ret=app.exec
#backend.worker_thread.quit()
#backend.worker\u thread.wait()
系统退出(ret)

请提供一个链接,而不是外部链接。回购协议中包含大量文件。对每个人来说,克隆repo并运行它比手动复制、粘贴和下载必要的文件更容易。这样做的目的不是帮助用户实施他们的项目,而是解决一个特定的问题,以便其他用户可以将其作为未来问题的参考。因此,文章必须是独立的,也就是说,他们不能依赖外部资源,因为,例如,链接可能会在将来断开,使文章无法使用。如果你的项目很小,那么它将是MRE的一个很好的候选人,但如果不是这样,那么你必须努力做到这一点:要么删除与当前问题无关的文件,复制你文章中的所有代码,要么创建一个新的文件。project只关注功能,并在您的帖子中复制代码。同时阅读并复习@zardos抱歉,这是你的观点。在什么基础上,从安全角度来看,我们可以克隆并运行一些我们一无所知的随机回购?在任何情况下,我们当然不能通过“大量文件”为您找到与您的问题相关的特定点,这是您的工作部分。请仔细阅读给定的链接,并遵循他们的建议。这非常有效,谢谢@eyllanesc。由于我正在努力学习qml和py文件之间的通信方面,我在哪里可以学到更多关于这方面的知识。
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Window 2.15

Window {
    id: mainWindow

    width: 750
    height: 500
    visible: true
    color: "#00000000"
    title: qsTr("Progress Bar")

    Row {
        spacing: 10
        anchors.centerIn: parent

        Button {
            id: btnGenerate

            text: "start"
            onClicked: backend.start_worker()
        }

        ProgressBar {
            id: progressBar
            from: 0
            to: 100.0
        }

    }

    Connections {
        target: backend

        function onProgressChanged(progress) {
            progressBar.value = progress;
        }

    }

}