2016-08-31 15 views
2

Ich habe mehrere QComboboxes teilen das gleiche Modell. Normalerweise können sie Elemente in diesem Modell unabhängig voneinander auswählen. In einigen Fällen möchte ich diese Comboboxen zwingen, die gleiche Modellreihe zu zeigen, d. H., Wenn man eine Auswahl ändert, sollte diese über die anderen Kombinationen reflektiert werden.Wie erzwingen mehrere Ansichten, um die gleiche Modellreihe zu zeigen

Dies kann über (ein potentielles Chaos von) Signalen und Slots erfolgen, aber ich frage mich, ob es eine Möglichkeit gibt, es vom Modellende sauberer zu machen. I.e. Erzwinge, dass alle Ansichten dieselbe Zeile anzeigen.

Ein Kommentar unten deutet darauf hin, das selectionModel unter den Combos zu teilen. Ich habe dies getan, indem meine Combos in eine Liste zu sammeln und ein Modell auf sie setzen:

QList<QComboBox*> my_combos; 
// .. then populate my_combos .. then 
QComboBox *combo; 
foreach(combo, my_combos) 
    combo->setModel(&_my_model); 

dann

QItemSelectionModel *selectionmodel = my_combos.at(0)->view()->selectionModel(); 
    foreach(combo, my_combos) 
    { 
    if (combo == my_combos.at(0)) 
     continue; 
    combo->view()->setSelectionModel(selectionmodel); 
    } 

Bin ich hier einen Schritt fehlt?

+0

Das Datenmodell kennt die Ansichten nicht, und es ist nicht seine Aufgabe, damit umzugehen. –

+0

Messepunkt - Haben Sie einen Vorschlag, wie Sie das sauber machen können? Wie sieht das Beispiel Hayt aus? – mike

Antwort

3

Die Auswahl ist ein Hering. QComboBox lässt keine Mehrfachauswahl zu. Was Sie als "Auswahl" bezeichnen, ist der aktuelle Index. Es ist einfach, es unter Comboboxen zu teilen, indem das currentIndexChanged Signal an setCurrentIndex verbindet:

// https://github.com/KubaO/stackoverflown/tree/master/questions/combo-shared-select-39247471 
#include <QtWidgets> 
#include <array> 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    QStringListModel model; 
    model.setStringList({ "foo", "bar", "baz "}); 

    QWidget ui; 
    QHBoxLayout layout{&ui}; 
    std::array<QComboBox, 3> combos; 
    // setIndices could be a method in a class 
    auto setIndices = [&combos](int index) { 
     for (auto & combo : combos) 
      combo.setCurrentIndex(index); 
    }; 
    for (auto & combo : combos) { 
     using namespace std::placeholders; 
     layout.addWidget(&combo); 
     combo.setModel(&model); 
     QObject::connect(&combo, 
         static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), 
         setIndices); 
    } 
    ui.show(); 

    return app.exec(); 
} 

Side Hinweis: Sie können die Widgets von Wert halten. Wenn ihre Nummer zum Zeitpunkt der Kompilierung festgelegt wurde, verwenden Sie . Andernfalls können Sie std::list mit emplace_back verwenden. Signiert, byValueGuy.

+0

Ja, dass N^2 Verbindungen mich unordentlich anfühlten, weshalb ich versuche, es zu vermeiden. – mike

+1

Nichts Unordentliches, es sei denn, Sie haben Profiler-Ergebnisse, um das Gegenteil zu beweisen, aber ja, vielleicht ist es eine vorzeitige Pessimierung.Wir können von O (N^2) nach O (N) über die Anzahl der Verbindungen gehen. –

+0

Ich würde sie alle mit einem Slot des oberen Widgets verbinden und diesen Slot alle entsprechenden Slots der Comboboxen aufrufen lassen. Sieht ein bisschen klarer aus und macht dasselbe. Der Teil, in dem das Objekt nach Wert gehalten werden kann, mag zwar stimmen, aber aus Gründen der Übereinstimmung mit Qt funktioniert das mit Heap-Allocation hier besser. – Hayt

2

prüfen http://doc.qt.io/qt-5/qitemselectionmodel.html und http://doc.qt.io/qt-5/model-view-programming.html#handling-selections-of-items

in der Regel jede Ansicht hat ein eigenes Modell zur Auswahl, aber Sie können eine Ansicht verwenden Sie das Auswahlmodell einer anderen Sicht.

Edit: es scheint, als ob die view von QComboBox nur für die Auswahl Popup ist. Sie könnten zusätzlich das selectionChanged/currentRowChanged-Signal des Selektionsmodells mit jedem "setCurrentIndex" verbinden.

Alternativ können Sie auch Ihre Elternklasse zu jedem Signal der Comboboxen verbinden lassen und dann den Slot jeder Combobox im Signalhandler der Elternklasse aufrufen.

+0

Das sieht wie die Antwort aus (Freigabe der Comboboxen-> view() -> selectionModel()) - aber es scheint nicht für meine qcomboboxes zu arbeiten. Ich werde die Frage mit einem Codebeispiel aktualisieren – mike

+0

@mike OK Ich habe mit einer Erweiterung bearbeitet, aber es scheint, als ob es nicht möglich ist, nur die Auswahlmodelle zu verbinden. – Hayt

+0

danke Hayt. der zweite Vorschlag (verbinde selectionChanged/currentRowChanged des Selektionsmodells mit setCurrentIndex der Combos) funktioniert nicht, da die Argumente nicht übereinstimmen (ich sehe weder einen setCurrentIndex, der einen QModelIndex akzeptiert, noch selection/currentRowChanged, die einen int senden). und die dritte Auswahl ist, was ich zu vermeiden hoffte, vielleicht bin ich irrational, aber ich mag es nicht, so viele Verbindungen aufzubauen, wenn ich ihnen helfen kann. – mike

Verwandte Themen