PyQt: Widget im Dialog adressieren

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

Hallo,

ich habe ein Dialogfenster (MeinDialog(QtGui.QDialog, Dlg)) und in diesem ein Widget (widgetGrafik) in das ich z.B. ein Rechteck (drawRect) zeichnen möchte per paintEvent.

Wie bringe ich drawRect dazu, dass der Koordinatenursprung im Widget liegt und nicht im Dialog?

Grüße
Frank
lunar

Du musst eben in das Widget zeichnen und nicht in den Dialog. Du hast doch jetzt hoffentlich keine ausführlichere Antwort erwartet?
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

:roll:

Na, das ist mir schon klar.
Mein paintEvent sieht erst einmal so aus:

Code: Alles auswählen

   def paintEvent(self, event):
      painter = QtGui.QPainter(self)
      painter.setPen(self.pen)
      painter.setBrush(self.brush)
      painter.drawRect(10,10,20,20)
Damit wird natürlich in den Dialog gemalt, da self der Dialog ist.
Dann habe ich mein widgetGrafik, das vorher hier gebaut wird:

Code: Alles auswählen

class MeinDialog(QtGui.QDialog, Dlg):
   def __init__(self):
      QtGui.QDialog.__init__(self)
      self.setupUi(self)
und so definiert wird:

Code: Alles auswählen

        self.widgetGrafik = QtGui.QWidget(Hauptdialog)
        self.widgetGrafik.setGeometry(QtCore.QRect(10, 360, 441, 191))
        self.widgetGrafik.setObjectName("widgetGrafik")
Jetzt würde ich sagen, na gut, dann bau ich soetwas:

Code: Alles auswählen

def paintEvent(self.widgetGrafik, event):
Aber das geht scheinbar nicht so, wie ich mir das vorstelle
:wink:
lunar

Du musst dein QWidget mit einem Exemplar einer von QWidget abgeleiteten Klasse ersetzen, und in dieser Klasse dann paintEvent überschreiben. Man kann nicht von "außerhalb" in Widgets zeichnen, zumindest nicht plattformübergreifend.
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

Danke! Das werde ich gleich mal probieren...
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

Das bekomme ich hin, wenn ich das Widget nicht mit dem QtDesigner erzeuge.
Sollte man denn ggf. nur das Layout bauen und dann im Programm das Widget in das Layout fügen? Macht das Sinn? Zumindest habe ich das schon in zwei Beispielen gesehen...

Grüße
Frank
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich wüsste nicht, wo das Problem sein soll. Du schreibst die Klasse halt mit in die Datei, die sich um deine Gui kümmert. Falls du das Widget auch in anderen Projekten benötigst, könntest du ja ein Modul ``customized_widgets`` (oder so ähnlich) erstellen, wo dann die Klassen deiner angepassten Widgets definiert sind.
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

Da schaffe ich inzwischen schon. Mein Problem liegt darin, dass ich mit dem Designer ein leeres Widget erzeuge, in das ich zeichnen möchte und jetzt nicht sagen kann, wie ich das richtig einbinde.

Der Designer erzeugt ja sowas:

Code: Alles auswählen

class Ui_Hauptdialog(object):
    def setupUi(self, Hauptdialog):
Im setupUi wird dann u.a. auch mein leeres Widget definiert.

Wenn ich das ohne den Designer erzeugen würde, hätte ich mein Layout und definiere vorher sowas:

Code: Alles auswählen

class MeinWidget(QtGui.QDialog):
   def __init__(self,parent):
      QtGui.QLabel.__init__(self, parent)
      self.parent = parent

   def paintEvent(self, event):
      print "Widget!"
und lege das Widget in das Layout.
Aber über den das setpUi kann ich nicht sagen, wie ich dran komme um das paintEvent zu erzeugen.
Tja, das sind wohl Anfängerprobleme... :wink:
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Du kannst das z.B. über benutzerdefinierte Klassen im QDesigner erreichen (es muß ja nicht gleich ein Modul für den Designer sein).

So gehts:
- Angepaßte Klasse schreiben z.B. CustomPaintWidget(QWidget) in custompaintwidget.py
- Im Designer alles fertig layouten mit der Basisklasse Deines CustomPaintWidgets.
- Rechtsklick auf Dein Hauptwidget --> Benutzerdefinierte Klassen
- Im Dialog die Basisklasse und den Klassennamen setzen, also QWidget und CustomPaintWidget; unter include-Datei darf für Python nur der Modulname erscheinen, hier custompaintwidget
- Zum Schluß Rechtsklick auf das "Platzhalterwidget" --> Als Platzhalter für ben. Klasse --> CustomPaintWidget

Der uic-Loader kann das richtig auflösen, wobei er manchmal Probleme macht, wenn die CustomKlasse in der selben Datei ist wie die MainKlasse (zirkulärer Import etc.)

Grüße Jerch

Addendum:
Solltest Du ein komplexeres Design in Deiner CustomKlasse brauchen, geht das auch wieder über ui-files. Mit diesem "Schachtelprinzip" (Matroschka) kannst Du Dir quasi Deinen eigenen Widgetbaukasten erstellen.
Was ich noch vergessen habe: Du kannst dieses CustomWidget auch in die linke Seitenleiste zu den anderen Widgets ziehen, es erscheint dann unter "Ablage".
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

Danke! Damit sollte es jetzt hoffentlich weiter gehen. Zumindest hänge ich nicht mehr an meinem alten Problem... :wink:
schnupp
User
Beiträge: 19
Registriert: Samstag 24. Januar 2009, 17:30
Wohnort: Hamburg

Klasse! Das funktioniert - sogar einfacher als erwartet...
Antworten