time.sleep() 和背景 Windows PyQt5
Posted
技术标签:
【中文标题】time.sleep() 和背景 Windows PyQt5【英文标题】:time.sleep() and BackGround Windows PyQt5 【发布时间】:2018-06-10 21:08:04 【问题描述】:鉴于此,我从 PyQt5 模块开始,我仍然在慢慢理解它背后的逻辑。也就是说,我遇到了一个无法找到答案的问题,希望您能帮助我。 我有这个脚本:
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()”函数继续。
Edit2:按照建议,我尝试替换“time.sleep (2)”,但得到了相同的结果。问题是,如果我不暂停,窗口会正常显示,但重置发生得太快,用户看不到进度条的填充。如果我改为输入“time.sleep (2)”,或者建议的解决方案,窗口仅在暂停后出现,即重置已经发生。
【问题讨论】:
不要合并库,制作这样的软件无关紧要。 PyQt5 在脚本开头使用它只是为了加载“内存中”的文件,然后关闭它并继续使用 Pygame。没有组合或什么都没有,但就好像它们是分开的。 好的,你可以展示一个可以运行的代码来看看什么是最好的选择,你的目前不是。 【参考方案1】:对PyQt友好的等价于time.sleep(2)
的表达式如下:
loop = QEventLoop()
QTimer.singleShot(2000, loop.quit)
loop.exec_()
问题是因为你在暂停后显示小部件,你必须在调用run()
之前做,另外一个错误是使用QImage
,对于小部件的问题你必须使用QPixmap
。
如果文件不存在,那么QPixmap
将为空,要知道它是否存在,您应该使用isNull()
方法:
[...]
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 (2)”的位置吧? 我试过了,但不幸的是我遇到了同样的问题。但是我修改了问题,以便只包括 PyQt5 部分。 我是个笨蛋,我专注于暂停的事实,我认为我不必移动指令“show()”。感谢您提供有关“QImage”和“QPixmap”的信息。不幸的是,即使进行了此更正,如果文件丢失,也不会引发异常或错误,因此我无法干预,可能会更改背景颜色或其他。 再一次,我用意大利语说的“Tanto di cappello”(我不能老实说用英语 XD)开玩笑,我再次感谢您的宝贵帮助。 如何导入qeventloop? AttributeError:类型对象“QObject”没有属性“QEventLoop”以上是关于time.sleep() 和背景 Windows PyQt5的主要内容,如果未能解决你的问题,请参考以下文章
time.sleep(..)的准确性会更改并影响循环性能,具体取决于是否正在运行其他进程