主页 > 互联网  > 

QT(四)模型/视图QFileSystemModel,QStringListModel,QStandardIte

QT(四)模型/视图QFileSystemModel,QStringListModel,QStandardIte
思考:QTableWidget 在某种程度上可以等价为QStandardItemModel,同理,其他的功能也有类似的等价,但是以当前的QTableWidget 和QStandardItemModel为例的话,两者都是用于实现建立表格的相关组件,只不过QStandardItemModel使用更为灵活,可以自定义自己的模型 一 QFileSystemModel,list,view,tree view应用于文件模型

知识点:下列案例是QFileSystemModel文件模型的应用 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QFileSystemModel> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_treeView_clicked(const QModelIndex &index); private: Ui::MainWindow *ui; QFileSystemModel *model; }; #endif // MAINWINDOW_H #include "mainwindow.h" #include "ui_mainwindow.h" #include "QDebug" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建模型 model = new QFileSystemModel; //设置文件系统模型的根目录 //在这指定的目录下安装了一个文件系统监视器,这个目录下的文件信息的改变都会显示在这个模型里面 model->setRootPath(QDir::currentPath()); //关联模型和"视图" ui->treeView->setModel(model); ui->listView->setModel(model); ui->tableView->setModel(model); //list,tree,table是三种view,实现的功能是一样的,只是对当前文件系统的显示方式不一样 //使用信号槽,通知其他视图的即使变化,实现3种view同步变化 connect(ui->treeView,SIGNAL(clicked(QModelIndex)),ui->listView, SLOT(setRootIndex(QModelIndex))); connect(ui->treeView,SIGNAL(clicked(QModelIndex)),ui->tableView, SLOT(setRootIndex(QModelIndex))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_treeView_clicked(const QModelIndex &index) { ui->labelFileName->setText(model->fileName(index)); float size = model->size(index) /1024; //?k qDebug() << "size " << size; if(size >1024){ ui->labelFileSize->setText(QString::asprintf("%.1f MB", size/1024.0)) ; }else { ui->labelFileSize->setText(QString::asprintf("%f kB", size)) ; } ui->labelNodeType->setText(model->type(index)); ui->checkBox->setChecked(model->isDir(index)); ui->labelFilePath->setText(model->filePath(index)); } 二 QStringListModel

知识点:总结来说,模型的使用,包括以下几个步骤:

在.h文件中,定义模型指针 QStringListModel *model;;

在cpp文件的构造函数中,构建模型model= new QStringListModel; ,

构造数据/导入数据, QStringList addrList = {"北京","上海","广州","深圳","贵州","杭州","深圳"}; model->setStringList(addrList);

模型和组件的关联 ui->listView->setModel(model);

