Pimpl und Signale/Slots

Alles rund um die Programmierung mit Qt
Antworten
muued
Beiträge: 4
Registriert: 28. Januar 2010 22:04

Pimpl und Signale/Slots

Beitrag von muued »

Hallo zusammen,

ich habe kein direktes Problem, vielmehr eine Frage.

Nachdem ich die letzten Tage vergeblich die Qt-Dokumentation dazu befragt habe und gerade ausgiebig die Suchfunktion hier bemüht habe, traue ich mich doch mal, nachzufragen:

Ein normales, mit dem Qt-Creator erstelltes Fenster wird ja aufgespalten in den eigentlichen Code (fenstername.cpp/h) und den Gui-Kram (fenstername.ui bzw generiert ui_fenstername.h).

Dabei wird statt Vererbung schönerweise Pimpl eingesetzt (also die Ui-Klasse als Member des eigentlichen Fensters).

Das wirft natürlich das Problem auf, dass nun die Gui-Klasse nichts mehr über die Code-Klasse weiß (wenn ich die Klassen mal so nennen darf).
Das in den Codebeispielen in allen möglichen Tutorials und meist auch hier im Forum mit als drittem Parameter verwendete

Code: Alles auswählen

connect
hat also Probleme, die Zielfunktion zu finden (das Einbinden der Codeklasse wäre extrem unschön, pimpl würde sein Ziel verfehlen und man hätte wohl zyklische Abhängigkeiten).

Nun scheint das Ganze aber auf magische Weise doch zu klappen, indem einfach Slots/Signale der Qt-Oberklasse (QDialog) genommen werden und in der Codeklasse Slots wie on_SendingObject_SendingObjectsSignal() implementiert werden.

Ich bin zwar begeistert, dass das so wunderschön funktioniert, aber konnte dazu bisher keine Dokumentation finden.
Hat jemand von euch vielleicht eine genauere Erklärung dafür?

Besten Dank im Voraus
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Was ist gegen connect(ui.myPushButton, SIGNAL(clicked()), this, SLOT(onPblicked()) einzuwenden?
Und das die ui-Klasse ein Member ist hat nichts mit pimpl zu tun...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
muued
Beiträge: 4
Registriert: 28. Januar 2010 22:04

Beitrag von muued »

Christian81 hat geschrieben:Was ist gegen connect(ui.myPushButton, SIGNAL(clicked()), this, SLOT(onPblicked()) einzuwenden?
Wenn ich das "Verbinden" (connect) in der Codeklasse durchführe, muss ich dort entsprechende Header einbinden, die was mit GUI zu tun haben - diese hatte ich aber doch vorher so schön in das UI-File (ich habe ein ui_fenstername.cpp angelegt, das ui_fenstername.hpp kommt mit Forward Declarations aus, da die Member nur Pointer sind) verbannt.

Für mich ist es eine Frage des Code-Designs.
Christian81 hat geschrieben:Und das die ui-Klasse ein Member ist hat nichts mit pimpl zu tun...
Oh .. ich hatte Pimpl als "Pointer to Implementation" kennen gelernt. Das würde in dem Zusammenhang vllt mehr Sinn geben.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Das .ui ist nur dazu gedacht, dir das eigenhändige schreiben von reinem GUI-Code abzunehmen - Widgets anlegen, in Layouts packen, Properties ändern, Menü einrichten, Resourcen verwalten, usw.
Das ui ist NICHT dafür gedacht, eine eigene Implementierungsklasse herzugeben, das musst du selber machen! Und wie du es schaffst ui_fenstername.hpp selber zu verwalten frage ich mich auch!

Und Pimpl hat was mit der Implementierung zu tun (wie der Name schon sagt) - es wird alles was private ist in eine eigene Klasse gesteckt. Das reduziert die Kompilierabhängigkeiten für alles was myClass.h includiert.

Und wie du das mit den uis machst steht in der Doku! Einfach mal durchblättern und die Exmples anschauen damit du ein Gefühl für die gedachte Verwendung bekommst und nicht deine eigenen Wege suchen musst.
muued
Beiträge: 4
Registriert: 28. Januar 2010 22:04

Beitrag von muued »

Ok, ignorieren wir mal meine Worte zum Thema Pimpl, das tut ja eigentlich gar nichts zur Sache. Ich werde mich dahingehend nochmal weiter einlesen.

Mein eigentliches Problem ist nicht der Umgang mit .ui-Files - die kann man prima mit dem Creator anlegen und verwalten. Dazu gibt es auch genug Dokumentation.

Ich habe mir vielmehr mal angeschaut, was genau aus einem solchen .ui-file generiert wird.
Das generierte Headerfile implementiert die Funktion setupUI(QDialog *fenstername)
Diese Funktion wird dann zwar mit der von QDialog abgeleiteten Code-Klasse aufgerufen, allerdings bringt das ja der setupUI-methode nichts.
Als Beispiel nehme ich mal eine QDialogButtonBox buttonBox, die einen QDialogButtonBox::Ok - Knopf hat.
Folgende Codezeile scheint das signal on_buttonBox_accepted() an die übergebene Klasse weiterzuleiten:

Code: Alles auswählen

QObject::connect(buttonBox, SIGNAL(accepted()), fenstername, SLOT(accept()));
Dazu würde ich gern etwas in der Dokumentation finden, habe aber bisher vergeblich gesucht.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

muued hat geschrieben:Folgende Codezeile scheint das signal on_buttonBox_accepted() an die übergebene Klasse weiterzuleiten:

Code: Alles auswählen

QObject::connect(buttonBox, SIGNAL(accepted()), fenstername, SLOT(accept()));
Dazu würde ich gern etwas in der Dokumentation finden, habe aber bisher vergeblich gesucht.
http://doc.qt.nokia.com/4.6/qmetaobject ... lotsByName
muued
Beiträge: 4
Registriert: 28. Januar 2010 22:04

Beitrag von muued »

Oh, perfekt
vielen Dank :)
Antworten