加载栏作业在作业完成之前不会呈现 PyQt5

Loading bar job doesn't render till job is complete PyQt5

我使用包含进度条的 PyQt5 创建了一个 UI。我在 python 中编写了这个进度条,以便实时增加到 99%。我面临的问题是 window 在作业完成之前不会加载。我读过类似的关于线程的帖子,但我无法从中掌握任何内容。如果有人能向我解释一个解决方案,我将不胜感激,如果它确实需要线程,这是我尚未学习的一个方面,请用外行术语向我解释。

import sys, os, sqlite3
import random, datetime
from PyQt5 import QtCore, QtGui, uic
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtWidgets 
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, 
QMessageBox, QProgressBar, QSplashScreen
import sqlite3
import time


window2 = uic.loadUiType("login_loadingbar.ui")[0]


class LoadingBar(QtWidgets.QMainWindow, window2): 
   def __init__(self, parent=None):
       QtWidgets.QMainWindow.__init__(self, parent)
       self.setupUi(self)
        
       #title
       self.setWindowTitle('Loading')

        
        
    
    #makes progress bar go from 0-100, time scaled
    def progress(self):
        for i in range(100):
            time.sleep(0.1)
            self.login_progressBar.setValue(i)
        


app = QApplication(sys.argv)
w2 = LoadingBar(None)
w2.show()
w2.progress()
app.exec_()

当你创建 gui 应用程序时,你有一个线程,在这个线程中有一个叫做事件循环的东西 - 它本质上是处理事件的 while true 循环 - 在必要时重绘小部件,将键盘和鼠标输入分派给相关的小部件。

因为你只有一个线程,你一次只能做一件事,所以当你做像 time.sleep() 这样的长时间操作时,事件循环被冻结 - 没有小部件被重绘,没有输入被处理直到它完成并到达事件循环的下一次迭代。

您可以创建第二个线程并将操作移到那里,或者在可以将操作拆分成多个部分的简单情况下 - 在各个部分之间的事件循环中处理事件:

for i in range(100):
    time.sleep(0.1)
    self.login_progressBar.setValue(i)
    QtWidgets.QApplication.processEvents()

这种方式事件循环有点管用,但应用程序不是 100% 响应的,因为每个 time.sleep(0.1) 都会冻结它,所以鼠标点击和其他事件可能无法处理。