数据添加完毕后,让鼠标选中新添加的数据新型显示 ui->listView->setCurrentIndex(index); #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStringListModel> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButtonEndAdd_clicked(); void on_pushButtonInsert_clicked(); void on_pushButtonDelete_clicked(); void on_pushButtonClear_clicked(); void on_pushButtonInit_4_clicked(); void on_pushButtonInit_3_clicked(); void on_pushButtonInit_2_clicked(); private: Ui::MainWindow *ui; QStringListModel *model; }; #endif // MAINWINDOW_H #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); //创建模型 model= new QStringListModel; //构造数据/导入数据 QStringList addrList = {"北京","上海","广州","深圳","贵州","杭州","深圳"}; model->setStringList(addrList); //关联 ui->listView->setModel(model); ui->tableView->setModel(model); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButtonEndAdd_clicked() { //在尾部插入一行 model->insertRow(model->rowCount()); QModelIndex index = model->index(model->rowCount()-1,0); //获取最后一行第0列数据 //设置插入行的数据 model->setData(index,"新的城市"); //数据添加完毕后,让鼠标选中新添加的数据新型显示 ui->listView->setCurrentIndex(index); } void MainWindow::on_pushButtonInsert_clicked() { QModelIndex index = ui->listView->currentIndex(); model->insertRow(index.row()); model->setData(index,"插入新的城市"); ui->listView->setCurrentIndex(index); } void MainWindow::on_pushButtonDelete_clicked() { QModelIndex index = ui->listView->currentIndex(); model->removeRow(index.row()); } void MainWindow::on_pushButtonClear_clicked() { model->removeRows(0,model->rowCount()); } void MainWindow::on_pushButtonInit_4_clicked() { QStringList list = model->stringList(); ui->plainTextEdit->clear(); for(int i = 0; i < list.count(); i++){ ui->plainTextEdit->appendPlainText(list[i]); } } void MainWindow::on_pushButtonInit_3_clicked() { ui->plainTextEdit->clear(); } void MainWindow::on_pushButtonInit_2_clicked() { //构造数据/导入数据 QStringList addrList = {"北京","上海","广州","深圳","贵州","杭州","深圳"}; model->setStringList(addrList); } 三 QStandardItemModel 问题:这种表格和table view之间的差别和联系是什么:是一种存储数据的模型,虽然展现的格式是表格,但是有自己的数据取出和存储方式,table view是一个组件工具知识点:之前的自定义槽函数的命名模式是on_actionBold_triggered,on_信号_槽函数,这样做的前提是,信号是QT组件发出的信号,槽函数可以任意自定义,但是如果信号不是Qt组件发出的信号,而是自定义或者调用的类发出的信号,则最好不要这样命名,on_信号 即可,会导致找不到信号,虽然不会影响程序的正常运行。比如当前案例调用了一个类selectionModel = new QItemSelectionModel(model);,这个类发出信号,点击类名QItemSelectionModel查看相应的信号名,最终实现 根据单元格是否是粗体,要更新粗体图标的状态 的功能。 该案例就是用一个类发出信号,而非组件 // 添加信号槽 void currentChanged(const QModelIndex &current, const QModelIndex &previous); connect(selectionModel, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,SLOT(on_currentChanged(const QModelIndex &, const QModelIndex &)));

最终实现 根据单元格是否是粗体,要更新粗体图标的状态 的功能

