2015-06-20 99 views
1

我想编写一个程序,像使用Qt框架的小导航系统一样工作,但我仍然对它很陌生。按字母顺序更新和排序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); 

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

那么有谁在那里,谁能够帮助我?

回答

1

您正在尝试使用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。