动态QFrame显示(python PyQt5)

时间:2018-04-10 16:25:58

标签: python pyqt5 qtwidgets qframe

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

这是代码(watch 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 Widgets的颜色(self.grille_carre是QFrame列表的列表),我可以看到这些更改在最终显示上有效,但是 整个程序运行后显示整个显示,我希望看到每个方块都被创建。

1 个答案:

答案 0 :(得分: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_())