2015-06-20 52 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。