Ich bastle gerade an dem Editor für mein RPG. Damit der ganze Code schön sauber und Strukturiert ist, soll er aus einzelnen Tools bestehen, z.B. "Entity hinzufügen", "Entity Eigenschaften bearbeiten" oder "Bodentextur bemalen". Jedes Tool hat dementsprechend ein Fenster, wo alle benötigten Widgets drin sind, die Tool Fenster sollen jeweils DockWidgets sein, damit man sich das Layout schön selber bearbeiten kann.
Das ganze im Qt Designer zusammenklicken war kein Problem, aber jetzt möchte ich jedes Tool Fenster in einer eigenen .ui Datei definieren, und das will einfach nicht klappen. Ich habe mehrere Wege ausprobiert, und alle haben auf ihre Art nicht funktioniert. Mal wurde das Layout nicht der Fenstergröße angepasst, mal wurden die Events nicht automatisch verbunden und mal hat man einfach gar nix gesehen.
Mein Prinzipieller Versuch war es, in jeder Tool ui Datei ein Widget zu haben, dass dann im Editor beim laden einem entsprechenden DockWidget hinzugefügt wird. Jetzt weiß ich aber nichtmal so genau, wie die Toolklasse aussehen sollte, sollte man lieber ein ui Attribut von der generierten ui-Klasse haben (sowas ähnliches hat man ja, wenn man einfach mit dem Wizard sich ein normales Hauptfenster erstellt), oder direkt von dieser Klasse erben? Da in der Tool Klasse ja die Eventhandler definiert sein sollen, schien mir letzteres irgendwie sinnvoller, aber geklappt hat das auch nicht.
Naja, vielleicht hat jemand sowas ähnliches ja schonmal gemacht und kann mir sagen, wie ich das grob strukturieren sollte.
[Qt] Fenster aus .ui Datei erstellen
[Qt] Fenster aus .ui Datei erstellen
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: [Qt] Fenster aus .ui Datei erstellen
Also ich mach das ganze unter QtCreator (wobei ich sonst mit VS2008 arbeite). Dort hatte ich bisher keine Probleme, auch nicht mit eigenen Widgets. Beim Autoconnect mußt du dich halt an die Namenskonvention von Qt halten sonst klappt das nicht, soweit ich weiß war das was wie on_<widget>_<event>(<params>).
Das mit dem Layout tut auch nur wenn du Layoutelemente deinem Widget hinzufügst. Wie das dann für dein DockWidget aussieht, das sozusagen dein CustomWidget im DockWidget angepaßt wird, weiß ich nicht genau, wobei ich das wohl bei mir im generierten Code nachschauen könnte. Mir ist noch nicht so ganz klar, warum die Widgets im Code laden mußt und nicht per Designer schon designen kannst?
Thoran
Das mit dem Layout tut auch nur wenn du Layoutelemente deinem Widget hinzufügst. Wie das dann für dein DockWidget aussieht, das sozusagen dein CustomWidget im DockWidget angepaßt wird, weiß ich nicht genau, wobei ich das wohl bei mir im generierten Code nachschauen könnte. Mir ist noch nicht so ganz klar, warum die Widgets im Code laden mußt und nicht per Designer schon designen kannst?
Thoran
Wer Rechtschreibfehler findet, darf diese gerne behalten.
Mein Entwicklertagebuch
Aktuelle Projekte: Universum: Domination (ehemalig AlphaOmega),Universum: Sternenjäger, PixelWars: Highscore-based Top-Down-Spaceshooter
Spieleengine Unreal 5
Mein Entwicklertagebuch
Aktuelle Projekte: Universum: Domination (ehemalig AlphaOmega),Universum: Sternenjäger, PixelWars: Highscore-based Top-Down-Spaceshooter
Spieleengine Unreal 5
Re: [Qt] Fenster aus .ui Datei erstellen
Ok, also mal mehr Details.
In der Editor.ui hab ich mehrere DockWidgets, in einem davon will ich jetzt mein Tool laden. Ich hab also ein QDockWidget, mit einem QWidget als Child (wurde automatisch mit dem DockWidget erstellt) und als Layout horizontal ausgewählt.
Dann hab ich meine EntityAddTool.ui, die besteht aus einem QWidget, ebenfalls mit horizontalen Layout und dann halt einer ListBox und einem Button.
Soweit klingt das für mich eigentlich ganz vernünftig. In meiner Editorklasse (die der Wizard beim anleden der Editor.ui erstellt hat) mach ich nun folgendes:
Meine AddTool Klasse sieht so aus:
Tool ist dabei meine Oberklasse für alle Tools, um eine einheitliche Schnittstelle zu haben (macht bisher nix außer die Editor Referenz zu speichern), Ui_ToolEntityAdd die Klasse, die aus der EntityAdd.ui generiert wurde.
Wenn ich das so kompiliere, sehe ich meine List Box gar nicht, und den Button in falscher Größe. Wenn ich diesen anklicke passiert nix.
Die Frage ist jetzt: Wieso rafft Qt das mit meinem Layout nicht? Theoretisch hab ich wohl ein QDockWidget, dass ein QWidget mit einem Layout beinhaltet, in das ich mein eigenes QWidget mit Layout lade, indem der Button und die Liste ist. Dass ich 2 verschachtelte QWidgets habe ist zwar doof, aber es scheint nicht anders zu gehen, da ich das Content QWidget vom QDockWidget nicht löschen kann; egal, sollte ja auch so gehen.
Dann ist die Frage: Was muss ich tuen, damit er das mit dem automatisch verbinden rafft? Ich hab das ganze jetzt mit Vererbung gemacht (von Ui_ToolEntityAdd geerbt), damit er in der richtigen Klasse sucht, was er nicht tut.
Überhaupt ist das ganze automatisch verbinden irgendwie blöd, es wäre gut, wenn es sowas wie diese Annotations in Java gäbe, so dass ich eine Warnung bekommen würde, wenn eine Funktion nicht verbunden wird, obwohl ich das erwarte. Das jedesmal zu testen ob es klappt oder man sich vielleicht doch verschrieben hat, macht die Sache ziemlich witzlos...
In der Editor.ui hab ich mehrere DockWidgets, in einem davon will ich jetzt mein Tool laden. Ich hab also ein QDockWidget, mit einem QWidget als Child (wurde automatisch mit dem DockWidget erstellt) und als Layout horizontal ausgewählt.
Dann hab ich meine EntityAddTool.ui, die besteht aus einem QWidget, ebenfalls mit horizontalen Layout und dann halt einer ListBox und einem Button.
Soweit klingt das für mich eigentlich ganz vernünftig. In meiner Editorklasse (die der Wizard beim anleden der Editor.ui erstellt hat) mach ich nun folgendes:
Code: Alles auswählen
ui.setupUi(this);
m_AddTool.setupUi(ui.dockWidgetAddContents);
Code: Alles auswählen
class ToolEntityAdd : public Tool, public Ui_ToolEntityAdd
{
public:
ToolEntityAdd(Editor& theEditor);
void Init();
public Q_SLOTS:
void on_pushButtonLoadFactory_clicked(bool checked);
private:
FactoryP<Entity, std::string> m_EntityFactory;
};
Wenn ich das so kompiliere, sehe ich meine List Box gar nicht, und den Button in falscher Größe. Wenn ich diesen anklicke passiert nix.
Die Frage ist jetzt: Wieso rafft Qt das mit meinem Layout nicht? Theoretisch hab ich wohl ein QDockWidget, dass ein QWidget mit einem Layout beinhaltet, in das ich mein eigenes QWidget mit Layout lade, indem der Button und die Liste ist. Dass ich 2 verschachtelte QWidgets habe ist zwar doof, aber es scheint nicht anders zu gehen, da ich das Content QWidget vom QDockWidget nicht löschen kann; egal, sollte ja auch so gehen.
Dann ist die Frage: Was muss ich tuen, damit er das mit dem automatisch verbinden rafft? Ich hab das ganze jetzt mit Vererbung gemacht (von Ui_ToolEntityAdd geerbt), damit er in der richtigen Klasse sucht, was er nicht tut.
Überhaupt ist das ganze automatisch verbinden irgendwie blöd, es wäre gut, wenn es sowas wie diese Annotations in Java gäbe, so dass ich eine Warnung bekommen würde, wenn eine Funktion nicht verbunden wird, obwohl ich das erwarte. Das jedesmal zu testen ob es klappt oder man sich vielleicht doch verschrieben hat, macht die Sache ziemlich witzlos...
Zuletzt geändert von Jonathan am 22.04.2011, 23:23, insgesamt 1-mal geändert.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: [Qt] Fenster aus .ui Datei erstellen
Ich bin einen Schritt weiter.
Man nehme ein DockWidget, mit einem ContentWidget (anders gehts ja gar nicht). Dieses ContentWidget darf allerdings kein Layout haben, dann kann man problemlos ein anderes QWidget aus einer ui Datei laden.
Nachdem also das Layout nun stimmt, bleibt noch die Frage, wie ich die Signals&Slots hinbekomme. Ich habe jetzt eine Tool Klasse, die eine Instanz auf das UI Objekt vom Designer speichert. Jetzt müssen die Signale aus diesem Widgets mit den Slots meiner Toolklasse verbunden werden. Das automatische Verbinden klappt nicht, das manuelle leider auch nicht:
Ja, ganz toll, dass connect nur true oder false zurückgibt - mir aber nicht sagen will, WAS denn jetzt schief gelaufen ist. Ist es eigentlich so schwer, vernünftige Fehlermeldungen zu schreiben?
Man nehme ein DockWidget, mit einem ContentWidget (anders gehts ja gar nicht). Dieses ContentWidget darf allerdings kein Layout haben, dann kann man problemlos ein anderes QWidget aus einer ui Datei laden.
Nachdem also das Layout nun stimmt, bleibt noch die Frage, wie ich die Signals&Slots hinbekomme. Ich habe jetzt eine Tool Klasse, die eine Instanz auf das UI Objekt vom Designer speichert. Jetzt müssen die Signale aus diesem Widgets mit den Slots meiner Toolklasse verbunden werden. Das automatische Verbinden klappt nicht, das manuelle leider auch nicht:
Code: Alles auswählen
class Tool : public QObject
{
Q_OBJECT
public:
Tool(Editor& theEditor): m_Editor(theEditor){}
virtual void setupUi(QWidget *Parent)=0;
virtual ~Tool(){}
protected:
Editor& m_Editor;
class ToolEntityAdd : public Tool
{
public:
ToolEntityAdd(Editor& theEditor);
void Init();
void setupUi(QWidget *Parent);
public Q_SLOTS:
void on_LoadFactory(bool checked);
private:
Ui::ToolEntityAdd ui;
FactoryP<Entity, std::string> m_EntityFactory;
};
void ToolEntityAdd::setupUi(QWidget *Parent)
{
ui.setupUi(Parent);
assert(connect(ui.pushButtonLoadFactory, SIGNAL(clicked(bool)), SLOT(on_LoadFactory(bool))));
}
void ToolEntityAdd::on_LoadFactory(bool checked)
{
QMessageBox::information(0, "Patience please", "loading Factory...");
}
};
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
Re: [Qt] Fenster aus .ui Datei erstellen
Der Vollständigkeit halber: Es reicht nicht, in Tool das Q_OBJECT Makro zu benutzen, man muss es in jeder davon abgeleiteten Klasse nochmal machen, sonst findet er den Slot nicht. Und Fehlermeldungen landen in der Debuggerausgabe, nur hatte ich nicht daran gedacht, diese durchzulesen.
Und ob ich die auch automatisch verbinden könnte: Ich machs lieber von Hand, dann krieg ich wenigstens mit, wenn ich mich vertippt habe. Es ist mir jetzt schon zig mal passiert, dass irgendeine Kleinigkeit im Namen nicht stimmte und zack hat es geknallt...
Und ob ich die auch automatisch verbinden könnte: Ich machs lieber von Hand, dann krieg ich wenigstens mit, wenn ich mich vertippt habe. Es ist mir jetzt schon zig mal passiert, dass irgendeine Kleinigkeit im Namen nicht stimmte und zack hat es geknallt...
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/