按字母顺序更新和排序 Qt ComboBoxes
Update and sort Qt ComboBoxes alphabetically
我想写一个程序,像使用 Qt 框架的小导航系统一样工作,但我对它还是很陌生。
我创建了一个带有两个组合框的对话框。每个组合框包含所有 "citynames"。
在初始化时,两个框的内容按字母顺序排序。
如果第一个框中的名称被选中,则不应在第二个框中显示,反之亦然。
我成功删除了该项目并再次添加了它,如果选择了另一个项目,但我知道我无法再对它们进行排序
这是我到目前为止尝试更新的内容:
for(std::vector<City>::iterator iter = citylist.begin(); iter != citylist.end(); iter++){
if(ui->combo2->currentText() != (*iter).getName()
and ui->combo1->findText((*iter).getName()) == -1){
ui->combo1->addItem((*iter).getName(),QComboBox::InsertAlphabetically);
}
}
但它不会按字母顺序插入项目...
所以我之后尝试对其进行排序:
QSortFilterProxyModel* proxy = new QSortFilterProxyModel(ui->combo1);
proxy->setSourceModel(ui->combo1->model());
// combo's current model must be reparented,
// otherwise QComboBox::setModel() will delete it
ui->combo1->model()->setParent(proxy);
ui->combo1->setModel(proxy);
// sort
ui->combo1->model()->sort(0);
但是如果我尝试调用此函数,则会发生错误并且应用程序会终止。
所以有人能帮助我吗?
您正在尝试使用 QComboBox
的内部模型作为 proxy
的源模型。这不会起作用,因为 QComboBox
拥有其内部模型,并且当您调用 QComboBox::setModel
时,先前的模型将被删除(尽管您重置了其父模型)。您需要创建一个单独的源模型。如果城市列表相同,您可以方便地为两个组合框使用一个源模型。
使用 QSortFilterProxyModel
进行排序很容易,但要用它排除一个特定的字符串却出奇地困难。您可以 subclass QSortFilterProxyModel::filterAcceptsRow
并实现您想要的行为。我决定改用一些黑魔法(参见 this answer)。
私有 class 字段:
private:
QSortFilterProxyModel *proxy1, *proxy2;
来源:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStandardItemModel* model = new QStandardItemModel(this);
foreach(QString name, QStringList()
<< "Paris"<< "London"<< "Moscow" << "Tokyo" << "Berlin" << "Amsterdam") {
model->appendRow(new QStandardItem(name));
}
proxy1 = new QSortFilterProxyModel();
proxy1->setSourceModel(model);
proxy1->sort(0);
ui->comboBox1->setModel(proxy1);
proxy2 = new QSortFilterProxyModel();
proxy2->setSourceModel(model);
proxy2->sort(0);
ui->comboBox2->setModel(proxy2);
connect(ui->comboBox1, &QComboBox::currentTextChanged,
this, &MainWindow::something_changed);
connect(ui->comboBox2, &QComboBox::currentTextChanged,
this, &MainWindow::something_changed);
something_changed();
}
void MainWindow::something_changed() {
ui->comboBox1->blockSignals(true); //prevent recursion
ui->comboBox2->blockSignals(true);
proxy2->setFilterRegExp(QString("^(?!(%1)$)").arg(
QRegExp::escape(ui->comboBox1->currentText())));
proxy1->setFilterRegExp(QString("^(?!(%1)$)").arg(
QRegExp::escape(ui->comboBox2->currentText())));
ui->comboBox1->blockSignals(false);
ui->comboBox2->blockSignals(false);
}
在 Qt 5.3 中测试。
你快到了!
ui->comboBox1.addItem("myitem");
// qApp->processEvents(); not really needed
ui->comboBox1.model()->sort(0);
我想写一个程序,像使用 Qt 框架的小导航系统一样工作,但我对它还是很陌生。
我创建了一个带有两个组合框的对话框。每个组合框包含所有 "citynames"。 在初始化时,两个框的内容按字母顺序排序。
如果第一个框中的名称被选中,则不应在第二个框中显示,反之亦然。
我成功删除了该项目并再次添加了它,如果选择了另一个项目,但我知道我无法再对它们进行排序
这是我到目前为止尝试更新的内容:
for(std::vector<City>::iterator iter = citylist.begin(); iter != citylist.end(); iter++){
if(ui->combo2->currentText() != (*iter).getName()
and ui->combo1->findText((*iter).getName()) == -1){
ui->combo1->addItem((*iter).getName(),QComboBox::InsertAlphabetically);
}
}
但它不会按字母顺序插入项目...
所以我之后尝试对其进行排序:
QSortFilterProxyModel* proxy = new QSortFilterProxyModel(ui->combo1);
proxy->setSourceModel(ui->combo1->model());
// combo's current model must be reparented,
// otherwise QComboBox::setModel() will delete it
ui->combo1->model()->setParent(proxy);
ui->combo1->setModel(proxy);
// sort
ui->combo1->model()->sort(0);
但是如果我尝试调用此函数,则会发生错误并且应用程序会终止。
所以有人能帮助我吗?
您正在尝试使用 QComboBox
的内部模型作为 proxy
的源模型。这不会起作用,因为 QComboBox
拥有其内部模型,并且当您调用 QComboBox::setModel
时,先前的模型将被删除(尽管您重置了其父模型)。您需要创建一个单独的源模型。如果城市列表相同,您可以方便地为两个组合框使用一个源模型。
使用 QSortFilterProxyModel
进行排序很容易,但要用它排除一个特定的字符串却出奇地困难。您可以 subclass QSortFilterProxyModel::filterAcceptsRow
并实现您想要的行为。我决定改用一些黑魔法(参见 this answer)。
私有 class 字段:
private:
QSortFilterProxyModel *proxy1, *proxy2;
来源:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStandardItemModel* model = new QStandardItemModel(this);
foreach(QString name, QStringList()
<< "Paris"<< "London"<< "Moscow" << "Tokyo" << "Berlin" << "Amsterdam") {
model->appendRow(new QStandardItem(name));
}
proxy1 = new QSortFilterProxyModel();
proxy1->setSourceModel(model);
proxy1->sort(0);
ui->comboBox1->setModel(proxy1);
proxy2 = new QSortFilterProxyModel();
proxy2->setSourceModel(model);
proxy2->sort(0);
ui->comboBox2->setModel(proxy2);
connect(ui->comboBox1, &QComboBox::currentTextChanged,
this, &MainWindow::something_changed);
connect(ui->comboBox2, &QComboBox::currentTextChanged,
this, &MainWindow::something_changed);
something_changed();
}
void MainWindow::something_changed() {
ui->comboBox1->blockSignals(true); //prevent recursion
ui->comboBox2->blockSignals(true);
proxy2->setFilterRegExp(QString("^(?!(%1)$)").arg(
QRegExp::escape(ui->comboBox1->currentText())));
proxy1->setFilterRegExp(QString("^(?!(%1)$)").arg(
QRegExp::escape(ui->comboBox2->currentText())));
ui->comboBox1->blockSignals(false);
ui->comboBox2->blockSignals(false);
}
在 Qt 5.3 中测试。
你快到了!
ui->comboBox1.addItem("myitem");
// qApp->processEvents(); not really needed
ui->comboBox1.model()->sort(0);