C++ 将QTableView与模型一起使用
我有QVectorC++ 将QTableView与模型一起使用,c++,qt,model-view,C++,Qt,Model View,我有QVector汽车,我想根据汽车的注册号进行过滤。我想创建一个新的过滤向量。我不认为这是可以的,因为我迭代了2个向量,从第一个复制到第二个。我这样做对吗 void MainWindow::on_actionBy_registration_number_triggered() { myDialog = new MyDialog(this); myDialog->exec(); QString toSearchString = myDialog->getRe
汽车
,我想根据汽车的注册号进行过滤。我想创建一个新的过滤向量。我不认为这是可以的,因为我迭代了2个向量,从第一个复制到第二个。我这样做对吗
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);
}
void主窗口::on_actionBy_registration_number_triggered()
{
myDialog=新建myDialog(此);
myDialog->exec();
QString-toSearchString=myDialog->getRegistrationNumber();
QVector的建立;
矢量迭代器(cars);
while(iterator.hasNext()){
Vehicle car=迭代器.next();
QString num=car.getRegistration().getRegistrationNumber();
if(num.contains(toSearchString,Qt::CaseSensitive)){
成立。追加(汽车);
}
}
model=新的QStandardItemModel(founded.size(),5,this);
//创建标题
createHeader(模型);
int j=0;//行
国际热核聚变实验堆(成立);
while(iter.hasNext()){
车辆输出=iter.next();
//定置车
QString makeAndModel=output.getGeneralData().getMake()+output.getGeneralData().getModel();
QStandardItem*mAndM=新的QStandardItem(QString(makeAndModel));
模型->设置项(j,0,mAndM);
//集合类型
QStandardItem*type=新的QStandardItem(QString(output.getGeneralData().getType());
模型->设置项(j,1,类型);
//设定里程
QString mileageString=QString::number(output.getGeneralData().getMilege());
QStandardItem*里程=新的QStandardItem(QString(mileageString));
型号->设置项(j,2,里程);
//固定年份
QString yearString=QString::number(output.getGeneralData().getYear());
QStandardItem*year=新的QStandardItem(QString(yearString));
型号->设置项(j,3,年);
//集合注册
QString regString=vehiclehlper::convertBoolToString(output.getRegistration().isRegistered());
QStandardItem*regDate=新的QStandardItem(QString(regString));
模型->设置项(j,4,regDate);
j++;
}
ui->tableView->setModel(模型);
ui->tableView->setEnabled(假);
}
这可以使用代理过滤器模型巧妙地完成。下面是一个在Qt4和Qt5上运行的自包含示例
// 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://github.com/KubaO/stackoverflown/tree/master/questions/filter-18964377
#包括
#如果QT_版本_专业>4
#包括
#恩迪夫
等级车辆{
QString m_品牌、m_型号、m_注册号;
公众:
车辆(常数串和品牌、常数串和型号、常数串和注册号):
m_make{make},m_model{model},m_registrationNumber{registrationNumber}{}
QString make()常量{return m_make;}
QString model()常量{return m_model;}
QString registrationNumber()常量{返回m_registrationNumber;}
bool isRegistered()常量{return!m_registrationNumber.isEmpty();}
};
类别车辆模型:公共QAbstractTableModel{
QList m_数据;
公众:
VehicleModel(QObject*parent={}):QAbstractTableModel{parent}{}
int rowCount(const QModelIndex&)const override{return m_data.count();}
int columnCount(constqmodelindex&)constoverride{return 3;}
QVariant数据(常量QModelIndex&index,int角色)常量覆盖{
if(role!=Qt::DisplayRole&&role!=Qt::EditRole)返回{};
const auto&vehicle=m_数据[index.row()];
开关(index.column()){
案例0:返回车辆。make();
案例1:返回车辆。模型();
案例2:归还车辆。注册号();
默认值:返回{};
};
}
QVariant headerData(int节,Qt::Orientation-Orientation,int-role)常量重写{
if(orientation!=Qt::Horizontal | | role!=Qt::DisplayRole)返回{};
道岔(区段){
案例0:返回“Make”;
案例1:返回“模型”;
案例2:返回“注册号”;
默认值:返回{};
}
}
无效附加(施工车辆和车辆){
beginInsertRows({},m_data.count(),m_data.count());
m_数据附加(车辆);
endInsertRows();
}
};
类Widget:publicqwidget{
QGridLayout m_布局{this};
QTableView m_view;
QPushButton m_按钮{“过滤器”};
车辆模型m_模型;
QSortFilterProxyModel m_代理;
QInputDialog Mu dialog;
公众:
Widget(){
m_layout.addWidget(&m_视图,0,0,1,1);
m_布局.addWidget(&m_按钮,1,0,1,1);
连接(&m_按钮,信号(单击()),&m_对话框,插槽(打开());
m_model.append({“Volvo”、“240”、“SQL8941”});
m_model.append({“Volvo”,“850”,“{}});
m_模型附加({“沃尔沃”、“940”、“QRZ1321”});
m_模型附加({“沃尔沃”、“960”、“QRZ1628”});
m_proxy.setSourceModel(&m_model);
m_proxy.setFilterKeyColumn(2);
m_view.setModel(&m_proxy);
m_dialog.setLabelText(“输入要筛选的注册号片段。保留为空以清除筛选”);
m_dialog.setInputMode(QInputDialog::TextInput);
连接(&m_对话框,信号(textValueSelected(QString)),
&m_代理,SLOT(setFilterFixedString(QString));
}
};
int main(int argc,char*argv[])
{
应用程序a{argc,argv};
小部件w;
w、 show();
返回a.exec();
}
我认为您不应该过早地进行优化。如果您的Vehicle类实现了COW行为,那么一切都正常。唯一建议-您可以使用QList类而不是QVector。在您的情况下,它更具优先性,因为它在数据类型上保留指针,而不是显式值。