对模型使用QTableView [英] Using QTableView with a model

查看:175
本文介绍了对模型使用QTableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有QVector cars ,我想根据汽车的注册号过滤。我想创建一个新的过滤矢量。我不认为这是确定,因为我迭代2向量,从第一个复制到第二个。我这样做吗?

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


推荐答案

这可以使用代理过滤器模型。下面是一个在Qt 4和5上运行的自包含示例。

This can be done neatly using a proxy filter model. Below is a self-contained example that runs on both Qt 4 and 5.

#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 = nullptr) : 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 QVariant{};
      const Vehicle & 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{};
      };
   }
   QVariant headerData(int section, Qt::Orientation orientation, int role) const override {
      if (orientation != Qt::Horizontal) return QVariant{};
      if (role != Qt::DisplayRole) return QVariant{};
      switch (section) {
      case 0: return "Make";
      case 1: return "Model";
      case 2: return "Reg.#";
      default: return QVariant{};
      }
   }
   void append(const Vehicle & vehicle) {
      beginInsertRows(QModelIndex{}, 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(Vehicle{"Volvo", "240", "SQL8941"});
      m_model.append(Vehicle{"Volvo", "850", QString{}});
      m_model.append(Vehicle{"Volvo", "940", "QRZ1321"});
      m_model.append(Vehicle{"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();
}

这篇关于对模型使用QTableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