[Qt4] QtDesigner - CustomWidget?
[Qt4] QtDesigner - CustomWidget?
Hallo,
Ich habe ein Qt-Form-Ui, das meine OpenGl Klasse fernsteuern sollte.
in Qt3 konnte man sich im Designer einfach ein CustomWidget erstellen und dem beliebige Slots und Signals zuweisen.
In Qt4 geht das nicht mehr, sondern man muss wohl ein Plugin für QtDesigner schreiben!!
Soweit ich das verstanden habe, heißt das es ist kleines extra Programm nötig, das man dann auf irgendeine mysteriöse weise in qtdesigner rein kompilieren muss?
http://web.mit.edu/qt-dynamic_v4.0.0/ww ... dgets.html
Geht das wirklich nicht einfacher/sinnvoller? Der QtDesigner braucht doch nur zu wissen welche Slots und Signals mein OpenGl-Widget annimmt!
Versteh jemand von euch die Vorgehensweise, bzw. was zu machen ist, damit ich wieder Signale senden kann?
Ich habe ein Qt-Form-Ui, das meine OpenGl Klasse fernsteuern sollte.
in Qt3 konnte man sich im Designer einfach ein CustomWidget erstellen und dem beliebige Slots und Signals zuweisen.
In Qt4 geht das nicht mehr, sondern man muss wohl ein Plugin für QtDesigner schreiben!!
Soweit ich das verstanden habe, heißt das es ist kleines extra Programm nötig, das man dann auf irgendeine mysteriöse weise in qtdesigner rein kompilieren muss?
http://web.mit.edu/qt-dynamic_v4.0.0/ww ... dgets.html
Geht das wirklich nicht einfacher/sinnvoller? Der QtDesigner braucht doch nur zu wissen welche Slots und Signals mein OpenGl-Widget annimmt!
Versteh jemand von euch die Vorgehensweise, bzw. was zu machen ist, damit ich wieder Signale senden kann?
Hy!
Ja, du musst ein Plugin schreiben.
Nein, der Designer muss nicht nur wissen welche Slots/Signals dein Widget anbietet, sondern auch noch die Eigenschaften kennen, um es zu parametrisieren, und dein Widget auch noch in compilierter Form vorliegen haben, da er dein Widget ja einfach in seinem eigenen Fenster anzeigen lässt, so wie du es später in deinem eigenen Projekt später tun würdest.
Um das Plugin zu schreiben, musst du nur 13 Funktionen implementieren, du größtenteils Strings zurückgeben, um Informationen an den Designer zu übergeben. siehe WorldTimeClockPlugin
mfg
uhu01
Ja, du musst ein Plugin schreiben.
Nein, der Designer muss nicht nur wissen welche Slots/Signals dein Widget anbietet, sondern auch noch die Eigenschaften kennen, um es zu parametrisieren, und dein Widget auch noch in compilierter Form vorliegen haben, da er dein Widget ja einfach in seinem eigenen Fenster anzeigen lässt, so wie du es später in deinem eigenen Projekt später tun würdest.
Um das Plugin zu schreiben, musst du nur 13 Funktionen implementieren, du größtenteils Strings zurückgeben, um Informationen an den Designer zu übergeben. siehe WorldTimeClockPlugin
mfg
uhu01
thanx so far,
Also, das mit den 13 Funktionen in der Pluginklasse ist ja ok. Hab einfach die beiden Beispieldateien von worldtimeclockplugin angepasst.
Allerdings muss ich da ja auch meine Widget-Classe includen. Das geht so natürlich nicht, da an der Klasse mein komplettes Programm hängt. (Es ist sicher nicht Sinn der Sache, dass mehrere tausend Zeilen in eine .dll als Plugin für den Designer kompiliert werden? Der ja eigentlich nichts weiter tun soll als ein schwarzen Platzhalter anzeigen!!!)
Also muss ich eine Abstraction meiner Widget-Classe programmieren die nach aussenhin genauso aussieht, wie mein richtiges Programm, aber nichts macht. Genaugenommen, müsste es eigentlich sogar reichen wenn nur noch die Signals und Slots mit leeren Funktionsrümpfen enthalten sind.
Das müsste dann doch funktionieren, oder?
Steve
Also, das mit den 13 Funktionen in der Pluginklasse ist ja ok. Hab einfach die beiden Beispieldateien von worldtimeclockplugin angepasst.
Allerdings muss ich da ja auch meine Widget-Classe includen. Das geht so natürlich nicht, da an der Klasse mein komplettes Programm hängt. (Es ist sicher nicht Sinn der Sache, dass mehrere tausend Zeilen in eine .dll als Plugin für den Designer kompiliert werden? Der ja eigentlich nichts weiter tun soll als ein schwarzen Platzhalter anzeigen!!!)
Also muss ich eine Abstraction meiner Widget-Classe programmieren die nach aussenhin genauso aussieht, wie mein richtiges Programm, aber nichts macht. Genaugenommen, müsste es eigentlich sogar reichen wenn nur noch die Signals und Slots mit leeren Funktionsrümpfen enthalten sind.
Das müsste dann doch funktionieren, oder?
Steve
Keine Slots?
Nun, mein Widget ist jetzt in QtDesigner. meine Schritte:
- CustomWidget-Classe mit Slots und Signals erstellt
- QT-Plugin-Classe nach dem Standartaufbau
- ".pro" Datei angepasst
- Mit qmake die Makefiles generiert
- nmake -f Makefile.release all
- nach fehlerfreiem Kompilieren ist das CustomPlugin im QtDesigner.
Allerdings fehlen die Slots und Signals!? Außerdem ist mein CustomWidget im Gegensatz zu den Beispiel Widgets im zustand "Promoted". Was auch immer das heißen mag...
Hat jemand einen Tipp?
Ps: für den fall dass es jemand mal probieren will, hängen die 5 files im Anhang
- CustomWidget-Classe mit Slots und Signals erstellt
- QT-Plugin-Classe nach dem Standartaufbau
- ".pro" Datei angepasst
- Mit qmake die Makefiles generiert
- nmake -f Makefile.release all
- nach fehlerfreiem Kompilieren ist das CustomPlugin im QtDesigner.
Allerdings fehlen die Slots und Signals!? Außerdem ist mein CustomWidget im Gegensatz zu den Beispiel Widgets im zustand "Promoted". Was auch immer das heißen mag...
Hat jemand einen Tipp?
Ps: für den fall dass es jemand mal probieren will, hängen die 5 files im Anhang
- Dateianhänge
-
- QtDesigner: CustomWidget Eintrag "GLRenderer" und eigenartiger Eintrag "__qt__promoted_GLRenderer"
- neu-1.gif (3.26 KiB) 6029 mal betrachtet
-
- QtDesignerCustomPlugin.zip
- (3.94 KiB) 159-mal heruntergeladen
Lösung:
damit man solts und signals hat sollte man darauf achten, dass die Funktion PluginClasse::name() und PluginClasse::domXml() ->class die gleichen Namen zurück liefern.
Mit der Eigenschaft "Promoted" lässt sich eine andere Klasse, die nach aussenhin genauso aussieht wie die WidgetClasse, verwenden.
Auch wenn es jetzt funktioniert, erscheint mir der Aufbau mit dem Plugins alles andere als sinnvoll.
Stellt sich auch die frage, was passiert wenn meine Uni allgemein auf QT4 umsteigt? Dann müsste jeder Student seine Customwidgets als Plugin in den Designer einbauen..... da sind Namenskonflikte vorprogrammiert....
damit man solts und signals hat sollte man darauf achten, dass die Funktion PluginClasse::name() und PluginClasse::domXml() ->class die gleichen Namen zurück liefern.
Mit der Eigenschaft "Promoted" lässt sich eine andere Klasse, die nach aussenhin genauso aussieht wie die WidgetClasse, verwenden.
Auch wenn es jetzt funktioniert, erscheint mir der Aufbau mit dem Plugins alles andere als sinnvoll.
Stellt sich auch die frage, was passiert wenn meine Uni allgemein auf QT4 umsteigt? Dann müsste jeder Student seine Customwidgets als Plugin in den Designer einbauen..... da sind Namenskonflikte vorprogrammiert....
So wie ich das sehe, funktioniert das schon, aber dann kannst du deine Widgets nicht im Designer connecten sondern nur noch im Code. (das geht mit dem neuen "Auto-Connect" von qt4 u.u. recht einfach)
Sehr interessant zum Theme CustomWidgets ist folgender Link:
http://www.qtforum.org/article/15468/Ad ... igner.html
Hier wird eine Alternative zu den DesignerPlugins beschrieben. Ausserdem werden die CustomSlots in QtDesigner möglicherweise mit Qt 4.2 wiedereingeführt. Na hoffentlich
Sehr interessant zum Theme CustomWidgets ist folgender Link:
http://www.qtforum.org/article/15468/Ad ... igner.html
Hier wird eine Alternative zu den DesignerPlugins beschrieben. Ausserdem werden die CustomSlots in QtDesigner möglicherweise mit Qt 4.2 wiedereingeführt. Na hoffentlich
Ich habes auch anhand von SteveXP's Beispiel versucht und es ewig nicht hin bekommen. Bei mir war es dann aber ein simpler, aber für mich schwer zu findender Fehler.
In Steve's Beispiel ist der Standartname des Widgets gleich dem Klassennamen. Wenn man das vergisst zu ändern hat man wirklich sonderbare Compilerfehler. Also Ich habe den Code von Steve soweit abgeändert das er jetzt als Standartnamen nicht mehr den Klassennamen trägt. Ansonsten scheint mir diese Plugin-Lösung gerade mit dem Gedanken an die Portabilität des Quelltext eine riesen Unfall zusein. Von einem festen Arbeitsumfeld aus aber noch sinnvoll anwendbar.
In Steve's Beispiel ist der Standartname des Widgets gleich dem Klassennamen. Wenn man das vergisst zu ändern hat man wirklich sonderbare Compilerfehler. Also Ich habe den Code von Steve soweit abgeändert das er jetzt als Standartnamen nicht mehr den Klassennamen trägt. Ansonsten scheint mir diese Plugin-Lösung gerade mit dem Gedanken an die Portabilität des Quelltext eine riesen Unfall zusein. Von einem festen Arbeitsumfeld aus aber noch sinnvoll anwendbar.
uff ... fertig...
Also die einfachste Mehode: WordClock example kopieren, alles was mit worldclock zu tun hat umbenennen, also z.B: MyGx, MyGxPlugin, ebenso die Files, kompilieren und ins plugin dir von designer.
Nun hat man ein "unbrauchbares" MyGx-widget, das bei .ui/ui_mainform.h initialisiert wird. Dann eine eigene beliebige MyLocalGx-class, die von QGLWidget abgeleitetet wird bauen und die anstatt MyGx im code platzieren, z.B. durch: "typedef MyLocalGx MyGx" (im plugin muss allerdings noch der string für den zugehörigen header ("mygx.h") auf die lokale header-Datei geändert werden.
Die Worldclock ist hier nur ein container, der dann einfach komplett ersetzt wird. Vorteil: die Grafik-Methoden müssen nicht im designer plugin existieren, und das plugin-Zeug ist komplett aus dem eigenen Code raus.
Nun hat man ein "unbrauchbares" MyGx-widget, das bei .ui/ui_mainform.h initialisiert wird. Dann eine eigene beliebige MyLocalGx-class, die von QGLWidget abgeleitetet wird bauen und die anstatt MyGx im code platzieren, z.B. durch: "typedef MyLocalGx MyGx" (im plugin muss allerdings noch der string für den zugehörigen header ("mygx.h") auf die lokale header-Datei geändert werden.
Die Worldclock ist hier nur ein container, der dann einfach komplett ersetzt wird. Vorteil: die Grafik-Methoden müssen nicht im designer plugin existieren, und das plugin-Zeug ist komplett aus dem eigenen Code raus.