问题描述
鉴于此,我从 PyQt5 模块开始,我还在慢慢理解它背后的逻辑.也就是说,我遇到了一个找不到答案的问题,希望您能帮助我.
我有这个脚本:
given that, I'm starting with the PyQt5 module, I'm still slowly understanding the logic behind it. That said, I'm having a problem that I can not find an answer to and I hope you can help me.
I have this script:
import sys, socket, time
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from io import BytesIO as by
class loadGame(QWidget):
wLoadDisplay = 768
hLoadDisplay = 576
wLoadBar = 650
hLoadBar = 40
pbarCSS = """
QProgressBar
{
font-size: 20px;
font-weight: bold;
background-color: #FFF;
border: 4px solid #000;
text-align: center;
}
QProgressBar::chunk
{
background-color: #FF0000;
width: 1px;
}
"""
labelCSS = """
QLabel
{
font-size: 20px;
font-weight: bold;
background-color: #FFF;
border: 4px solid #000;
}
"""
fileResource = []
imgResource = []
vidResource = []
audResource = []
diaResource = []
txtResource = []
internetConnection = False
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.outputFile = by()
self.pbar = QProgressBar(self)
self.pbar.setGeometry((self.wLoadDisplay / 2 - self.wLoadBar / 2), (self.hLoadDisplay / 2 - self.hLoadBar * 2),
self.wLoadBar, self.hLoadBar)
self.pbar.setFormat("%v/%m")
self.pbar.setValue(0)
self.pbar.setStyleSheet(self.pbarCSS)
self.label = QLabel(self)
self.label.setGeometry((self.wLoadDisplay / 2 - self.wLoadBar / 2), (self.hLoadDisplay / 2),
self.wLoadBar, self.hLoadBar)
self.label.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
self.label.setStyleSheet(self.labelCSS)
self.setGeometry(0, 0, self.wLoadDisplay, self.hLoadDisplay)
oImage = QImage("bgloading.png")
sImage = oImage.scaled(QSize(self.wLoadDisplay, self.hLoadDisplay))
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
qtRectangle = self.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
self.move(qtRectangle.topLeft())
self.run()
def run(self):
self.checkConnection()
if self.internetConnection:
self.checkUpdate()
else:
pass
def checkConnection(self):
self.objectChange("Check Internet Connection", 1)
try:
host = socket.gethostbyname("www.google.it")
s = socket.create_connection((host, 80), 2)
self.internetConnection = True
except:
pass
self.count()
self.reset()
def checkUpdate(self):
pass
def objectChange(self, object, n):
self.label.setText(object)
self.pbar.setMaximum(n)
def count(self):
self.pbar.setValue(self.pbar.value() + 1)
def reset(self):
time.sleep(2)
self.pbar.setMaximum(0)
self.pbar.setValue(0)
self.label.setText("...")
if __name__ == '__main__':
loadDisplay = QApplication(sys.argv)
load = loadGame()
load.show()
sys.exit(loadDisplay.exec_())
在网上搜索,发现问题与time.sleep(2)"有关,即指令阻塞了两秒过去才出现的窗口.
事实是,我想花一两秒钟来显示栏的完成,然后再重置并转到def run (self)"中包含的下一条语句.
那么,有没有办法在不使用 Time 模块的情况下暂停?我不知道,也许用 QTimer?我再说一遍,我对 PyQt5 还不太了解,所以我不知道 QTimer 是否可以做同样的事情.
如果 QTimer 做不到,是否可以通过其他方式实现?我想避免 PyQt5 的线程",因为我读到可以这样做,但我想避免仅将它用于 Timer 模块.
我只添加了一个问题,以避免打开另一个问题并发布相同的脚本.
在脚本中,窗口背景是通过oImage = QImage(bgloading.png")"等完成的.
但是,我注意到,如果发现文件名错误,或者文件本身丢失,背景会显示为黑色.因此,如果有任何错误(错误名称或文件丢失),可以设置背景,例如白色?
因为当窗口加载这个错误"时,不会引发异常,脚本继续.
我已经编辑了已发布的脚本,使其仅包含 PyQt5 部分,因此您可以尝试一下.显然只有图像丢失了,可以用任何图像替换.
不幸的是我忘记写了self.set_display()"被报告的部分是为了表明一旦PyQt5执行的工作被终止,它将被关闭(这仍然缺失,因为使用Pycharm我会关闭执行程序中的脚本).脚本将继续调用self.set_display()"函数.
Searching on the web, I discovered that the problem is related to "time.sleep (2)", that is, the instruction blocks the window that does not appear until two seconds have passed.
The fact is that I would like to spend one or two seconds, showing the completion of the bar, before resetting and move on to the next statement contained in "def run (self)".
So, is there a way to make that pause, without using the Time module? I do not know, maybe with QTimer? I repeat, I do not know much about PyQt5 yet, so I'm not aware if QTimer can do the same thing.
If QTimer can not do it, is it possible in any other way? I would like to avoid the "threads" of PyQt5, because I read that it would be possible to do it, but I would like to avoid using it only for the Timer module.
I only add one more question, to avoid opening another one and publishing the same script.
In the script, the window background is done via "oImage = QImage (" bgloading.png ")" etc.
I noticed, however, that if the file name were found to be wrong, or the file itself is missing, the background is colored black. So, if there are any errors (wrong name or missing file) it's possible set a background, for example, white?
Because when the window is loaded with "this error", no exception is raised and the script continues.
I've edited the published script so that it contains only the PyQt5 part, so you can try it out. Obviously only the image is missing, which can be replaced with any image.
Unfortunately I had forgotten to write that the part where "self.set_display ()" was reported was to show that once the work performed by PyQt5 was terminated, it would be closed (which was still missing, because using Pycharm I would close the execution of the script from the program). The script would continue by calling the "self.set_display ()" function.
Edit2:我按照建议尝试替换time.sleep (2)",但得到了相同的结果.问题是如果我不暂停,窗口正常显示,但重置发生得太快,用户看不到进度条的填充.如果我改为输入time.sleep (2)"或建议的解决方案,则该窗口仅在暂停后出现,即已发生重置时.
I tried, as suggested, to replace "time.sleep (2)", but I get the same result. The problem is that if I do not put the pause, the window appears normally, but the reset happens too quickly and the user does not see the filling of the progress bar. If instead I put "time.sleep (2)" or, the suggested solution, the window appears only after the pause, that is when the reset has already occurred.
推荐答案
一个等价于time.sleep(2)
的对PyQt友好的表达式如下:
An expression equivalent to time.sleep(2)
that is friendly to PyQt is as follows:
loop = QEventLoop()
QTimer.singleShot(2000, loop.quit)
loop.exec_()
问题是因为你在暂停后显示widget,你必须在调用run()
之前做,还有一个错误是使用QImage
,对于您必须使用QPixmap
的小部件问题.
The problem is caused because you are showing the widget after the pause, you must do it before calling run()
, Also another error is to use QImage
, for questions of widgets you must use QPixmap
.
如果文件不存在,则 QPixmap
将为 null,要知道它是否存在,您应该使用 isNull()
方法:
If the file does not exist then QPixmap
will be null and to know if it is you should use the isNull()
method:
[...]
self.setGeometry(0, 0, self.wLoadDisplay, self.hLoadDisplay)
palette = self.palette()
pixmap = QPixmap("bgloading.png")
if not pixmap.isNull():
pixmap = pixmap.scaled(QSize(self.wLoadDisplay, self.hLoadDisplay))
palette.setBrush(QPalette.Window, QBrush(pixmap))
else:
palette.setBrush(QPalette.Window, QBrush(Qt.white))
self.setPalette(palette)
qtRectangle = self.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
self.move(qtRectangle.topLeft())
self.show()
self.run()
[...]
def reset(self):
loop = QEventLoop()
QTimer.singleShot(2000, loop.quit)
loop.exec_()
self.pbar.setMaximum(0)
self.pbar.setValue(0)
self.label.setText("...")
这篇关于time.sleep() 和 BackGround Windows PyQt5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!