Seite 1 von 1

QWidgets: Signale an Parent...

Verfasst: 17. November 2010 08:20
von tux.2000
Hallo Gemeinde!

Zu meinem "Problem":
Ich habe ein CustomWidget ("my_widget") erzeugt, dass ich manuell/dynamisch mit

Code: Alles auswählen

my_widget = new my_widget();
erzeuge und anschließend einem (vertikalen) Layout hinzufüge:

Code: Alles auswählen

ui->vertLayout->addWidget(my_widget);
Die wird zur Laufzeit des öfteren gemacht, so dass mir das Layout als Container für z.B. 30 my_widget()´s dient, die untereinander angeordnet sind.

Hier taucht auch gleich meine 1. Frage auf:
Ich weiß, dass ich 30 my_widget() im Layout habe. Wie iteriere ich über diese bzw. wie kann ich sie auslesen? Im Moment speichere ich die Adressen aller my_widgets() zwischen und verwalte diese über einen std::vector<unsigned int>. Da gibt es doch garantiert eine elegantere Möglichkeit?

Zu einem späteren Zeitpunkt in der Applikation wird das relativ große Layout einem neuen QWidget namen "Mgr" übergeben und dieses Widget in eine QScrollArea gehängt, damit der User über alle my_widget() scrollen kann..

Code: Alles auswählen

Mgr->setLayout(ui->vertLayout);

Code: Alles auswählen

ui->my_ScrollArea->setWidget(Mgr);
Das my_widget() beherbergt einige Knöpfe und Schalter.
Und damit kommen wir zur 2. Frage:
Ich möchte ganz gerne, dass das Fenster, das die ScrollArea verwaltet, auf die Signale dieser Buttons reagiert. Wenn z.B. ein Knopf gedrückt wird, soll z.B. die Hintergrundfarbe des Fensters geändert werden.
Wie verbinde ich das clicked()-Signal mit dem (Main-)Fenster (zur Laufzeit des Programmes?) Geschieht dies auch über die connect()-Anweisung?

Kurz noch die Struktur:

Code: Alles auswählen

QDialog
|
|--- QScrollArea
             |
             |--- ScrollAreaWidgetContent
                                     |
                                     |--- QVBoxLayout
                                                    |
                                                    |--- QWidget ("Mgr")*
                                                                  |
                                                                  |--- QWidget("my_widget")*
                                                                  |--- QWidget("my_widget")*
                                                                  |--- QWidget("my_widget")*
                                                                                    ...

* = zur Laufzeit erstellt (alles andere via Designer)
Ich müsste also das ausgesendet Button-clicked()-Signal bis hinauf zum QDialog-Fenster durchreichen oder? Wie realisiert man dies?

Vielen Dank im Voraus für eure Hilfe.

Verfasst: 17. November 2010 08:43
von padreigh
warum std::vector ... nimm QVector ... nimm generell die Qt Datentypen, damit bleibst du konsistent, die Handhabung ist fast identisch, sie sind effizienter beim rumkopieren (da shared und erstmal nicht kopiert) - natürlich greift letzteres nur wenn du nicht immer voll const und Referenz Übergaben machst.

Layouts "gehören" die ihm enthaltenen Sachen nicht, die gehören normalerweise dem Widget das dieses Layout mit widget::setLayout() bekam. Dort gibt es methoden wie children(), findChild<Typ*>() usw die dir im Verbund mit qobjectcast<Wunschtyp*> weiterhelfen können.

Ansonsten kannst du auch noch sogenannte objectnames vergeben (zB für alle myWidgets) den namen "myWidget" welche dann auch mit findChild<Typ*>(objectname) gefunden werden können. Du kannst dynamisch erzeugte myWidgets gleich bei der Erzeugung mit dem QDialog connecten ... entweder hältsts du den als member oder suchst ihn ähnlich wie die widgets ... das macht aber eigentlich nur Sinn wenn du von QDialog abgeleitet hast ... denn es reagieren nicht "Fenster" sondern Klassen auf Signale. Mach mal Minimalcode für mehr Auskunft (das sollte ja bei dem Beispiel recht übnersichtlich bleiben)

Verfasst: 17. November 2010 12:08
von tux.2000
Also nochmal zur Signal-Verbindung, da ich nicht weiß, wie die connect()-Zeile auszusehen hat

Ausgangslage:

Code: Alles auswählen

my_widget *my_widget;
my_widget = new my_widget();

Mein my_widget() beherbergt den QPushButton "btn_Remove". Sieht dann die Connect-Zeile etwa so aus?

Code: Alles auswählen

connect(my_widget->m_ui->btn_Remove, SIGNAL(clicked()), this, SLOT(Widget_Remove));
Nachtrag:
Nö, habs gerade versucht zu übersetzen... (*m_ui ist private). Das Widget und damit auch den PushButton hatte ich via Designer erstellt. Wie komme ich also an das Signal? Brauche ich dafür irgendwie diese findChild("btn_Remove") oder so?
Vielen Dank.

Verfasst: 17. November 2010 18:17
von padreigh
Wenn du das alles im Designer machen willst klickste auf das myWidget, Signale/Slots ändern und f+gst ein Signal hinzu: meinButtonklicked(). Dann connectest du (im designer) das Signal des buttons mit dem gerade erstellten signal des widgets. dann kannst du das connect ohne die indirektion über m_ui machen...

Code: Alles auswählen

 connect(my_widget, SIGNAL(meinButtongklicked()), this, SLOT(Widget_Remove));
Insgesamt sieht das aber merkwürdig aus und warscheinlich ein designwirrwarr ... code :)

Verfasst: 18. November 2010 11:44
von tux.2000
Ich will ja eben nicht mit dem Designer arbeiten. Die Connection zwischen SLOT und Signal soll zur Laufzeit realisiert werden! (nur das Aussehen des eigenen Widgets hatte ich im Designer gemacht).