按字母顺序更新和排序Qt ComboBoxes

时间:2015-06-20 17:34:46

标签: c++ qt sorting combobox

我想编写一个程序,就像使用Qt框架的一个小导航系统一样,但我仍然很新。

我创建了一个包含两个Comboboxes的对话框。每个组合框包含所有"城市名称"。 在初始化时,两个框的内容按字母顺序排序。

如果第一个框中的名称被选中,则不应该在第二个框中显示,也不应该在第二个框中显示。

我成功删除了该项目并再次添加,如果选择了其他项目,但我知道我不能再对它们进行排序

这是我到目前为止尝试更新的内容:

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);

但是,如果我尝试调用此函数,则会发生错误并且应用程序终止。

那里有人能帮助我吗?

2 个答案:

答案 0 :(得分:2)

您尝试将QComboBox的内部模型用作proxy的源模型。这不起作用,因为QComboBox拥有其内部模型,当您调用QComboBox::setModel时,先前的模型将被删除(尽管您重置了其父模型)。您需要创建单独的源模型。方便的是,如果城市列表相同,则可以为两个组合框使用一个源模型。

使用QSortFilterProxyModel进行排序很容易,但要用它排除一个特定的字符串会非常困难。您可以继承QSortFilterProxyModel::filterAcceptsRow并实现所需的行为。我决定使用一些黑魔法(见this answer)。

私人类字段:

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中测试。

答案 1 :(得分:1)

你快到了!

ui.comboBox1.addItem("myitem");
// qApp->processEvents();  not really needed
ui.comboBox1.model()->sort(0);