2013-09-23 2 views
4

나는 QVector cars을 차의 등록 번호를 기준으로 필터링하려고합니다. 새로운 필터링 된 벡터를 만들고 싶습니다. 저는 두 벡터를 반복하고 있기 때문에 이것은 괜찮다고 생각하지 않습니다. 첫 번째 벡터에서 두 번째 벡터로 복사하기 때문입니다. 이 일을 제대로하고 있습니까?QTableView를 모델로 사용하기

void MainWindow::on_actionBy_registration_number_triggered() 
{ 
    myDialog = new MyDialog(this); 
    myDialog->exec(); 

    QString toSearchString = myDialog->getRegistrationNumber(); 
    QVector<Vehicle> founded; 
    QVectorIterator<Vehicle> iterator(cars); 
    while(iterator.hasNext()){ 
     Vehicle car = iterator.next(); 
     QString num = car.getRegistration().getRegistrationNumber(); 
     if(num.contains(toSearchString,Qt::CaseInsensitive)){ 
      founded.append(car); 
     } 
    } 
    model = new QStandardItemModel(founded.size(),5,this); 

    //create header 
    createHeader(model); 

    int j = 0; //row 
    QVectorIterator<Vehicle> iter(founded); 
    while(iter.hasNext()){ 
     Vehicle output = iter.next(); 
     //set car 
     QString makeAndModel = output.getGeneralData().getMake() + output.getGeneralData().getModel(); 
     QStandardItem *mAndM = new QStandardItem(QString(makeAndModel)); 
     model->setItem(j,0,mAndM); 

     //set type 
     QStandardItem *type = new QStandardItem(QString(output.getGeneralData().getType())); 
     model->setItem(j,1,type); 

     //set mileage 
     QString mileageString = QString::number(output.getGeneralData().getMileage()); 
     QStandardItem *mileage = new QStandardItem(QString(mileageString)); 
     model->setItem(j,2,mileage); 

     //set year 
     QString yearString = QString::number(output.getGeneralData().getYear()); 
     QStandardItem *year = new QStandardItem(QString(yearString)); 
     model->setItem(j,3,year); 


     //set registration 
     QString regString = VehicleHelper::convertBoolToString(output.getRegistration().isRegistered()); 
     QStandardItem *regDate = new QStandardItem(QString(regString)); 
     model->setItem(j,4,regDate); 
     j++; 
    } 

    ui->tableView->setModel(model); 
    ui->tableView->setEnabled(false); 
} 
+0

당신이 조기 최적화를하지 말아야 할 생각입니다. Vehice 클래스가 COW 동작을 구현하면 모두 OK입니다. 제안 만 - QVector 대신 QList 클래스를 사용할 수 있습니다. 그것은 명시 적 값 대신 데이터 유형에 대한 포인터를 유지하기 때문에 귀하의 경우에 더 유용합니다. –

답변

7

프록시 필터 모델을 사용하여 깔끔하게 수행 할 수 있습니다. 다음은 자체에 포함 된 두 Qt는 4에서 실행 예를 들어, 5

screenshot

// https://github.com/KubaO/stackoverflown/tree/master/questions/filter-18964377 
#include <QtGui> 
#if QT_VERSION_MAJOR > 4 
#include <QtWidgets> 
#endif 

class Vehicle { 
    QString m_make, m_model, m_registrationNumber; 
public: 
    Vehicle(const QString & make, const QString & model, const QString & registrationNumber) : 
     m_make{make}, m_model{model}, m_registrationNumber{registrationNumber} {} 
    QString make() const { return m_make; } 
    QString model() const { return m_model; } 
    QString registrationNumber() const { return m_registrationNumber; } 
    bool isRegistered() const { return !m_registrationNumber.isEmpty(); } 
}; 

class VehicleModel : public QAbstractTableModel { 
    QList<Vehicle> m_data; 
public: 
    VehicleModel(QObject * parent = {}) : QAbstractTableModel{parent} {} 
    int rowCount(const QModelIndex &) const override { return m_data.count(); } 
    int columnCount(const QModelIndex &) const override { return 3; } 
    QVariant data(const QModelIndex &index, int role) const override { 
     if (role != Qt::DisplayRole && role != Qt::EditRole) return {}; 
     const auto & vehicle = m_data[index.row()]; 
     switch (index.column()) { 
     case 0: return vehicle.make(); 
     case 1: return vehicle.model(); 
     case 2: return vehicle.registrationNumber(); 
     default: return {}; 
     }; 
    } 
    QVariant headerData(int section, Qt::Orientation orientation, int role) const override { 
     if (orientation != Qt::Horizontal || role != Qt::DisplayRole) return {}; 
     switch (section) { 
     case 0: return "Make"; 
     case 1: return "Model"; 
     case 2: return "Reg.#"; 
     default: return {}; 
     } 
    } 
    void append(const Vehicle & vehicle) { 
     beginInsertRows({}, m_data.count(), m_data.count()); 
     m_data.append(vehicle); 
     endInsertRows(); 
    } 
}; 

class Widget : public QWidget { 
    QGridLayout m_layout{this}; 
    QTableView m_view; 
    QPushButton m_button{"Filter"}; 
    VehicleModel m_model; 
    QSortFilterProxyModel m_proxy; 
    QInputDialog m_dialog; 
public: 
    Widget() { 
     m_layout.addWidget(&m_view, 0, 0, 1, 1); 
     m_layout.addWidget(&m_button, 1, 0, 1, 1); 
     connect(&m_button, SIGNAL(clicked()), &m_dialog, SLOT(open())); 
     m_model.append({"Volvo", "240", "SQL8941"}); 
     m_model.append({"Volvo", "850", {}}); 
     m_model.append({"Volvo", "940", "QRZ1321"}); 
     m_model.append({"Volvo", "960", "QRZ1628"}); 
     m_proxy.setSourceModel(&m_model); 
     m_proxy.setFilterKeyColumn(2); 
     m_view.setModel(&m_proxy); 
     m_dialog.setLabelText("Enter registration number fragment to filter on. Leave empty to clear filter."); 
     m_dialog.setInputMode(QInputDialog::TextInput); 
     connect(&m_dialog, SIGNAL(textValueSelected(QString)), 
       &m_proxy, SLOT(setFilterFixedString(QString))); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a{argc, argv}; 
    Widget w; 
    w.show(); 
    return a.exec(); 
}