问题
I have the QVector cars
that I want to filter basing on the car's registration number. I want to create a new filtered vector. I don't think that this is ok because i'm iterating 2 vectors, copying from the first one to the second one. Am I doing this right?
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);
}
回答1:
This can be done neatly using a proxy filter model. Below is a self-contained example that runs on both Qt 4 and 5.
// 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();
}
来源:https://stackoverflow.com/questions/18964377/using-qtableview-with-a-model