// void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous) { if(current.isValid()){ auto item = model->itemFromIndex(current); //根据当前选中单元格的字体是不是粗体来判断图标的变化,如果是粗体,图标状态是选中状态 //反之,不选中 ui->actionBold->setChecked(item->font().bold()); //在状态栏的标签中,显示所选中单元格是第几行第几列 labelinfo->setText(QString::asprintf("当前单元格:%d行,%d列", current.row()+1,current.column()+1) + " 单元格内容 " + item->text()); } }

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStandardItemModel> #include <QItemSelectionModel> #include <QLabel> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_actionOpen_triggered(); void on_actionAdd_triggered(); void on_actionInsert_triggered(); void on_actionDelete_triggered(); void on_actionSee_triggered(); void on_actionSave_triggered(); void on_actionRight_triggered(); void on_actionLeft_triggered(); void on_actionMiddle_triggered(); void on_actionBold_triggered(bool checked); void on_currentChanged(const QModelIndex &current, const QModelIndex &previous); private: Ui::MainWindow *ui; QStandardItemModel *model; QItemSelectionModel *selectionModel; int collumCount; //列数 void initModel(QStringList content); QLabel *labelinfo; }; #endif // MAINWINDOW_H #include "mainwindow.h" #include "ui_mainwindow.h" #include <QFileDialog> #include <QTextStream> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); collumCount = 6; model = new QStandardItemModel(2,collumCount, this); selectionModel = new QItemSelectionModel(model); ui->tableView->setModel(model); ui->tableView->setSelectionModel(selectionModel); //对表数据选择模式,比如选中ctrl+鼠标可以多选 //配置table view的相关属性 //QAbstractItemView::ExtendedSelection:当前模式能实现以下的功能 //单击某选项,以前的选择会被取消 //同时按下ctrl,以前的选项和现在的选项都会保留 //同时按下shift,第一次选中的为左上角,当前选择为右下角的数据都会被选中 ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); //选择单元格 ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems); // 添加信号槽 void currentChanged(const QModelIndex &current, const QModelIndex &previous); connect(selectionModel, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,SLOT(on_currentChanged(const QModelIndex &, const QModelIndex &))); //手动添加标签到状态栏 labelinfo = new QLabel(this); statusBar()->addWidget(labelinfo); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_actionOpen_triggered() { QString filiname = QFileDialog::getOpenFileName(this,"打开一个文件",QCoreApplication::applicationDirPath(), "文本数据文件(*txt);;所有文件(*.*)"); if(filiname.isEmpty()){ return; } QFile qfile(filiname); //指定文件的打开方式,如果打不开,结束 if(!qfile.open(QIODevice::ReadOnly | QIODevice::Text)){ return; } QTextStream stream(&qfile); QStringList fileContent; while(!stream.atEnd()){ QString line = stream.readLine(); fileContent.append(line); //把读到的内容放到右侧的文本编辑器 ui->plainTextEdit->appendPlainText(line); } qfile.close(); //将数据放置到数据模型里面去 initModel(fileContent); } void MainWindow::initModel(QStringList content) { //需要根据数据文本格式来进行切割 QString headline = content[0]; //QRegExp \s 自动匹配1个任意空白字符 //\s+ 自动匹配1个或者多个任意空白字符 // \\ 转移为'\' QStringList headlist = headline.split(QRegExp("\\s+"), QString::SkipEmptyParts); //跳过空格 model->setHorizontalHeaderLabels(headlist); //读取数据 int rows = content.count(); for(int i =1 ;i < rows; i++){ QString line = content[i]; QStringList filedList = line.split(QRegExp("\\s+"), QString::SkipEmptyParts); for(int j =0; j < collumCount-1; j++){ QStandardItem *item = new QStandardItem(filedList[j]); model->setItem(i-1,j,item); } //取最后一列数据,将是打✔,否则维持原状 QStandardItem *item = new QStandardItem(headlist[collumCount-1]); item->setCheckable(true); // 设置为可勾选 if(filedList[collumCount-1] == "否"){ item->setCheckState(Qt::Unchecked); }else{ item->setCheckState(Qt::Checked); } model->setItem(i-1,collumCount-1,item); } } void MainWindow::on_actionAdd_triggered() { QStringList initValue = {"无名","男","市场部","销售","50000","婚否"}; //将数据放入list中 QList <QStandardItem*> itemList; for(int j =0; j < collumCount; j++){ QStandardItem *item = new QStandardItem(initValue[j]); itemList.push_back(item); } itemList[collumCount-1]->setCheckable(true); // 设置为可勾选,最后一列数据是可选框的状态 model->insertRow(model->rowCount(), itemList); //默认在最后一行添加数据 //设置最后一行是被选中的状态 selectionModel->clearSelection(); QModelIndex index = model->index(model->rowCount() -1,0); selectionModel->setCurrentIndex(index,QItemSelectionModel::Rows); } void MainWindow::on_actionInsert_triggered() { QStringList initValue = {"无名","男","市场部","销售","50000","婚否"}; QList <QStandardItem*> itemList; for(int j =0; j < collumCount; j++){ QStandardItem *item = new QStandardItem(initValue[j]); itemList.push_back(item); } itemList[collumCount-1]->setCheckable(true); // 设置为可勾选,最后一列数据是可选框的状态 QModelIndex index = selectionModel->currentIndex(); model->insertRow(index.row(), itemList); //设置最后一行是被选中的状态 selectionModel->clearSelection(); selectionModel->setCurrentIndex(index,QItemSelectionModel::Rows); } void MainWindow::on_actionDelete_triggered() { QModelIndex index = selectionModel->currentIndex(); if(index.row() == model->rowCount()-1){ model->removeRow(index.row()); }else { model->removeRow(index.row()); selectionModel->setCurrentIndex(index,QItemSelectionModel::Select); } } void MainWindow::on_actionSee_triggered() { //把左侧数据模型里面的数据,更新到右侧窗口 ui->plainTextEdit->clear(); //获取表头 QString str; for(int i =0; i<model->columnCount(); i++) { QStandardItem *item = model->horizontalHeaderItem(i); str += item->text() + "\t"; } ui->plainTextEdit->appendPlainText(str); //会自动换行 //获取每一行数据 for(int i =1; i<model->rowCount(); i++) { str = " "; for(int j =0; j<model->columnCount()-1; j++) { QStandardItem *item = model->item(i,j); str += item->text() + "\t"; } if(model->item(i,model->columnCount()-1)->checkState() == Qt::Checked){ str += "是"; }else{ str += "否"; } ui->plainTextEdit->appendPlainText(str); } } void MainWindow::on_actionSave_triggered() { //选择保存文件的储存路径 QString filename = QFileDialog::getSaveFileName(this,"保存文件",QCoreApplication::applicationDirPath()); if(filename.isEmpty()){ return; } QFile qfile(filename); //指定文件的打开方式,如果打不开,结束,QIODevice::Truncate把文件截断为0,避免文件已经存在或者已经有数据了 if(!qfile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)){ qDebug() << "打不开"; return; } QTextStream stream(&qfile); //读表头 QString str; for(int i =0; i<model->columnCount(); i++) { QStandardItem *item = model->horizontalHeaderItem(i); str += item->text() + "\t"; } stream << str << "\n"; //写表头 //获取每一行数据 for(int i =1; i<model->rowCount(); i++) { str = " "; for(int j =0; j<model->columnCount()-1; j++) { QStandardItem *item = model->item(i,j); str += item->text() + "\t"; } if(model->item(i,model->columnCount()-1)->checkState() == Qt::Checked){ str += "是"; }else{ str += "否"; } stream << str << "\n"; //写数据 } qfile.close(); } void MainWindow::on_actionRight_triggered() { //对选择的单元格进行格式设置 //先判断是否有选中单元格 if(!selectionModel->hasSelection()){ return; } QModelIndexList indexlist = selectionModel->selectedIndexes(); for(int i = 0; i < indexlist.count();i++){ auto item = model->itemFromIndex(indexlist[i]); item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); } } void MainWindow::on_actionLeft_triggered() { if(!selectionModel->hasSelection()){ return; } QModelIndexList indexlist = selectionModel->selectedIndexes(); for(int i = 0; i < indexlist.count();i++){ auto item = model->itemFromIndex(indexlist[i]); item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); } } void MainWindow::on_actionMiddle_triggered() { if(!selectionModel->hasSelection()){ return; } QModelIndexList indexlist = selectionModel->selectedIndexes(); for(int i = 0; i < indexlist.count();i++){ auto item = model->itemFromIndex(indexlist[i]); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); } } void MainWindow::on_actionBold_triggered(bool checked) { if(!selectionModel->hasSelection()){ return; } QModelIndexList indexlist = selectionModel->selectedIndexes(); for(int i = 0; i < indexlist.count();i++){ auto item = model->itemFromIndex(indexlist[i]); QFont font = item->font(); font.setBold(checked); item->setFont(font); } } //根据单元格是否是粗体,要更新粗体图标的状态 void MainWindow::on_currentChanged(const QModelIndex &current, const QModelIndex &previous) { if(current.isValid()){ auto item = model->itemFromIndex(current); //根据当前选中单元格的字体是不是粗体来判断图标的变化,如果是粗体,图标状态是选中状态 //反之,不选中 ui->actionBold->setChecked(item->font().bold()); //在状态栏的标签中,显示所选中单元格是第几行第几列 labelinfo->setText(QString::asprintf("当前单元格:%d行,%d列", current.row()+1,current.column()+1) + " 单元格内容 " + item->text()); } } 四 自定义代理 上述三案例,没有设置表的可编辑模式,但是默认是可以编辑的,并且没有限制。但是如果不对输入数据进行限制,用户可能会输入不符合要求的数据,比如在性别后面输入数据。上一个案例可以编辑是因为使用了默认代理,所谓代理就是用于展示数据的一个媒介。因此优化上述案例,就可以通过自定义代理来实现代理的两个作用,显示数据和编辑数据 4.1 自定义薪资代理

