GUI crashed bei Änderung von Button-Styles

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
hoinabauer
User
Beiträge: 2
Registriert: Freitag 2. Februar 2018, 09:59

Guten Morgen liebe Formumgemeinde.

Ich konnte diesem Forum schon sehr viel nützliche Tipps entnehmen. Vielen Dank dafür. Bei einem Problem komme ich aber neuerdings nicht weiter und habe mich daher kurzerhand registriert. Dies ist also meine erster Beitrag und ich hoffe ihr könnt mir helfen.

In einem Lager gibt es verschiedene Stapel mit Produkten.
Für jeden Stapel 1-43 habe ich mit QT-Designer einer Pushbutton erstellt.
Es sind also 43 Pushbuttons die als Text die Anzahl der Produkte auf diesem Lagerplatz anzeigen und je nach Produktsorte soll sich die Farbe des Buttons ändern.

Die Lagerdaten werden aus einer SPS gelesen (mit snap7)
Das Bytearray geht dann aus meinem Main-Thread per Signal zum GUI und wird dort in integers zerlegt (Funktion get_int).

Dann folgt die Schleife über alle pushbuttons die je nach ermittelten Werten eine bestimmte Bezeichnung, Farbe und ggf. Umrandung annehmen.

Das ganze funktioniert immer ein paar Durchläufe und plötzlich crasht das GUI (pythonw.exe funktioniert nicht mehr=
Wenn ich die Änderung des Button-Styles ausblende, läuft es einwandfrei, Stundenlang ohne Crash. Mir scheint es so, als könne QT diese Masse an Buttonstyle-Änderungen nicht verkraften. Wann der Crash kommt, scheint vollkommen zufällig zu sein.

woran kann es nur liegen?

Code: Alles auswählen


        u=43
        #Anzahl belegte in Buttontext
        for ii in range(u): #ii geht bei Null los und läuft bis 42
            start_plb=86
            byte_plb=(start_plb+(2*ii))
            k=ii+1
           
            global plb
            plb =[None]*44
            plb[k] = get_int(msg,byte_plb)
            buttonadresse='Stapel_'+str(k)
            getattr(self,buttonadresse).setText(_translate("MainWindow", str(plb[k]), None))

       for ii in range(u): #ii startet bei 0 und läuft bis 42
            start_sorte=258
            byte_plsorte=(start_sorte+(2*ii))
            k=ii+1
            global plsorte
            plsorte =[None]*44
            plsorte[k] = get_int(msg,byte_plsorte)
            
            buttonadresse='Stapel_'+str(k)
            
            
            if plsorte[k]==1:
                colorbuttonbg="background-color:rgb(0, 255, 0)"
            elif plsorte[k]==2:
                colorbuttonbg="background-color: rgb(0, 170, 0)"
            elif plsorte[k]==3:
                colorbuttonbg="background-color:rgb(170, 255, 127)"
            elif plsorte[k]==7:
                colorbuttonbg="background-color: rgb(255, 255, 0)"
            elif plsorte[k]==8:
                colorbuttonbg="background-color:rgb(255, 170, 0)"
            elif plsorte[k]==0:
                colorbuttonbg="background-color:rgb(255, 255, 255)"
            else :
                colorbuttonbg=""
                
            start_aktiv=172
            byte_plaktiv=(start_aktiv+(2*ii))
            global plaktiv
            plaktiv =[None]*44
            plaktiv[k] = get_int(msg,byte_plaktiv)

            if plaktiv[k]==0:
                colorbuttonbg=colorbuttonbg+";border-color: rgb(255, 0, 0);border-style: outset;border-radius: 6px;border-width: 4px;"                                   
            else:
                colorbuttonbg=colorbuttonbg

# WENN ICH DIE FOLGENDE ZEILE AUSBLENDE FUNKTIONERT ES OHNE CRASH

            getattr(self,buttonadresse).setStyleSheet(_fromUtf8(colorbuttonbg))
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was Qt (und kein anderes GUI toolkit) abkann, ist seine Innereien aus mehreren Threads zu manipulieren. Das darfst du nicht. Wenn du diese Aenderung in einem Hintergrund-Thread berechnest, musst du sie irgendwie in den Main-Thread hieven, um sie dort zu Aenderung an der GUI werden zu lassen.

Qt macht es einem da recht einfach: wenn du QThreads benutzt, und sogenannte "queued connections", kannst du eine signal/slot-Connection benutzen. Dein Hintergrund-Thread feuert also einfach ein signal, und der Main-Thread bekommt das eingetuetet und reagiert darauf.
hoinabauer
User
Beiträge: 2
Registriert: Freitag 2. Februar 2018, 09:59

Ja obwohl ich noch recht neu in GUI-Programmierung bin, habe ich das schon berücksichtigt. Sollte meiner Meinung nach so passen:
Ich hatte nur den Hintergrund-Thread (wo meine Logik) abläuft fälschlicherweise als MAIN-Thread betitelt.

Gleich am anfang der Endlosschleife werden die Daten gelesen und per Signal gesendet.

Code: Alles auswählen

 while 1:
              

        global db8_array
        db8_array = leseDB(8,0,703)
        msgForGui = db8_array
        mySrc.myGUI_signal.emit(msgForGui)
        time.sleep(2)
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Trick sind die queued connections. Und du musst QThreads benutzen. Da du nicht zeigst was du machst, gehe ich immer noch davon aus, das das die Ursache ist.
Antworten