Menü-Design: Welcher Container für lebendige Interaktion?
-
Hallo zusammen,
ich habe mich kürzlich mit verschiedenen Funktionen im Layout Designer beschäftigt und verschiedene Möglichkeiten zur Erstellung von Menüs ausprobiert. Obwohl ich noch nicht ganz sicher bin, welche Option für mich am besten geeignet ist, hoffe ich, dass sich das mit der Zeit klärt.
Nun stehe ich vor der Herausforderung, meinen Menüs etwas Leben einzuhauchen, insbesondere wenn sie angeklickt werden sollen. Ich möchte, dass z.B. beim Klicken auf "Datei" in meinem Menü nicht einfach ein neues Fenster geöffnet wird, sondern dass alles in meinem Hauptfenster geladen wird. Dort möchte ich dann die entsprechenden Aktionen durchführen und, wenn ich fertig bin, zu meinem Hauptbildschirm zurückkehren oder einen neuen Punkt im Menü auswählen können.
Meine Frage ist nun, welchen Container ich dafür am besten verwenden sollte. Im Moment denke ich, dass ein "stackedWidget" hier gut passen könnte.
Ich frage mich jedoch, ob größere Formulare oder Prozesse auf den einzelnen Seiten des stackedWidgets mit Ladezeiten oder anderen Problemen verbunden sind. Sind die Seiten, die nicht sichtbar sind, deaktiviert und für den Programmablauf nicht mehr relevant? Blockieren sie Ressourcen oder stehen sie nicht im Konflikt mit den anderen Seiten?
Ich hoffe, meine Frage ist verständlich, und jemand kann mir bei meinem Gedankenwirrwarr helfen.
Viele Grüße,
Mücke -
@Muecke82
Hallo Mücke,wenn ich Dich richtig verstehe, dann bist Du auf der Widgets-Seite unterwegs und Quick/QuickControls sind kein Thema? Denkbar wären dann ein
QTabWidget
oder eben einQStackedWidget
. Der Unterschied ist hauptsächlich optischer Natur und damit Geschmackssache. Die nicht aktivierten "Seiten" werden nicht gemalt, und blockieren keine Ressourcen in Sachen Grafik. Die Frage ist, welche Klassen Du für diese Seiten verwendest. Auch ein hidden Widget horcht auf Events und Signale. So lange sie nur auf auf ihren Show-Event warten, sind sie genügsam. Aber das hängt davon ab, was Du programmierst. Vielleicht willst Du ja gerade bei komplexen Formularen im Hintergrund z.B. einQAbstractItemModel
mit Daten füllen, damit der Show-Event nicht zum Show-Stopper wird.Fazit: Anwort musst Du Dir selbst geben, ich hoffe ich konnte etwas zur Verwirrung beitragen ;-)
LG
Axel -
Eine kleine Ergänzung bezüglich Ressourcen: Wenn du im Designer alle Seiten des Stacked Widgets zusammenklickst, bedeutet das auch, dass beim Programmstart alle Seiten geladen werden (d.h. alle UI-Objekte angelegt werden). Je mehr UI-Objekte du hast, desto langsamer könnte es sein, dass dein Programm startet.
Übersichtlicher ist es ohnehin die einzelnen Seiten des Stacked Widgets in einzelne .ui-Dateien zu packen und dann über Code zu laden. Die beste Optimierung hierbei ist, dass die Seiten nur dann geladen werden, wenn sie das erste Mal gebraucht werden. Dann sollte dein Programm sich auch schnell öffnen lassen.
-
@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
Du auf der Widgets-Seite unterwegs und Quick/QuickControls sind kein Thema?
Hmm, jetzt fragst du mich was, jetzt muss ich erst mal nachschauen was "Quick/QuickControls" ist um das zu beantworten.
Bisher habe ich so nette Videos gesehen, wie man mit dem Formular-Editor kleine Programme bauen kann (leider sind die alle in Pyton und nicht in C++, weshalb mir der Code-Teil etwas schwergefallen ist, aber ich habe die ersten Sachen hinbekommen).
https://www.youtube.com/watch?v=adC48qZ8p5Y
https://www.youtube.com/watch?v=7DXxQV47jOU&t=1207s
usw. ...Bis jetzt habe ich mich ein wenig mit Menüs beschäftigt und verschiedene Dinge zusammengebaut bzw. nachgebaut.
Jetzt würde ich mich gerne damit beschäftigen, wo ich die einzelnen "Fenster" dann auch anzeigen lassen kann, damit der Benutzer etwas machen kann. Ich stelle mir das im Moment noch etwas schwierig vor.
@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
Die Frage ist, welche Klassen Du für diese Seiten verwendest.
Das ist auch eine gute Frage, so weit bin ich noch nicht, und auch das muss ich erst noch schlagen, was das genau bedeutet.
@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
Auch ein hidden Widget horcht auf Events und Signale.
Das stelle ich mir problematisch vor, wenn ich jetzt ca. 40 verschiedene "Seiten" habe. Die dann alle ständig jedes Signal etc. abfragen und mithören. Denn jede Seite hat ja nicht nur 1 Signal, sondern viel mehr.
@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
Vielleicht willst Du ja gerade bei komplexen Formularen im Hintergrund z.B. ein QAbstractItemModelmit Daten füllen, damit der Show-Event nicht zum Show-Stopper wird.
Hmm, diese Dinge sind eher in den einzelnen Menüpunkten, wenn diese einen Ablauf haben und so weiter.
Zwischen den einzelnen Menüpunkten wird das nicht gemacht, wenn ich das richtig im Kopf habe, naja, das kann sich noch ändern, wenn ich weiß, was ich wirklich brauche ;-)@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
ich hoffe ich konnte etwas zur Verwirrung beitragen ;-)
Ein bisschen, aber für eine gute Verwirrung.
DANKE@SimonSchroeder: Das klingt nach etwas mehr Übersicht.
Habe ich das richtig verstanden, hier würde ich ein Haupt UI bauen (Menü und Platzhalter der einzelnen Unter UI`s, Platzhalter wären dann die Pages des stackedWidget?Ich würde mir das Prinzip gerne genauer anschauen und würde auch eher dem Endsprechen, wie ich mir das zu Beginn gedacht habe.
Gibt es für diese Art einen Namen, nach dem ich suchen kann? Oder ein kleines Beispiel, das ich mir anschauen kann?
-
@Muecke82 said in Menü-Design: Welcher Container für lebendige Interaktion?:
Das ist auch eine gute Frage, so weit bin ich noch nicht, und auch das muss ich erst noch schlagen, was das genau bedeutet.
Dann empfehle ich Dir, unsere Examples anzuschauen.
-
@Muecke82 said in Menü-Design: Welcher Container für lebendige Interaktion?:
Das stelle ich mir problematisch vor, wenn ich jetzt ca. 40 verschiedene "Seiten" habe. Die dann alle ständig jedes Signal etc. abfragen und mithören. Denn jede Seite hat ja nicht nur 1 Signal, sondern viel mehr.
Mir scheint, dass diese Lektüre angesagt ist. Signale werden nicht "abgehört", der Mechanismus ist in der Dokumentation genau beschrieben.
-
@Muecke82 said in Menü-Design: Welcher Container für lebendige Interaktion?:
Habe ich das richtig verstanden, hier würde ich ein Haupt UI bauen (Menü und Platzhalter der einzelnen Unter UI`s, Platzhalter wären dann die Pages des stackedWidget?
QStackedWidget
kannst du dir wie ein Buch vorstellen, bei dem du zwischen Seiten hin- und herblättern kannst. Ohne, dass du die anderen Seiten/Widgets komplett entfernen/ersetzen musst.
Ob du jetzt wirklich 40 "Seiten" für deine App benötigst, bezweifle ich, da du ja die einzelnen Seiten auch nochmal füllen kannst mit mehrenen Widgets wie Buttons, Schalter, Textfelder etc. Daher eher eine Seite pro "Themengebiet".Das stelle ich mir problematisch vor, wenn ich jetzt ca. 40 verschiedene "Seiten" habe. Die dann alle ständig jedes Signal etc. abfragen und mithören. Denn jede Seite hat ja nicht nur 1 Signal, sondern viel mehr.
Bevor du wirklich anfängst zu "basteln" und zu designen, würde ich auch grob einen Plan machen, was du dir vorstellst, wie die App funktionieren soll und zu bedienen ist.
Und Signale werden ja nur gesendet, wenn sie wirklich ausgelöst werden.
Da versteckte Widgets ja eh nicht neu gerechnet und gerendert werden, passiert dort nicht soo viel, außer du schickst selbst aktiv Signale an die Objekte, die dann natürlich noch imQStackedWidget
"leben".
Darum, was @SimonSchroeder oben meinte: Erst wirklich die Seite vollständig aufbauen lassen, wenn sie zum ersten Mal wirklich gebraucht wird. Falls du 20 Seiten hast, aber ein Nutzer klickt sich nur durch die ersten 5 und schließt das Programm wieder, dann hättest du unnötigerweiser Speicher reserviert und Ladezeit verloren :) -
@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
Dann empfehle ich Dir, unsere Examples anzuschauen.
Welche meinst du denn?
@Axel-Spoerl said in Menü-Design: Welcher Container für lebendige Interaktion?:
Mir scheint, dass diese Lektüre angesagt ist. Signale werden nicht "abgehört", der Mechanismus ist in der Dokumentation genau beschrieben.
Das ist jetzt nicht böse gemeint, aber mir fehlt ein Teil des Fachwissens und ich verstehe wirklich wenig davon.
Das soll jetzt nicht heißen, dass ich das nicht lesen werde, ganz im Gegenteil, denn nur wenn ich viel lese, kann ich hoffentlich mehr verstehen.@Pl45m4 Ok das mit dem Buch verstehe ich.
Ja ich habe mir oder ich mache mir immer wieder neue Ablaufpläne. Gerade immer wenn ich was Neues ausprobiert habe, dann ändere ich den Ablaufplan ein bisschen :-)
Wobei ich noch gar nicht am eigentlichen Programm schreibe, sondern ich versuche nur verschiedene Sachen auszuprobieren, um zu verstehen, was wie funktioniert und wie man dann auch auf was zugreifen kann.Was ich noch nicht herausgefunden habe ist, wie man ein neues Formular (UI) in eine der QStackedWidget Page Buchseiten laden kann.
Und dann müsste man das noch im Code irgendwo mit einer Flagge versehen, bereits geladen oder noch zu laden. -
Aktuell habe ich die Seite des stackedWidget über einen Menüpunkt so aufgerufen.
meiwindow.h
private slots: void on_action_Datei_Einstellungen_triggered();
maiwindow.cpp
void MainWindow::on_action_Datei_Einstellungen_triggered() { ui->stackedWidget->setCurrentWidget(ui->page_Einstellungen); }
Ich habe nun eine neue Seite (Einstellungen.ui) erstellt.
Diese UI müsste ich nun mit der Seite "page_Einstellungen" verknüpfen, damit der Inhalt dieser Seite auch angezeigt wird, wenn ich die Seite aufrufe.
Dazu habe ich aber noch nichts im Netz gefunden :-(
Wie heißt das? Wonach muss ich suchen?[Edit] sorry, habe versehentlich zu früh den Beitrag abgesendet.
-
@Muecke82 said in Menü-Design: Welcher Container für lebendige Interaktion?:
Ich habe nun eine neue Seite (Einstellungen.ui) erstellt.
Diese UI müsste ich nun mit der Seite "page_Einstellungen" verknüpfen, damit der Inhalt dieser Seite auch angezeigt wird, wenn ich die Seite aufrufe.
Dazu habe ich aber noch nichts im Netz gefunden :-(
Wie heißt das? Wonach muss ich suchen?Da das Formular/Widget
Einstellungen
nun nicht mehr inmainwindow.ui
und somit auch nicht mehr über denui->
Zeiger vonMainWindow
erreichbar ist, musst du das neue Form bzw. die Klasse (Header, Code und UI Datei) inmainWindow
einbinden.
Z.B. mit#include "einstellungen.h"
Dann machst du entweder pro Seite eine private Member Variable in deinem
MainWindow
, die immer den Zeiger je Seite hält, oder du erstellst das Widget lokal im Slot, der ausgelöst wird, wenn der Knopf gedrückt wird und fügst es dann zumQStackedWidget
hinzu.Da das Hinzufügen mit
stackedWidget->addWidget(....)
das neue Widget zum Kind vom StackedWidget macht, musst du dir auch keine Gedanken über das Löschen und Speicherfreigeben machen. Durch die Eltern-Kind-Klassenstruktur vonQOject
, werden Kinder automatisch gelöscht, wenn das übergeordneteQObject
gelöscht wird. In dem Fall oben würde sich dasQStackedWidget
und somit auch die Seiten erst löschen, wenn das Eltern-Widget von ihm gelöscht wird... und das passiert erst, wenn du das Programm beendest, da das übergeodnete Widget vomQStackedWidget
dasMainWindow
ist.Könnte in etwa so aussehen:
MainWindow.h
// hier deine neue Form-Klasse einbinden #include "einstellungen.h" private: Einstellungen* m_pageEinstellungen;
MainWindow.cpp
// Konstruktor und andere Funktionen... // ... // ... // Deine Slots zum Wechseln der Seiten void MainWindow::on_action_Datei_Einstellungen_triggered() { if (!m_pageEinstellungen) { // Wenn der Zeiger noch "irgendwo" hinzeigt -> kein Objekt vorhanden (nicht initialisiert) m_pageEinstellungen = new Einstellungen; // dann erzeuge neues Objekt deiner Klasse inkl. UI Form ui->stackedWidget->addWidget(m_pageEinstellungen); // und füge Objekt dem StackedWidget hinzu } else { ui->stackedWidget->setCurrentWidget(m_pageEinstellungen); // sonst, wenn Seite schon erstellt wurde, zeige sie direkt an } }
So kannst du theoretisch mit jeder "Seite" umgehen.
Hab das jetzt "mal eben" hier Antworten Fenster gecodet... also keine Garantie, ob ich nicht was vergessen habe :)
Sollte aber so funktionieren :)Dann hast du deine
einstellungen.h
,.cpp
und.ui
, die du genauso bearbeiten und gestalten kannst, wie dasMainWindow
.
Ist ja nix anderes... Buttons hinzufügen, Funktionen schreiben, Verbindungen für Signale zu anderen Widgets erstellen usw.Hab versucht den Code mal auf Deutsch und einsteigergerecht zu kommentieren.
Es hilft halt ungemein C++ zu können, bzw. solide Kenntnisse sollten vorhanden sein, um Qt einigermaßen zu nutzen :)Geeignete Stichwörter zum Nachlesen wären zum Beispiel:
- C++ Objekt von Klasse erzeugen
- Klassenvariablen (und deren Sichtbarkeit)
- Klassenvererbung
- Nutzen von
#includes
, um Instanzen in anderen Klassen zu erzeugen
Sind alles eigentlich C++ Grundlagen. Keine Ahnung wie weit du dich da schon eingelesen hast...
Hier ist noch eine kleine Einführung in C++ (auf Deutsch).
Mir fällt es ehrlich gesagt schon schwer die deutschen Wörter zu nutzen und muss teilweise überlegen, wie man etwas auf Deutsch (in Programmier-Fachsprache) überhaupt nennt :)
Meist kommt man um so ein DEnglisch nicht herum. Wie in dem anderen Beitrag von @Volker75 bereits gesagt, würde man eher HTML auf Deutsch sagen, während man Python und nicht "Püton" sagt.Edit:
Kleine Ergänzung zu
Einstellungen* m_pageEinstellungen;
und
if (!m_pageEinstellungen)
Alle ungenutzen Zeiger mit "null" / "nullptr" zu initialisieren macht das Programm berechenbarer, da
Einstellungen* m_pageEinstellungen
eben irgendwo im Speicher hin zeigt, wo gerade frei ist... und da können u.U. noch Datenfragmente von anderen Prozessen oder sonst was stehen.
Daher, wenn man im Kontruktor alle privaten Zeiger mitm_pageEinstellungen = nullptr; // oder m_pageEinstellungen = NULL; // macro NULL = nullptr // oder m_pageEinstellungen = 0;
initialisiert, weiß man, dass es wirklich den "Nichts" Wert hat, der nicht wirklich nichts ist, sondern deterministisch
NULL
/0
und nicht theoretischxeFBG124sjj288nsnsgjfwj12458
oder sonst was, was an Bytes gerade in dem Speicherbereich steht, den der Zeiger zugewiesen bekommen hat. Und das kann wirklich ALLES sein... Speicherbereiche aus dem selben Programm... andere Variablen oder auch eben Schrott, der von anderen Prozessen übrig ist. -
Oha, das muss ich in Ruhe durcharbeiten, das ist viel. !
Allerdings habe ich den Eindruck, dass ich bei der Erstellung meines anderen Formulars etwas nicht richtig gemacht habe, denn ich habe die h-Datei nicht, oder ist das normal, dass man sie dann selbst von Hand erstellen muss? wenn nicht, dann habe ich das mit dem Assistenten zur Erstellung des Formulars nicht ganz richtig gemacht.
-
@Muecke82 said in Menü-Design: Welcher Container für lebendige Interaktion?:
Allerdings habe ich den Eindruck, dass ich bei der Erstellung meines anderen Formulars etwas nicht richtig gemacht habe, denn ich habe die h-Datei nicht, oder ist das normal, dass man sie dann selbst von Hand erstellen muss? wenn nicht, dann habe ich das mit dem Assistenten zur Erstellung des Formulars nicht ganz richtig gemacht.
Das hängt wirklich davon ab, was du ausgewählt hast...
Gibt mehrere Optionen im Assistenten, unter anderem:
-
C++ > C++ - Klasse
, erstellt Header und Code-Datei für deine Implementierung. GUI Elemente müssten jedoch manuell per Code hinzugefügt werden. Ansonsten ist es eine reine Nicht-Qt C++ Klasse (bzw. Klassen-Vorlage). -
Qt > Designer-Formularklasse
, wie oben, vollständige C++ Klasse, jedoch mit fertig eingebundener UI Datei, die mit dem Designer bearbeitet werden kann. -
Qt > Qt Designer Formular
, reines UI Designer Formular im XML style, ohne eine Klassenstruktur. Muss manuell in einer Klasse z.B. durchQUiLoader
zur Laufzeit geladen werden, siehe hier:
Das Zweite wäre das, was ich für die Widget-Seiten empfehlen würde. So hast du die Unterstützung vom Designer für deine UI und kannst aber trotzdem, vergleichsweise "einfach" direkt loscoden und das Widget mit Logik versehen, ohne irgendwelche Datei nachzuladen oder zur Laufzeit mit
QUiLoader
, der auch seinen Nutzen hat, irgendwas zusammenzubasteln. -
-
Liebe Community,
ich möchte mich von Herzen bei euch allen für eure wertvolle Unterstützung bedanken. Es war großartig, eure Hilfe zu bekommen und eure Ratschläge zu erhalten.
Nach gründlicher Überlegung habe ich jedoch erkannt, dass Programmierung nicht meine Stärke ist und mich nicht zu meinen Zielen führen wird. Daher habe ich beschlossen, nach einem Programmierer zu suchen, der das Programm für mich erstellt. Dies beinhaltet sowohl die Software- als auch die Hardwareprogrammierung sowie die notwendige Analyse.
Vielen Dank noch einmal an jeden einzelnen von euch für eure Hilfe und euer Verständnis.
Herzliche Grüße,
Mücke -
-
@Muecke82 Es war eine Freude dir zu helfen. Leider hat Qt eine sehr steile Lernkurve. Oft genug haben wir hier im Forum Fragen von Leuten, die vollkommen davon überzeugt sind, dass Programmieren ihr Ding ist. Sie zeigen aber bei weitem nicht den Durchblick, den wir bei dir beobachtet haben.