QCheckBox Objekte dynamisch erzeugen

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

Hallo,

ich habe eine Gui, die mehrere checkBoxes enthält. Da sich die Liste relativ oft Ändern kann, würde ich das ganze gern dynamisch erzeugen.

Am Ende soll der Anwender den Inhalt in einer Konfigdatei ablegen können.

Folgenden Code habe ich bis Jetzt:

Code: Alles auswählen

checkBoxList = ['Motor','Getriebe', 'Rad']

for item in checkBoxList:
   objectName = 'self.checkBox%s' % item
   exec '%s = None' % (objectName)
   exec '%s = %s' % (objectName,QCheckBox())
   exec 'self.gridLayoutComponentType.addWidget(%s,%d,0,1,1)' % (objectName,checkBoxList.count(item))

allerdings bekomme ich beim Erstellen dann folgenden Fehler:
exec '%s = %s' % (objectName,str(QCheckBox()))
File "<string>", line 1
self.checkBoxVerbrennungsmotor = <PyQt4.QtGui.QCheckBox object at 0x04268DB0>
^
SyntaxError: invalid syntax
hat jemand eine Idee?
Gruß,
Steffen
lunar

Das ist nicht Dein Ernst, oder?! Schon mal was von „Wörterbüchern“ gehört?!
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Code: Alles auswählen

exec '%s = QCheckBox()' % objectName
Warum bin ich mir nur jetzt schon sicher, dass ich das nicht hätte schreiben sollen?

Edit: % objectName
Zuletzt geändert von EyDu am Montag 29. November 2010, 17:00, insgesamt 1-mal geändert.
Das Leben ist wie ein Tennisball.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

EyDu hat geschrieben:

Code: Alles auswählen

exec '%s = QCheckBox()'
Warum bin ich mir nur jetzt schon sicher, dass ich das nicht hätte schreiben sollen?
Was auch immer du damit zu sagen versuchst, es kommt auf das gleiche heraus

lunar hat geschrieben:Das ist nicht Dein Ernst, oder?! Schon mal was von „Wörterbüchern“ gehört?!
Warum?


Mal im Ernst Leute. Ich habe ein Problem und bekomme nur dämliche Antworten. Das ich in meinem Code einen Fehler habe, weiß ich selbst. Nur finde ich ihn eben nicht. Und da wär es sehr Hilfreich, konstruktive Antworten zu erhalten und nicht die üblichen 'RTFM' Floskeln.

Ist mir gerade aufgefallen ... um das ganze vielleicht zu verdeutlichen. Der Fehler ist nicht bei 'self', sondern bei '<PyQ...'

Code: Alles auswählen

    exec '%s = %s' % (objectName,QCheckBox())
  File "<string>", line 1
    checkBoxVerbrennungsmotor = <PyQt4.QtGui.QCheckBox object at 0x04274DF8>
                                ^
SyntaxError: invalid syntax
Gruß,
Steffen
BlackJack

@knumskull: Was man Dir damit zu sagen versuchte, war dass Du die Finger von ``exec`` lassen sollst, und stattdessen Listen oder Dictionaries anstelle von dynamisch generierten Variablennamen verwenden solltest.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Die Fehlermeldung ist doch selbst erklärend.

Dein Programm, welches du dort versuchst auszuführen, kennt an dieser Stelle "self" nicht,
weil es nirgendwo definiert ist.
"self" wird normalerweise nur in Klassenobjekten genutzt.

Aber ganz nebenbei, was wird das eigentlich ?
"exec" ist an der Stelle völliger Blödsinn.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
lunar

@knumskull: Verzeih mir, doch wenn Du Python ernsthaft nicht so weit beherrscht, dass Du die elementaren Datenstrukturen beherrschst und erkennst, wie diese in diesem Fall anzuwenden sind, dann kann man Dir nicht sinnvoll helfen. Lies das Tutorial, und wende Dich der Anwendung erst wieder zu, wenn Du Listen und Wörterbücher verstanden hast.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

okay okay ... ich lasse mich natürlich gern belehren. :)

Ich habe exec nur verwendet, weil es das einzige war, was ich im Netz auf die Frage nach Objekten mit Dynamischen Namen gefunden habe und was in kleinen Tests auch soweit funktioniert hat.

Es gefällt mir natürlich nicht, so wie es aufgebaut ist, würde das auch gern anders machen, wenn ich wüsste wie.

@Lunar: Jetzt habe ich auch verstanden was du mit Wörterbüchern meinst. Diese deutschen Übersetzungen von Datenstrukturen sind für mich Sinnfrei. Hättest du Dictionary gesagt, hätte ich gleich gewusst was du meinst.

@Xynon1: Der Aufruf von exec ist in einer Klasse. Allerdings kann es wohl durchaus sein, dass die Umgebung von Exec ganz wo anders abläuft. Aber da ich besser die Finger von exec lassen soll, werde ich diesen Weg auch nicht weiter verfolgen

@all: Wie kann ich jetzt Klassen-Objekte mit variablen Namen erzeugen? Kann mir keine ein kleines Beispiel geben?

Code: Alles auswählen

checkBoxList = ['Motor','Getriebe', 'Rad']

for key in checkBoxList.keys():
  checkBoxDict[key] = QCheckBox()

Wie schaffe ich es an der Stelle das ganze als Klassenvariable zu deklarieren?

Gruß,
Steffen
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Eventuell die Build-In Funktion "setattr"
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

