QRadiobutton wird nicht ungeclicked.

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
kitebuggy
User
Beiträge: 38
Registriert: Donnerstag 5. August 2021, 21:11

Hallo

Ich habe folgendes Problem:

Ich möchte mittels Pushbutton diverse Radiobuttons ein- und ausschalten können. Ausschalten geht nicht.
Wenn ich den Radiobutton Test 2 drècke, ist er gesetzt. Nun möchte ich ihn nicht mehr setzen und benutze dafür die Funktion

Code: Alles auswählen

self.r2.setChecked(False)
Das funktioniert aber nicht. Der Radiobutton ist noch immer gesetzt.
Wenn ich stattdessen

Code: Alles auswählen

self.r1.setChecked(True)
schreibe, funktioniert es. Dies ist aber eher ein Workaround, da bei mehreren Radiobuttons jedesmal ein Button gesetzt werden müsste. Das ist extrem umständlich. Mit Checkbuttons funktioniert es.

Hier mein Code:

Code: Alles auswählen

#!/usr/bin/python

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QRadioButton,QPushButton
#from PyQt5.QtGui import *
class testbutton(QWidget):
    
    def __init__(self):
        super().__init__()
        self.setGeometry(100,100,200,200)
        self.setWindowTitle("Test Radiobutton")
        self.gui()
        self.show()
        
        
    def gui(self):
        self.r1=QRadioButton("Test 1",self)
        self.r1.move(105,15)
        self.r2=QRadioButton("Test 2",self)
        self.r2.move(105,30)
        p=QPushButton("Test",self)
        p.move(105,90)
        p.clicked.connect(self.pClicked)
        
    def pClicked(self):
        print ("Button clicked")
        self.r2.setChecked(False)
        
if __name__=="__main__":
    app=QApplication(sys.argv)
    window=testbutton()
    sys.exit(app.exec_())
    
Seht ihr eine Lösung resp. was mache ich falsch?

Hat es was mit autoExclusive zu tun?

Danke
kitebuggy
User
Beiträge: 38
Registriert: Donnerstag 5. August 2021, 21:11

Ich glaube, ich habe meine Frage schon selbst beantwortet: Irgendein definierter Zustand der Radiobuttons MUSS ja bestehen, weil sie eben exklusiv zueinander sind. Sind ja keine Checkboxen, die optional sein können.
Benutzeravatar
__blackjack__
User
Beiträge: 13919
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kitebuggy: Anmerkungen zum Quelltext: Klassennamen werden in Python in PascalCase benannt, nicht in Kleinbuchstaben.

Man gibt mit `setGeometry()` und `move()` keine absoluten Grössen und Positionen. Im besten Fall sieht es nicht gut aus, wie bei mir:
Bild
Im schlechten Fall ist die GUI unbenutzbar wenn sich Widgets überlappen oder nicht komplett im Fenster platz finden.

Das Erstellen der Widgetinhalte aus der `__init__()` in eine eigene Methode auszulagern macht keinen Sinn. `gui()` ist auch kein guter Methodenname, denn der Beschreibt keine Tätigkeit. Und das `show()` gehört dort nicht hinein. Kein vorhandenes Widget zeigt sich selbst an. Das ist die Aufgabe des Codes der das Widget erstellt.

`p` ist so gar kein sinnvoller Name für einen Button.

Die Exclusivität ist das ”Problem”. Am einfachsten löst man das in dem man die temporär ausschaltet und das geht am einfachsten über eine `QButtonGroup`:

Code: Alles auswählen

#!/usr/bin/env python3
import sys

from PyQt5.QtWidgets import (
    QApplication,
    QButtonGroup,
    QPushButton,
    QRadioButton,
    QVBoxLayout,
    QWidget,
)


class Window(QWidget):
    def __init__(self):
        super().__init__(windowTitle="Test Radiobutton")
        layout = QVBoxLayout()
        self.button_group = QButtonGroup(self)
        for i in range(1, 3):
            button = QRadioButton(f"Test {i}")
            self.button_group.addButton(button, i)
            layout.addWidget(button)

        layout.addWidget(QPushButton("Test", clicked=self.on_click))
        self.setLayout(layout)

    def on_click(self):
        print("Button clicked")
        self.button_group.setExclusive(False)
        self.button_group.checkedButton().setChecked(False)
        self.button_group.setExclusive(True)


def main():
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
kitebuggy
User
Beiträge: 38
Registriert: Donnerstag 5. August 2021, 21:11

Danke __blackjack__, dein Code sieht effektiv besser aus. Werde mir diesen Stil merken, weil er eleganter aussieht.

Ich hatte den Code schnell 'dahingekotzt', damit ich mein Problem erklären kann. :mrgreen:

Auch wusste ich das mit dem PascalCase-Klassennamen nicht. Oder die Vermeidung von connect
Antworten