Alle widgets von Parentwidget/-form auflisten (gelöst)

Alles rund um die Programmierung mit Qt
Antworten
and4mor
Beiträge: 2
Registriert: 17. Februar 2022 11:00

Alle widgets von Parentwidget/-form auflisten (gelöst)

Beitrag von and4mor »

Hallo liebes Forum,
ich bin Anfänger/Autodidakt mit C++/Qt und stehe nun vor dem Problem, dass ich ein Formularfenster/Widget habe auf dem viele Groupboxes mit noch mehr Checkboxes installiert sind, welches ich vor einer Neueingabe resetten möchte (also alle gecheckten Boxes auf unchecked setzen). In C# war das relativ einfach zu bewerkstelligen z. B. mit:

Code: Alles auswählen

            System.Collections.IList panelList = Controls; // alle Controls in Liste zusammenfassen
            
            for (int i = 0; i < panelList.Count; i++)
            {
                if (panelList[i] is MetroFramework.Controls.MetroPanel)  // prüfen, ob Control ein Panel ist
                {
                    MetroFramework.Controls.MetroPanel panel = (MetroFramework.Controls.MetroPanel)panelList[i];

                    System.Collections.IList controlList = panel.Controls;
                    for (int n = 0; n < controlList.Count; n++)
                    {
                        Control control = (Control)controlList[n];
                        if (control is MetroFramework.Controls.MetroTextBox) (control as MetroFramework.Controls.MetroTextBox).Text = "";
                        if (control is RadioButton) (control as RadioButton).Checked = false;
                    }
                }
Trotz intensiver Suche (es gibt für Qt fast nur offizielle Dokus) habe ich leider nichts dergleichen finden können. Auch hilft mir diese Doku nicht weiter, da es weder für Groupboxes eine entsprechende list()-Funktion gibt (nur .add()) noch ich irgendwas für das übergeordnete Widget finden konnte. Daher müsste ich jetzt alles "zu Fuß" machen im Stile von:

Code: Alles auswählen

    if(ui->CheckBox->isChecked()){
        ui->CheckBox->setAutoExclusive(false);
        ui->CheckBox->setChecked(false);
        ui->CheckBox->setAutoExclusive(true);
    }
Erstens bläht das den gesamten Code fürchterlich auf und wird extrem lang und unübersichtlich und verletzt die DRY-Regel (Don`t repeat yourself).
Also nun zu meiner Frage: Gibt es in C++ ein Konstrukt, dass es möglich macht die Objekte elegant zurückzusetzen?

Evtl. gibt es auch die Möglichkeit das komplette Formular zu reloaden und damit automatisch zurückzusetzen?!?

Schon im Voraus vielen lieben Dank
Zuletzt geändert von and4mor am 21. Februar 2022 15:12, insgesamt 1-mal geändert.
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Re: Alle widgets von Parentwidget/-form auflisten

Beitrag von hilefoks »

Moin,

da gibt es mehrere Wege (auch mehr als die 3 hier genannten).

1) im Prinzip kann man das gesamte Formular neu initialisieren (ui->setupUi). Dabei muss man aber einiges beachten. Diesen Weg würde ich daher nicht unbedingt gehen.

2) Man kann die Checkboxen auch nicht per Designer, sondern programmatisch aus C++ erzeugen. Im Designer erzeugt man dann ein Widget als Platzhalter, befüllt es aber aus C++ heraus. Dadurch kann man diese dann leicht in eigenen Datenstrukturen verwalten (QList oder so) und so über diese Struktur iterieren. In einigen Situationen bevorzuge ich diesen Weg.

3) Der einfachste Weg in deinem Fall scheint mir aber folgender. Qt hat durchaus die Funktion die du aus C# gewöhnt bist, wenn auch anders implementiert. Und zwar hat QObject und damit jedes QWidget die Methode findChilden (siehe https://doc.qt.io/qt-6/qobject.html#findChildren). Damit kann man, wie der Name schon sagt, jedes Kind ausgehend von einem beliebigen QObject finden.

Um z.B. alle Checkboxen zu finden:

Code: Alles auswählen

const auto list = findChildren<QCheckBox*>();
std::for_each(list.cbegin(), list.cend(), [](auto cb) { cb->setChecked(false); });
Oder nur die Checkboxen unterhalb eines bestimmten Widgets, hier z.B. groupBox1:

Code: Alles auswählen

const auto list = ui->groupBox1->findChildren<QCheckBox*>();
std::for_each(list.cbegin(), list.cend(), [](auto cb) { cb->setChecked(false); });
MfG
Hilefoks
and4mor
Beiträge: 2
Registriert: 17. Februar 2022 11:00

Re: Alle widgets von Parentwidget/-form auflisten

Beitrag von and4mor »

@ hilfoks: Super und vielen Dank. Werde mich die nächsten Tage dran versuchen. Hatte jetzt schon ellenlangen, sich ständig wiederholenden Code geschrieben dank Copy & Paste, sieht aber echt nicht schön aus und schon gar nicht elegant. Der Tipp dürfte auch einfach zu realisieren sein, da alles in Groupboxen gepackt ist. Die grafische Oberfläche "zu Fuß" zu erstellen dürfte in meinem Fall aufwendig werden, da doch sehr viele Elemente vorhanden sind.
Also nochmal vielen lieben Dank
Antworten