2016-04-20 5 views
1

In meiner GUI möchte ich eine QComboBox zu einer verticalLayout programmatisch basierend auf einem Signal durch bestimmte Aktion ausgelöst hinzufügen. Der folgende Code funktioniert gut und das Widget wird hinzugefügt:Wie positioniere ich ein hinzugefügtes Widget zu einem Layout, das auf einem anderen Widget im selben Layout basiert?

QComboBox* userOptions = new QComboBox(); 
ui->verticalLayout_13->addWidget(userOptions); 

Doch diese Art und Weise des Widget immer bis zum Ende des Layouts hinzugefügt wird.

Meine Frage ist: Wie positioniert man die QComboBox an die verticalLayout in Ausrichtung auf ein anderes Widget im selben Layout? (z. B .: über der "Go" -Schaltfläche zum Beispiel)

+1

Haben Sie wirklich einen neuen QComboBox erstellen müssen? Weil Sie es im Layout lassen und sichtbar machen können oder nicht, ob Sie es brauchen oder nicht. – ymoreau

+0

@YMoreau: Ich habe gerade die Sichtbarkeitseigenschaft verwendet, wie Sie vorgeschlagen haben. Danke –

Antwort

2

Es scheint keine Möglichkeit zu geben, ein Element explizit in ein Layout einzufügen, wo es sein soll.

Sie haben ein paar Möglichkeiten, dass die „harten“ Weg zu erreichen:

QLayout::takeAt(int index)
  • Gebrauch alle Einzelteile nach dem Index Sie einfügen möchten, um, legen Sie die Position und die aufgenommenen Elemente einfügen zurück.
  • Erstellen Sie ein Platzhalter-Widget, mit dem Sie einen Index im Layout reservieren können. Dann fügen Sie das Element nicht in das Layout ein, sondern in ein Layout, das im Platzhalter-Widget verschachtelt ist. Ohne ein Element benötigt das Platzhalter-Widget keinen Platz und wird erweitert, um alles aufzunehmen, was darin eingefügt wird.
  • implementieren Sie Ihre eigene QLayout Unterklasse, die das Einfügen in einem bestimmten Index unterstützt. Es gibt mehrere Funktionen, die Sie implementieren müssen.

EDIT: eine Auslassung an meinem Ende, wie Kuba Ober erwähnt, die meisten der Beton Layout Implementierungen unterstützen bei einem bestimmten Index, beispielsweise das Einfügen QBoxLayout abgeleitet haben Einsatzverfahren, die einen Index als Parameter übergeben.

+0

Es sieht wie viel unnötige "harte" Arbeit für das aus, was ich dachte, dass es eine nette und einfache Fähigkeit ist, zu lernen. Soweit es meine Bewerbung betrifft, bleibe ich bei der ersten Zeile in Ihrer Antwort (zumindest jetzt) ​​und verwende Sichtbarkeitseigenschaften wie "Y Moreau" vorgeschlagen. Danke –

+0

Vielleicht möchten Sie sich erneut die Dokumentation konkreter Layouts ansehen. Ja, es gibt keine Möglichkeit, dies nur mit der 'QLayout'-Schnittstelle zu tun, aber alle konkreten Layouts unterstützen es definitiv. 'QGridLayout' lässt Sie nicht direkt einfügen, aber Sie können vorhandene Elemente einfach mischen, um Platz für das neue zu schaffen. –

+0

@KubaOber - Ja, es ist wahr, ich habe es vorher nicht bemerkt, hauptsächlich weil ich Layouts nicht so oft und meistens in einem statischen Szenario verwendet habe. Ich verwende meistens QML, und QML-Layouts haben das überhaupt nicht. – dtech

1

Iterieren Sie zuerst ein Layout, um den Index des Referenzelements zu finden, in das Sie einfügen. Verwenden Sie dann die spezifische Widget-Einfüge-/Hinzufügungsfunktion des konkreten Layouts.

Da Sie vermutlich QBoxLayout verwenden, verwenden Sie die Methode insertWidget, um ein Widget einzufügen.

// https://github.com/KubaO/stackoverflown/tree/master/questions/insert-widget-36746949 
#include <QtWidgets> 

namespace SO { enum InsertPosition { InsertBefore, InsertAfter }; } 

bool insertWidget(QBoxLayout * layout, QWidget * reference, QWidget * widget, 
        SO::InsertPosition pos = SO::InsertBefore, int stretch = 0, 
        Qt::Alignment alignment = 0) { 
    int index = -1; 
    for (int i = 0; i < layout->count(); ++i) 
     if (layout->itemAt(i)->widget() == reference) { 
     index = i; 
     break; 
     } 
    if (index < 0) return false; 
    if (pos == SO::InsertAfter) index++; 
    layout->insertWidget(index, widget, stretch, alignment); 
    return true; 
} 

ähnliche Funktionen leicht werden können QFormLayout, QGridLayout und QStackedLayout entwickelt.

Und ein Test-Harnisch:

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    QWidget w; 
    QVBoxLayout l{&w}; 
    QLabel first{"First"}; 
    QLabel second{"Second"}; 
    l.addWidget(&first); 
    l.addWidget(&second); 
    insertWidget(&l, &first, new QLabel{"Before First"}, SO::InsertBefore); 
    insertWidget(&l, &second, new QLabel{"After Second"}, SO::InsertAfter); 
    w.show(); 
    return app.exec(); 
} 
Verwandte Themen