动态QFrame显示

Dynamic QFrame display

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

这是代码(观看 运行() 方法)

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_())

在 运行() 方法中,我更改了一些 QFrame 小部件的颜色(self.grille_carre 是 QFrame 列表的列表),我可以看到此更改在最终显示上有效,但 整个显示出现在整个程序 运行s 之后,我希望看到每个方块都被创建。

阻塞任务不应在主线程中使用,因为 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_())