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的主要内容,如果未能解决你的问题,请参考以下文章

Python time.sleep 杀死线程

windows *.bat批处理插入延时命令的方法

time.sleep() 和迭代直到秒过去之间的差异

time.sleep(..)的准确性会更改并影响循环性能,具体取决于是否正在运行其他进程

python函数深入浅出 16.time.sleep()函数详解

go runtime.Gosched() 和 time.Sleep() 做协程切换