Objekt ansprechen

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

Hallo

Ich habe folgendes Problem:

Ich erstelle eine Buttongroup und möchte einzelne Buttons ausserhalb der Funktion ansprechen.
Hier mein Quelltext, damit man weiss, was ich bezwecke (Die for-Schleife bekommt ihre Werte hier aus einer range(0,9), aber im reellen Programm aus einem dict. Das sollte aber das ganze nicht stören).

Code: Alles auswählen

#!/usr/bin/python
import sys
from PyQt5.QtWidgets import (QApplication,QWidget,QVBoxLayout,QPushButton,QButtonGroup)

class panel(QWidget):
    
    def __init__(self):
        super().__init__()
        self.buildPanel()
        #self.buttonchecked()
        self.show()    
        
    def buildPanel(self):
        '''
        builds the panel
        '''
        vlayout=QVBoxLayout()
        self.setWindowTitle('ButtonGroup test')
        buttonGroup=QButtonGroup(self)
        buttonGroup.setExclusive(False)
        for pin in range(0,9):
            button=QPushButton(self)
            button.setCheckable(True)
            button.setText(str(pin))
            button.setObjectName(str(pin))
            #f'self.button{pin}'=button #irgendsoetwas
            buttonGroup.addButton(button)
            vlayout.addWidget(button)
        buttonGroup.buttonClicked.connect(self.buttonClick)      
        self.setLayout(vlayout)
        
    def buttonClick(self,button):
        pin=button.text()
        print(f'Button: {pin}')
        
    def buttonchecked(self):
        checked=[2,3,5]
        for button in checked:
            f"button{button}".setText('pressed')
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    d=panel()
    sys.exit(app.exec())
Natürlich ist die ganze funktion buttonchecked Quatsch, da sie eine Syntaxerror erzeugt, aber der Text der Buttons der Liste soll ändern.

Danke für eure Hilfe
Benutzeravatar
__blackjack__
User
Beiträge: 14254
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kitebuggy: Wenn man Texte auf andere Werte abbilden will, dann gibt es Wörterbücher (`dict`). Wenn die Werte fortlaufend nummerierte ”Namen” sind, dann will man kein Wörterbuch, sondern eine Liste.
“All tribal myths are true, for a given value of 'true'.” — Terry Pratchett, The Last Continent
Benutzeravatar
__blackjack__
User
Beiträge: 14254
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Noch ein paar Anmerkungen zum Quelltext:

Von den Python-Namenskonventionen abzuweichen wenn eine Bibliothek eine andere Namenskonvention verwendet ist okay, aber dann von beiden abzuweichen wie bei `panel` ist nicht gut. Sowohl in Python als auch bei der Qt-Bibliothek werden Klassennamen in PascalCase geschrieben. Ein Vorteil davon sieht man bei `d` das eigentlich `panel` heissen sollte, was es aber nicht kann, weil die Klasse ungünstigerweise bereits so heisst.

Konsistenz ist bei Namen auch wichtig. Wenn man `buttonClick()` und `buttonchecked()` gesehen hat, muss man raten wie andere Slots wohl benannt sein werden, sowohl was die Gross-/Kleinschreibung als auch die Schreibweise des Ereignisses angeht. Wenn man auf ein Signal wartet das die Selbstzerstörung aktiviert ist, hiesse das dann `destructionactivate()`, `destructionactivated()`, `destructionActivate()`, oder `destructionActivated()`?

Das Hauptprogramm sollte in einer Funktion stehen. Hier werden sonst immer noch zwei modulglobale Variablen definiert.

Der `show()`-Aufruf gehört nicht in die `__init__()`. Das nimmt einem die Option solche Objekte zu erzeugen ohne das sie gleich angezeigt werden, zum Beispiel weil man das Widget gar nicht direkt als Fenster anzeigen, sondern in einem anderen Layout unterbringen möchte. Dann macht das auch mehr Sinn das Objekt nach dem erstellen an einen Namen zu binden, weil der dann auch tatsächlich benutzt wird.

Eine fast leere `__init__()` die hauptsächlich eine andere Methode aufruft in der das Objekt initialisiert wird, macht per se erst einmal keinen Sinn.

Code: Alles auswählen

#!/usr/bin/env python3
import sys

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


class Panel(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent, windowTitle="ButtonGroup test")
        layout = QVBoxLayout(self)
        buttonGroup = QButtonGroup(
            self,
            exclusive=False,
            buttonClicked=lambda button: print(f"Button: {button.text()}"),
        )
        self.pin_number_to_button = {}
        for pin_number in range(0, 9):
            button = QPushButton(str(pin_number), self, checkable=True)
            self.pin_number_to_button[pin_number] = button
            buttonGroup.addButton(button)
            layout.addWidget(button)

        for pin_number in [2, 3, 5]:
            self.pin_number_to_button[pin_number].setText("pressed")


def main():
    app = QApplication(sys.argv)
    panel = Panel()
    panel.show()
    sys.exit(app.exec())


if __name__ == "__main__":
    main()
“All tribal myths are true, for a given value of 'true'.” — Terry Pratchett, The Last Continent
Antworten