4.1.1 新建类文件

4.1.2 编辑类文件 在新建的类.h文件中,添加头文件#include <QStyledItemDelegate>,添加Q_OBJECT让当前类继承于QStyledItemDelegate 类,class QIntSlaryDelegate: public QStyledItemDelegate构造函数修改为有参构造 QIntSlaryDelegate(QObject *parent = 0);点击QStyledItemDelegate,转到类定义,将以下四个函数直接复制到新建类里面,createEditor作用是创建组件,setEditorData:将模型的数据给代理,setModelData:将代理里面的数据给到模型,updateEditorGeometry:设置显示格式设置组件的时候,根据数据需求来选择组件,比如当前的显示的数据是整型数据,要获取能够上下拨动的按钮的功能,对应的组件就是QSpinBox #ifndef QINTSLARYDELEGATE_H #define QINTSLARYDELEGATE_H #include <QStyledItemDelegate> class QIntSlaryDelegate: public QStyledItemDelegate { Q_OBJECT public: QIntSlaryDelegate(QObject *parent = 0); // editing QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setEditorData(QWidget *editor, const QModelIndex &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; #endif // QINTSLARYDELEGATE_H #include "qintslarydelegate.h" #include <QSpinBox> #include <QDebug> QIntSlaryDelegate::QIntSlaryDelegate(QObject *parent):QStyledItemDelegate(parent) { } //创建代理组件的时候,调用这个虚函数 QWidget *QIntSlaryDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option); Q_UNUSED(index); //QSpinBox只能输入证整数,右侧有上下两个可调箭头的框 QSpinBox *eidtor = new QSpinBox(parent); eidtor->setMinimum(2000); eidtor->setMaximum(100000); eidtor->setSingleStep(100); return eidtor; } //将模型的数据给代理 void QIntSlaryDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { //从数据模型获取数据 int value = index.model()->data(index).toInt(); QSpinBox *spinbox = static_cast<QSpinBox*>(editor); //获取代理组件,并转换成相应的组件类型 spinbox->setValue(value); } //将代理里面的数(可能已经修改)据,给到模型 void QIntSlaryDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QSpinBox *spinbox = static_cast<QSpinBox*>(editor); spinbox->interpretText(); //解释数据, 输入的都是文本,这要要的是整数 int value = spinbox->value(); model->setData(index,value); } void QIntSlaryDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index); editor->setGeometry(option.rect); //设置代理的大小就是原本的模型数据的小大 } 4.1.3 编辑mainwindow对应文件 在mainwindow.h文件中,包含新建类的头文件#include "qintslarydelegate.h",在private下,定义 QIntSlaryDelegate intSalaryDelegate;在mainwindow.cpp文件中,构造函数里面指定代理, ui->tableView->setItemDelegateForColumn(4,&intSalaryDelegate); #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStandardItemModel> #include <QItemSelectionModel> #include <QLabel> #include "qintslarydelegate.h" #include "qfloatdelegate.h" #include "qcomboxdelegate.h" #include "qdatedelegate.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_actionOpen_triggered(); void on_actionAdd_triggered(); void on_actionInsert_triggered(); void on_actionDelete_triggered(); void on_actionSee_triggered(); void on_actionSave_triggered(); void on_actionRight_triggered(); void on_actionLeft_triggered(); void on_actionMiddle_triggered(); void on_actionBold_triggered(bool checked); void on_currentChanged(const QModelIndex &current, const QModelIndex &previous); private: Ui::MainWindow *ui; QStandardItemModel *model; QItemSelectionModel *selectionModel; int collumCount; //列数 void initModel(QStringList content); QLabel *labelinfo; QIntSlaryDelegate intSalaryDelegate; QFloatDelegate floatDelegate; QComboxDelegate jobDelagete; QComboxDelegate genderDelegate; QDateDelegate dataDelegate; }; #endif // MAINWINDOW_H MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); 。。。。。 。。。。。 。。。。。 //指定代理 ui->tableView->setItemDelegateForColumn(4,&intSalaryDelegate); ui->tableView->setItemDelegateForColumn(5,&floatDelegate); jobDelagete.setItemList(QStringList{"软件工程师","硬件工程师","经理","助理"}); ui->tableView->setItemDelegateForColumn(3,&jobDelagete); genderDelegate.setItemList(QStringList{"男","女"}); ui->tableView->setItemDelegateForColumn(1,&genderDelegate); ui->tableView->setItemDelegateForColumn(2,&dataDelegate); } 4.2 自定义绩效系数代理 和4.1的区别就只在于组件类型不同,用的组件是QDoubleSpinBox

