简体   繁体   中英

Progress Bar PyQt5 style Minecraft Forge

I have a request on PyQt5 to which I am looking for a solution. I'm creating a videogame in Pygame and for uploading resources (images, audio etc) I would like to use PyQt5. I have already created a window with progress bar by following this and modified it graphically (css, etc.).

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)

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: 在此处输入图片说明



在此处输入图片说明

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:
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:

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. 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:

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_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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