Hab mal mit Qt Designer eine GUI erstellt, was Neuland für mich ist.
Aus der .ui Datei hab ich mit pyuic4 ein Python Skript erzeugt.
Ist es normal, das man dann alle Buttons selbst mit self.connect() "verbinden" muß ? Kann man das nicht automatisch machen lassen?
Als Beispiele hab ich das gefunden und dort wird das per Hand gemacht:
http://www.opendocs.net/pyqt/pyqt4.html ... rated-code
http://openbook.galileocomputing.de/pyt ... 8525b31a3e
Muß ich evtl. im Designer im Bereich "Signale und Slots" was erstellen, damit pyuic4 die Buttons mit einer Methode verbindet?
Qt Slots/Signals immer per Hand erstellen?
Hi Jens,
Hier mal ein code-schnipsel aus "Rapid-Gui Programming with Python and Qt" von Mark Summerfield.
Das funktioniert aber nur wenn Du per Hand ein Dialog oder Mainwindow erstellst.
Aber vielleicht kannst Du was zurecht basteln.
Ach ja, besser Du erwaehnst nicht, dass Du mit pyuic4 arbeitest (wie ich
). Das bringt Dir hier nur Aerger ein.
Wolf
Hier mal ein code-schnipsel aus "Rapid-Gui Programming with Python and Qt" von Mark Summerfield.
Code: Alles auswählen
buttonLayout = QVBoxLayout()
for text, slot in (
("Add &Text", self.addText),
("Add &Box", self.addBox),
("Add Pi&xmap", self.addPixmap),
("&Copy", self.copy),
("C&ut", self.cut),
("&Paste", self.paste),
("&Delete...", self.delete),
("&Rotate", self.rotate),
("Pri&nt...", self.print_),
("&Open...", self.open),
("&Save", self.save),
("&Quit", self.accept)):
button = QPushButton(text)
if not MAC:
button.setFocusPolicy(Qt.NoFocus)
self.connect(button, SIGNAL("clicked()"), slot)
if text == "Pri&nt...":
buttonLayout.addStretch(5)
if text == "&Quit":
buttonLayout.addStretch(1)
buttonLayout.addWidget(button)
buttonLayout.addStretch()
layout = QHBoxLayout()
layout.addWidget(self.view, 1)
layout.addLayout(buttonLayout)
self.setLayout(layout)
Aber vielleicht kannst Du was zurecht basteln.
Ach ja, besser Du erwaehnst nicht, dass Du mit pyuic4 arbeitest (wie ich

Wolf
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Das kann ja nur gehen, wenn der Designer die Zielmethode auch kennt!jens hat geschrieben: Ist es normal, das man dann alle Buttons selbst mit self.connect() "verbinden" muß ? Kann man das nicht automatisch machen lassen?
Im Designer kannst Du z.B. im Signal/Slot Editor bereits auf allg. bekannte Slots verlinken (z.B. exit() o.ä.).
Ansonsten: Lade Deine Widgets doch lieber dynamisch mit dem uic-Modul

encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Na, ich dachte, wenn ich den Button "foo_bar" nenne, dann ruft er einfach "self.foo_bar" auf. Kann man evtl. eine for-Schleife über alle Button's erhalten um das zu machen?Hyperion hat geschrieben:Das kann ja nur gehen, wenn der Designer die Zielmethode auch kennt!
Der Nachteil ist aber, das ich dann nicht vom generierten Code "abschauen" kann.Hyperion hat geschrieben:Ansonsten: Lade Deine Widgets doch lieber dynamisch mit dem uic-ModulDann sparst Du Dir das händische Kompilieren nach Änderungen im UI-Design.
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Hab mir mal sowas gebaut:
Könnte man noch verallgemeinern.
Code: Alles auswählen
def connectPushButtons(self):
for button_name in dir(self):
button = getattr(self, button_name)
if not isinstance(button, QtGui.QPushButton):
continue
method_name = button_name + "_clicked"
method = getattr(self, method_name, None)
if method is None:
print "Error: there exist no method '%s', please implement" % method_name
continue
self.connect(button, QtCore.SIGNAL("clicked()"), method)
Qt kennt eine "Autoslot"-Bezeichnung, vllt. suchst Du das:
'form.ui' ist ein QWidget mit einem PushButton mit dem Namen pushButton. Die Nomenklatur der Autoslots ist on_name_signal, das @QtCore.pyqtSlot() oben ist notwendig, da es das Signal 'clicked' zweimal gibt und man nur hiermit clicked() von clicked(bool) unterscheiden kann (ist nur in PyQt so).
Qt-Dok hierzu: http://doc.trolltech.com/4.6/qmetaobjec ... lotsByName
PyQt-Dok: http://www.riverbankcomputing.co.uk/sta ... ts-by-name
Du kannst auch im Designer neue Slots erstellen und verlinken und brauchst dann nur noch die Methode zu implementieren.
Code: Alles auswählen
from PyQt4 import QtGui, uic, QtCore
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
uic.loadUi('form.ui', self)
@QtCore.pyqtSlot()
def on_pushButton_clicked(self):
print "pushButton clicked"
app = QtGui.QApplication([])
win = MyWidget()
win.show()
app.exec_()
Qt-Dok hierzu: http://doc.trolltech.com/4.6/qmetaobjec ... lotsByName
PyQt-Dok: http://www.riverbankcomputing.co.uk/sta ... ts-by-name
Du kannst auch im Designer neue Slots erstellen und verlinken und brauchst dann nur noch die Methode zu implementieren.
Der @QtCore.pyqtSlot()-Dekorator dient hier eigentlich nur der Unterscheidung der verschiedenen Signalsignaturen (besser: erstellt eine passende Slotsignatur). Für ein Signal, das es nur mit einer Signatur gibt, reicht:
Wenn Du im obigen Bsp. den Dekorator weglässt, wird die Methode zweimal aufgerufen, da die Signale 'clicked()' und 'clicked(bool)' separat abgesetzt werden, und mit @QtCore.pyqtSlot(bool) würdest Du die Methode an 'clicked(bool)' heften.
Siehe hierzu die Riverbankdokumentation, da steht es nochmal etwas ausführlicher.
Code: Alles auswählen
def on_widgetName_signalXY(self, *signalParameter):
...
Siehe hierzu die Riverbankdokumentation, da steht es nochmal etwas ausführlicher.