1

我正在尝试让 PyQt5.QtWidgets.QFrame 动态更新他的颜色。

这是代码(手表 run() 方法)

import sys 
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QFont
from time import sleep,time
from random import randint

class cadrillage(QWidget):  
    def __init__(self,grille_init,Largeur_grille, pause=0):
        """grille init vaudra 1 ou 0 : 0 pour une grille initialement toute blanche, 1 pour une grille randomisée"""

        super().__init__()
        self.Largeur_grille = Largeur_grille


    self.n_etape = 0
        self.cadri_init(grille_init)
        self.run(pause)


    def cadri_init(self,grille_init):
        """ définit la fenetre d'affichage et la grille initiale """
        t1 = time()
        self.setGeometry(890,150,1000,800)
        self.setWindowTitle("Grille à la {}_ème étape".format(self.n_etape))

        self.show()

        self.grid = QGridLayout()
        self.grid.setSpacing(0)    # pas d'espace entre les carrés
        self.setLayout(self.grid)

        if grille_init == 0:
            #définir grille_couleurs
            grille_couleurs=[0 for i in range(self.Largeur_grille) for j in range(self.Largeur_grille)]
            # 0 pour le blanc, 1 pour le noir

        if grille_init == 1:
            #définir grille_couleurs
            grille_couleurs=[randint(0,1) for i in range(self.Largeur_grille) for j in range(self.Largeur_grille)]


        self.positions = [(i,j) for i in range(self.Largeur_grille) for j in range(self.Largeur_grille)]

        self.grille_carre=[[None for i in range(self.Largeur_grille)] for j in range(self.Largeur_grille)]    

        for position,couleur in zip(self.positions,grille_couleurs):

            carre = QFrame(self)

            if couleur == 0:
                carre.setStyleSheet("QWidget { background-color: #ffffff}")
            if couleur == 1:
                carre.setStyleSheet("QWidget { background-color: #000000}")
            carre.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
            self.grid.addWidget(carre, *position)

            i,j = position
            self.grille_carre[i][j] = carre

        print(time()-t1)
        sleep(0.2)

    def run(self,pause):

        for k in range(3):

            a,b = randint(0,self.Largeur_grille-1),randint(0,self.Largeur_grille-1)
            self.grille_carre[a][b].setStyleSheet("QFrame{ background-color: #000000}")
        sleep(pause)

if __name__ =='__main__':
    app = QApplication(sys.argv)
    grille = cadrillage(0,10,0.5)
    sys.exit(app.exec_())

在 run() 方法中,我更改了一些 QFrame 小部件的颜色(self.grille_carre 是 QFrame 列表的列表),我可以看到这个更改在最终显示上起作用,但是整个显示在整个程序运行后出现并且我想看到创建每个方块。

4

1 回答 1

0

由于 PyQt 在事件循环中执行,因此不应在主线程中使用阻塞任务,这允许您查看其他事件,例如键盘、鼠标等,如果在更改中您使用阻塞任务(如您进行的睡眠) GUI 没有响应。您要做的是为此您必须使用 QTimer 的定期任务(时间设置以毫秒为单位)。

import sys 
from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QFrame, QSizePolicy
from PyQt5.QtGui import QFont
from PyQt5.QtCore import QTimer, QEventLoop
from time import sleep,time
from random import randint

class cadrillage(QWidget):  
    def __init__(self,grille_init,Largeur_grille, pause=0):
        """grille init vaudra 1 ou 0 : 0 pour une grille initialement toute blanche, 1 pour une grille randomisée"""

        super().__init__()
        self.Largeur_grille = Largeur_grille

        self.n_etape = 0
        self.cadri_init(grille_init)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.run)
        self.counter = 0
        self.timer.start(pause)

    def cadri_init(self,grille_init):
        """ définit la fenetre d'affichage et la grille initiale """
        self.setGeometry(890,150,1000,800)
        self.setWindowTitle("Grille à la {}_ème étape".format(self.n_etape))

        self.show()

        self.grid = QGridLayout()
        self.grid.setSpacing(0)    # pas d'espace entre les carrés
        self.setLayout(self.grid)

        grille_couleurs=[0 if grille_init == 0 else randint(0,1) for i in range(self.Largeur_grille) for j in range(self.Largeur_grille)]

        self.positions = [(i,j) for i in range(self.Largeur_grille) for j in range(self.Largeur_grille)]

        self.grille_carre=[[None for i in range(self.Largeur_grille)] for j in range(self.Largeur_grille)]    

        for position,couleur in zip(self.positions,grille_couleurs):
            carre = QFrame(self)
            carre.setStyleSheet("QWidget {{ background-color: {}}}".format("#ffffff" if couleur == 0 else "#000000"))
            carre.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
            self.grid.addWidget(carre, *position)
            i,j = position
            self.grille_carre[i][j] = carre

    def run(self):
        self.counter += 1
        a,b = randint(0,self.Largeur_grille-1),randint(0,self.Largeur_grille-1)
        self.grille_carre[a][b].setStyleSheet("QFrame{ background-color: #000000}")
        if self.counter > 3:
            self.timer.stop()

if __name__ =='__main__':
    app = QApplication(sys.argv)
    grille = cadrillage(0,10,500)
    sys.exit(app.exec_())
于 2018-04-10T16:38:06.953 回答