类文件的.cpp文件 #include "qfloatdelegate.h" #include <QDoubleSpinBox> QFloatDelegate::QFloatDelegate(QObject *parent):QStyledItemDelegate(parent) { } QFloatDelegate::QFloatDelegate(){ } QWidget *QFloatDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option); Q_UNUSED(index); QDoubleSpinBox *editor = new QDoubleSpinBox(parent); editor->setFrame(false); editor->setMinimum(0); editor->setMaximum(5); editor->setSingleStep(0.1); return editor; } void QFloatDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { float value = index.model()->data(index).toFloat(); QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox*>(editor); spinbox->setValue(value); } void QFloatDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QDoubleSpinBox *spinbox = static_cast<QDoubleSpinBox*>(editor); spinbox->interpretText(); float value = spinbox->value(); QString str = QString::asprintf("%.1f", value); model->setData(index,str); } void QFloatDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index); editor->setGeometry(option.rect); //设置代理的大小就是原本的模型数据的小大 } 4.3 自定义多选框岗位和性别代理,一个代理对应两个变量 知识点:当前案例和上述有所不同,一个代理对应了两个变量,createEditor函数中的定义有所不同,使用的是addItems而不是addItem,添加的是QStringList, QWidget *QComboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QComboBox *editor = new QComboBox(parent); editor->addItems(itemList); return editor; }

