首页 文章

time.sleep()和BackGround Windows PyQt5

提问于
浏览
2

鉴于此,我仍然在慢慢理解它背后的逻辑 . 那就是说,我遇到了一个无法找到答案的问题,希望你能帮到我 .
我有这个脚本:

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)"中包含的下一个语句 .
那么,有没有办法在不使用时间模块的情况下进行暂停?我不知道,也许是QTimer?我再说一遍,我对PyQt5还不太了解,所以我不知道QTimer是否可以做同样的事情 .
如果QTimer无法做到,有可能以其他方式吗?我想避免PyQt5的"threads",因为我读到它可以做到,但我想避免仅将它用于Timer模块 .

我只添加了一个问题,以避免打开另一个问题并发布相同的脚本 .
在脚本中,窗口背景通过"oImage = QImage (" bgloading.png ")"等完成 .
但是,我注意到,如果发现文件名错误,或文件本身丢失,则背景为黑色 . 那么,如果有任何错误(错误的名称或丢失文件),可以设置背景,例如白色?
因为当窗口加载"this error"时,不会引发异常并继续脚本 .

编辑:我已经编辑了已发布的脚本,因此它只包含PyQt5部分,因此您可以尝试一下 . 显然只有图像丢失,可以用任何图像替换 .
不幸的是,我忘记写了报告"self.set_display ()"的部分是为了表明一旦PyQt5执行的工作被终止,它将被关闭(它仍然缺失,因为使用Pycharm我会关闭程序中脚本的执行) . 脚本将通过调用"self.set_display ()"函数继续 .

Edit2:我按照建议尝试替换“time.sleep(2)”,但我得到了相同的结果 . 问题是如果我没有暂停,窗口会正常显示,但重置发生得太快,用户看不到进度条的填充 . 如果我把“time.sleep(2)”或建议的解决方案,窗口只在暂停后出现,即复位已经发生时 .

1 回答

  • 2

    对PyQt友好的等效于 time.sleep(2) 的表达式如下:

    loop = QEventLoop()
    QTimer.singleShot(2000, loop.quit)
    loop.exec_()
    

    问题是因为您在暂停后显示窗口小部件,您必须在调用 run() 之前执行此操作,另一个错误是使用 QImage ,对于小部件的问题,您必须使用 QPixmap .

    如果该文件不存在,那么 QPixmap 将为null并且知道是否应该使用 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("...")
    

相关问题