Arbeiten mit Checkboxen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute,

ich möchte euch zwei Möglichkeiten aufzeigen, einmal meine einfache Variante, und eine Variante, die ich im Netz gefunden habe, und ich möchte zusammen mit euch versuchen zu verstehen, wie die Variante aus dem Netz zu verstehen ist, und gerne möchte ich wissen, welche Variante "besser" ist.

Meine Variante:

Code: Alles auswählen

        self._checkbox.stateChanged.connect(self._checkbox_cb)

    def _checkbox_cb(self):
        if self._checkbox.isChecked():
            print "Checked"
        else:
            print "Unchecked"
Ich möchte schon beim Klicken auf die Checkbox überprüfen, ob die Checkbox aktiviert oder deaktiviert wurde. Deswegen verwende ich in Zeile 1 die stateChanged()-Methode. Jedesmal, wenn das Kontrollkästchen seinen Zustand verändert, als aktiviert oder deaktiviert wird, soll ein Signal ausgesendet werden. Dieses Signal verbinde ich dann mit der _checkbox_cb()-Funktion. Und in der Funktion frage ich dann mit der isChecked()-Methode ab, ob das Kontrollkästchen aktiviert ist oder eben nicht.


Variante aus dem Netz:

Code: Alles auswählen

        self._checkbox.stateChanged.connect(self._checkbox_cb)

    def _checkbox_cb(self, state):
        assert QtCore.Qt.Unchecked == 0
        assert QtCore.Qt.Checked == 2
        assert state in (QtCore.Qt.Checked, QtCore.Qt.Unchecked, QtCore.Qt.PartiallyChecked)
        print "state:", state

Dieses Beispiel fand ich beim Stöbern, und möchte es mit eurer Hilfe zu gern verstehen. Soweit ich mich informiert habe, ist die assert-Anweisung ähnlich wie eine If-Abfrage, also so:

Code: Alles auswählen

 if not _checkbox: raise AssertionError() 
Nun, wie habe ich die Netz-Variante verstanden?
Zeile 3: Als Argument wird der Funktion ein state übergeben. State hat hier die Aufgabe zu überwachen(?)
Zeile 4 und 5: Die assert-Anweisung besagt, sobald beim Test die Bedingung falsch ist bzw. nicht erfüllt ist, soll ein Fehler ausgeworfen werden
Zeile 6: Hier komme ich ins Stocken.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Eine Checkbox kann in Qt drei Zustände haben:
Unchecked: Checkbox ist leer
Checked: Checkbox ist angekreuzt (oder mit Häkchen)
PartiallyChecked: Checkbox ist angekreuzt (oder mit Häkchen) aber angegraut
Der Zustand PartiallyChecked ist z.B. für eine Baumansicht, wenn bei einem Ast einige Unteräste Checked und einige Unchecked sind.

Dieser Zustand einer Checkbox wird nicht mit einem Objekt oder einem Symbol verwaltet, sondern mit einem enum. Qt ist nämlich eigentlich C++, nun hat Python aber keine enums, deshalb wird aus dem enum ein int gemacht. In C++ sind enums im Prinzip auch ints. Die int Werte der enums sind Unchecked=0, Checked=2 und PartiallyChecked=1 (wahrscheinlich). Diese int-Werte sind in Qt im C++ Code fest reinkompiliert, sie können sich also nicht ändern. Wozu also die Abfrage? Vielleicht ändern sie sich ja mal in Qt6, wer weiß? Die Zeilen 4 und 5 prüfen also nur, ob der C++ Code von Qt sich auch wirklich nicht geändert hat.

Zeile 6 macht schon mehr Sinn. Obwohl eine Checkbox nur einen der drei Zustände Checked, Unchecked oder PartiallyChecked hat, könnte es ja trotzdem sein, dass die Methode _checkbox_cb von woanders mit einer anderen Zahl als 0, 1 oder 2 aufgerufen wird.

Solcher Code kann nützlich sein, wenn man checken will, ob man Qt richtig verstanden hat. In einem produktiven Programm, sollte man darüber aber hinaus sein, assert Fehler zu werfen die sagen:
"Hallo hier wurde die GUI-Bibliothek nicht verstanden!"
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@MagBen: Wenn ich dich richtig verstanden habe, dann ist meine einfache und bescheidende Variante "eher" anzuwenden?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Sophus hat geschrieben:Wenn ich dich richtig verstanden habe, dann ist meine einfache und bescheidende Variante "eher" anzuwenden?
Ja
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@MagBen: Beim Lernen bin ich auf die Begriffe wie assert und state gestoßen. Die assert-Anweisung gleichen einer If-Abfrage, richtig? Und State ist eine Überwachungs-Methode? Ab wann ergibt es Sinn, mit assert zu arbeiten? Mal abgesehen von dem gezeigten Beispiel.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

state ist in diesem Zusammenhang einfach der Zustand der Checkbox, also (0, 1, 2) oder (QtCore.Qt.Checked, QtCore.Qt.Unchecked, QtCore.Qt.PartiallyChecked)

assert ist wie eine if Abfrage mit leerem if-Zweig bei dem im else-Zweig ein AssertionError geworfen wird. assert macht in den folgenden Fällen Sinn:
  • in einem Unit-Test
  • in einem noch nicht ganz ausgereiften Programm (also eigentlich jedes), um einen Programmierfehler abzufangen, der ein weiteres ausführen des Programms sinnlos macht.
a fool with a tool is still a fool, www.magben.de, YouTube
Antworten