Xynon1 hat geschrieben:Eventuell die Build-In Funktion "setattr"
:oops: Die habe ich mir schon eine ganze weile angeschaut ... aber irgendwie bin ich immer über die 3 Attribute gestolpert ... ich wusste nicht wirklich, was ich angeben sollte.

Code: Alles auswählen

setattr(self, objectName, QCheckBox(self.groupBox))
das tut es fürs erste. Also die Objekte habe ich schon mal.
Jetzt brauche ich dann aber doch noch einmal einen Tipp:

wie ersetze ich folgendes

Code: Alles auswählen

exec 'self.gridLayoutComponentType.addWidget(%s,%d,0,1,1)' % (objectName,checkBoxList.count(item))

Gruß,
Steffen
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Das ist doch eine Funktion, wieso rufst du diese nicht einfach auf.
bzw. wenn sie zu einem Späteren Zeitpunkt aufgerufen werden soll, dann mach doch einfach eine "lambda" Funktion daraus.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
lunar

@knumskull: Wieso müssen die Steuerelemente unbedingt Attribute des Exemplars sein? Es reicht doch, sie in einem Wörterbuch [1] abzulegen.

[1] Wenn diese Übersetzungen für Dich ohne Sinn sind, dann lerne die deutschen Entsprechungen zu englischen Fachbegriffen. „Wörterbuch“ ist eine in der Literatur absolut übliche Übersetzung für „dictionary“.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

Ich musste da aber das Objekt mit angeben. Aber zu setattr gibt es ja auch getattr, was mir das Objekt zurückliefert.

Habe es jetzt folgendermaßen gelöst

Code: Alles auswählen

        for item in checkBoxList:
            
            #creating objects
            objectName = 'checkBox%s' % item
            
            setattr(self, objectName, QCheckBox(self.groupBox))
            checkBoxObject = getattr(self, objectName) 
            self.gridLayoutComponentType.addWidget(checkBoxObject,checkBoxList.index(item),0,1,1)
            checkBoxObject.setText(QApplication.translate("TFMReleaseMainUI", item, None, QApplication.UnicodeUTF8))
            
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

lunar hat geschrieben: [1] Wenn diese Übersetzungen für Dich ohne Sinn sind, dann lerne die deutschen Entsprechungen zu englischen Fachbegriffen. „Wörterbuch“ ist eine in der Literatur absolut übliche Übersetzung für „dictionary“.
Ja, das mag sein, allerdings in Anbetracht des Fehlers[1], der mir angezeigt wurde, kann man von dem einen nicht auf das andere schließen. Und im übrigen ist dein Stil, Leute auf Fehler oder andere hinzuweisen, nicht sehr angebracht.

[1]

Code: Alles auswählen

exec '%s = %s' % (objectName,str(QCheckBox()))
File "<string>", line 1
self.checkBoxVerbrennungsmotor = <PyQt4.QtGui.QCheckBox object at 0x04268DB0>
^
SyntaxError: invalid syntax
BlackJack

@knumskull: Was ist denn der Sinn von dynamisch generierten Attributen wenn man nie Quelltext schreibt, der darauf direkt zugreift, weil man die Attribute in diesem Fall ja gar nicht kennt wenn man den Quelltext schreibt!? Warum verwendest Du kein Dictionary dafür? Das ist weniger umständlich und weniger fehleranfällig.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

Was meinst du mit dynamischen Attributen?

Was ich hier erzeugt habe, sind ja alles Objekte vom Typ QCheckBox mit einem Namen aus einer Liste. Ich habe ja keine weiteren Attribute.
lunar

@knumskull: "setattr" erzeugt dynamisch Attribute am Exemplar, welches als erstes übergeben wird. Warum sonst heißt die Funktion wohl "setattr(ibute)"?
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

okay ... ergibt Sinn :) ... Danke

Könnt Ihr mir mal ein Beispiel für eine Erzeugung von Objekten mit dictionary geben? Ich kann mir das recht schwer vorstellen.

Danke im Voraus
Gruß, Steffen
BlackJack

@knumskull: Du erstellst ein Dictionary und steckst da die erzeugten Objekte unter den entsprechenden Namen hinein. Statt die erzeugten Objekte unter den Namen mit `setattr()` an das Objekt zu binden.

Code: Alles auswählen

self.name2checkbox = dict()
for name in namen:
    self.name2checkbox[name] = CheckBox()
Listen und Dictionaries sind *die* beiden Grunddatentypen in Python um Objekte in einem Container zusammen zu fassen. Du solltest echt mal ein Grundlagentutorial durcharbeiten.
knumskull
User
Beiträge: 34
Registriert: Dienstag 29. September 2009, 08:07
Kontaktdaten:

BlackJack hat geschrieben: Listen und Dictionaries sind *die* beiden Grunddatentypen in Python um Objekte in einem Container zusammen zu fassen. Du solltest echt mal ein Grundlagentutorial durcharbeiten.
Hast du da eins parat? Es gibt ja zig Tutorials oder Bücher, wo allermöglicher Kram drin steht, aber da sind auch immer unterschiedliche Ansätze, bzw. einfach die Grundlagen nacheinander aufgezählt. Wirkliche Konzepte habe ich noch nirgends gesehen. Oder ich bin einfach nie in die entsprechenden Kapitel vorgedrungen.

Bis jetzt habe ich mir die Informationen aus Python-Documents oder halt auf Grund des anstehenden Problems zusammengesucht.
Antworten