Reputation: 31
I have two QComboBoxes to connect with each other.
In particular, I'd like that if a scaling is made in the first QComboBox, this is not also shown in the second QComboBox and vice versa.
This is my code:
auto lingua_originaleT = new QComboBox();
lingua_originaleT->addItems({"Italiano", "Inglese", "Francese", "Spagnolo", "Portoghese", "Tedesco", "Cinese"});
auto lingua_targetT = new QComboBox();
lingua_targetT->addItems({"Italiano", "Inglese", "Francese", "Spagnolo", "Portoghese", "Tedesco", "Cinese"});
The result should be like this:
The same language should not appear in the second drop-down menu as well.
Upvotes: 0
Views: 71
Reputation: 31
I solved and the solution works perfectly! Here's how I did it:
lingua_originaleT = new QComboBox();
lingua_targetT = new QComboBox();
QStringList traduzioneLangList = {"Italiano", "Inglese", "Francese", "Spagnolo", "Portoghese", "Tedesco", "Cinese"};
lingua_originaleT->clear();
lingua_originaleT->addItems(traduzioneLangList);
lingua_originaleT->setCurrentIndex(-1);
lingua_targetT->clear();
lingua_targetT->addItems(traduzioneLangList);
lingua_targetT->setCurrentIndex(-1);
connect(lingua_originaleT, &QComboBox::currentTextChanged, lingua_targetT, [=](const QString &selection) {
auto tarLangList = traduzioneLangList;
lingua_targetT->blockSignals(true);
tarLangList.removeOne(selection);
lingua_targetT->clear();
lingua_targetT->addItems(traduzioneLangList);
lingua_targetT->blockSignals(false);
});
connect(lingua_targetT, &QComboBox::currentTextChanged, lingua_originaleT, [=](const QString &selection) {
auto tarLangList = traduzioneLangList;
lingua_originaleT->blockSignals(true);
tarLangList.removeOne(selection);
lingua_originaleT->clear();
lingua_originaleT->addItems(traduzioneLangList);
lingua_originaleT->blockSignals(false);
});
lingua_originaleT->setCurrentIndex(0);
Many thanks to @lifof on reddit!
Upvotes: 0
Reputation: 317
Internally, QCombobox uses QStandardItemModel - unless you provided a custom one using setModel()
.
That means you can do things like:
// Just some setup
auto combo = new QComboBox(this);
combo->addItems({ "Item0", "Item1", "Item2" });
// Here is the interesting bit
auto model = qobject_cast<QStandardItemModel*>(combo->model());
auto item = model->item(0); // <-- index in the combobox
item->setEnabled(false); // <-- You can't select it anymore
if(combo->currentIndex() == 0) // Choose another one if it's already selected
combo->setCurrentIndex(1);
// From now, Item 0 will be visible in the dropdown but not selectable by the user.
I leave you find a way to get the 2 boxes disabling each other items (And importantly, enabling them back once if the selection change). This is a matter of listening the index changed signals of each boxes and and updating the other model accordingly.
Upvotes: 0
Reputation: 243907
One possible solution is to use QSortFilterProxyModel to do the filtering:
#include <QApplication>
#include <QComboBox>
#include <QHBoxLayout>
#include <QSortFilterProxyModel>
#include <QStandardItemModel>
#include <QWidget>
class FilterProxyModel: public QSortFilterProxyModel{
public:
using QSortFilterProxyModel::QSortFilterProxyModel;
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const{
if(filterRegExp().isEmpty())
return true;
return !QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.resize(640, 480);
widget.show();
QStandardItemModel *model = new QStandardItemModel(&widget);
const QStringList values{"Italiano", "Inglese", "Francese", "Spagnolo", "Portoghese", "Tedesco", "Cinese"};
for(const QString & value: values){
model->appendRow(new QStandardItem(value));
}
QComboBox *lingua_originaleT = new QComboBox;
FilterProxyModel *proxy_originalT = new FilterProxyModel(&widget);
proxy_originalT->setSourceModel(model);
lingua_originaleT->setModel(proxy_originalT);
QComboBox *lingua_targetT = new QComboBox;
FilterProxyModel *proxy_targetT = new FilterProxyModel(&widget);
proxy_targetT->setSourceModel(model);
lingua_targetT->setModel(proxy_targetT);
QHBoxLayout *lay = new QHBoxLayout(&widget);
lay->addWidget(lingua_originaleT);
lay->addWidget(lingua_targetT);
QObject::connect(lingua_originaleT, &QComboBox::currentTextChanged, proxy_targetT, &FilterProxyModel::setFilterFixedString);
QObject::connect(lingua_targetT, &QComboBox::currentTextChanged, proxy_originalT, &FilterProxyModel::setFilterFixedString);
lingua_originaleT->setCurrentIndex(0);
lingua_targetT->setCurrentIndex(1);
return a.exec();
}
Upvotes: 1