并设计了一个类的对外的接口,以便在调用的时候来完成itemList的值的设置,因此在mianwindow.cpp构造函数中指定代理前,需要调用该接口来指定QStringList里面的值

jobDelagete.setItemList(QStringList{"软件工程师","硬件工程师","经理","助理"}); ui->tableView->setItemDelegateForColumn(3,&jobDelagete); genderDelegate.setItemList(QStringList{"男","女"}); ui->tableView->setItemDelegateForColumn(1,&genderDelegate);

#ifndef QCOMBOXDELEGATE_H #define QCOMBOXDELEGATE_H #include <QStyledItemDelegate> class QComboxDelegate: public QStyledItemDelegate { Q_OBJECT public: QComboxDelegate(QObject *parent = 0); // editing QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setEditorData(QWidget *editor, const QModelIndex &index) const override; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; void setItemList(const QStringList &list); private: QStringList itemList; }; #endif // QCOMBOXDELEGATE_H #include "qcomboxdelegate.h" #include <QComboBox> QComboxDelegate::QComboxDelegate(QObject *parent):QStyledItemDelegate(parent) {} QWidget *QComboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { QComboBox *editor = new QComboBox(parent); editor->addItems(itemList); return editor; } //从数据模型取数据,给代理组件 void QComboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QString value = index.model()->data(index).toString(); QComboBox *comboBox = static_cast<QComboBox*>(editor); comboBox->setCurrentText(value); } void QComboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *comboBox = static_cast<QComboBox*>(editor); QString str = comboBox->currentText(); model->setData(index,str); } void QComboxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index); editor->setGeometry(option.rect); //设置代理的大小就是原本的模型数据的小大 } void QComboxDelegate::setItemList(const QStringList &list) { itemList = list; }
标签:

QT(四)模型/视图QFileSystemModel,QStringListModel,QStandardIte由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“QT(四)模型/视图QFileSystemModel,QStringListModel,QStandardIte