简体   繁体   English

进度条PyQt5风格的Minecraft Forge

[英]Progress Bar PyQt5 style Minecraft Forge

I have a request on PyQt5 to which I am looking for a solution. 我对PyQt5有一个要求,我正在寻求一个解决方案。 I'm creating a videogame in Pygame and for uploading resources (images, audio etc) I would like to use PyQt5. 我正在Pygame中创建一个视频游戏,并希望使用PyQt5上传资源(图像,音频等)。 I have already created a window with progress bar by following this and modified it graphically (css, etc.). 通过遵循此步骤 ,我已经创建了一个带有进度条的窗口,并对其进行了图形化修改(css等)。

My goal is to make the window in PyQt5 in the Minecraft Forge style, where, if you have, there is a white window with a progress bar, where mods, textures, etc. are loaded and the name is written under the loaded resource bar and the percentage (or in the case of Minecraft Forge the quantity, example: 74/1349) 我的目标是使用Minecraft Forge风格的PyQt5窗口,如果有的话,这里有一个带有进度条的白色窗口,其中加载了mod,纹理等,并且名称被写在已加载的资源栏下和百分比(如果是《我的世界》,则为数量,例如:74/1349)

The problem is that I can not understand how I should remove the button in the example and replace it so that every time a resource is loaded from the program, the progress bar is updated. 问题是我不明白如何删除示例中的按钮并替换它,以便每次从程序加载资源时,进度条都会更新。

In my case, the "load class" is called when the "game class" is initialized. 就我而言,初始化“游戏类”时将调用“负载类”。

To explain better, in PyQt5 I would like to create a window with the progress bar like this: 为了更好地解释,我想在PyQt5中创建一个带有进度条的窗口,如下所示: 在此处输入图片说明



在此处输入图片说明

Where from the "game class" the resources are loaded and the progress bar for each resource loaded is updated, or otherwise something like that. 从“游戏类”的位置加载资源,并更新每个加载的资源的进度条,或者类似的方法。

Edit for eyllanesc: 编辑eyllanesc:
I tried with: 我尝试了:

class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)
        self.pbar.setFormat("%v/%m")
        self.pbar.setMaximum(150)
        self.pbar.setValue(0)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QProgressBar')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

    while True:
        g = input("aggiornare?")
        if g is "y":
            w.pbar.setValue(w.pbar.value()+1)


class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)
        self.pbar.setFormat("%v/%m")
        self.pbar.setMaximum(150)
        self.pbar.setValue(0)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QProgressBar')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()

    while True:
        g = input("aggiornare?")
        if g is "y":
            w.pbar.setValue(w.pbar.value()+1)

        sys.exit(app.exec_())


class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)
        self.pbar.setFormat("%v/%m")
        self.pbar.setMaximum(150)
        self.pbar.setValue(0)
        timer = QTimer(self)
        timer.start(1000)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QProgressBar')
        self.show()
        self.run()

    def run(self):
        while True:
            g = input("aggiornare?")
            if g is "y":
                self.onTimeout()

    def onTimeout(self):
        self.pbar.setValue(self.pbar.value()+1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

I have also tried in other ways, but they are all similar to each other. 我也尝试过其他方式,但是它们彼此相似。

To set the text format you must use the setFormat() method, you must set the maximum value through setMaximum() and the current value through setValue() , in the following example I use QTimer to simulate the resource load: 要设置文本格式,必须使用setFormat()方法,必须通过setMaximum()设置最大值,并通过setValue()设置当前值,在以下示例中,我使用QTimer来模拟资源负载:

Complete code: 完整的代码:

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import  *

class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)
        self.pbar.setFormat("%v/%m")
        self.pbar.setMaximum(150)
        self.pbar.setValue(1)
        timer = QTimer(self)
        timer.timeout.connect(self.onTimeout)
        timer.start(1000)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QProgressBar')

    def onTimeout(self):
        self.pbar.setValue(self.pbar.value()+1)

if __name__ == '__main__':  
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Output: 输出:

在此处输入图片说明


In pygame one is in charge of generating an infinite loop but in PyQt one calls that loop through app.exec_() , that is, that loop is internal. 在pygame中,一个负责生成无限循环,但在PyQt中,一个通过app.exec_()调用该循环,也就是说,该循环是内部的。 So the input() should not be used directly since it locks that loop and generates the GUI behaves inadequately, what you should do is create another thread and run it there for it use QRunnable and QThreadPool , in addition to QMetaObject::invokeMethod() to update the values as shown below: 因此,不应直接使用input()因为它会锁定该循环并生成GUI行为QThreadPool ,除了QMetaObject::invokeMethod()外,您应该创建另一个线程并在其中使用QRunnableQThreadPool运行该线程。更新值,如下所示:

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)
        self.pbar.setFormat("%v/%m")
        self.pbar.setMaximum(150)
        self.pbar.setValue(0)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QProgressBar')
        self.show()
        self.runnable = Runnable(self)
        QThreadPool.globalInstance().start(self.runnable)

    @pyqtSlot()
    def updateProgressBar(self):
        self.pbar.setValue(self.pbar.value()+1)

class Runnable(QRunnable):
    def __init__(self, w):
        QRunnable.__init__(self)
        self.w = w

    def run(self):
        while True:
            g = input("aggiornare?")
            if g is "y":
                QMetaObject.invokeMethod(self.w, "updateProgressBar", Qt.QueuedConnection)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    sys.exit(app.exec_())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM