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

  • 思考: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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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; //?kqDebug() << "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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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);// editingQWidget *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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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);// editingQWidget *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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70087.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity热更新方案HybridCLR+YooAsset,从零开始,保姆级教程,纯c#开发热更

文章目录&#xff1a; 一、前言二、创建空工程三、接入HybridCLR四、接入YooAsset五、搭建本地资源服务器Nginx六、实战七、最后八、后记 一、前言 unity热更有很多方案&#xff0c;各种lua热更&#xff0c;ILRuntime等&#xff0c;这里介绍的是YooAssetHybridCLR的热更方案&a…

Zabbix——监控Windows下某个文件夹的所有文件变化

获取所有的指定路径下的文件列表 以D:\Apps这个文件夹下的所有文件为例&#xff0c;我需要找到这个文件夹里面的子文件夹中的所有文件&#xff0c;但是排除backup这个文件夹&#xff0c;下面我们来看怎么操作 在scripts目录下创建check_file_in_D_Apps.ps1文件&#xff0c;内容…

C++ Primer 函数匹配

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

java八股文-mysql

1. 索引 1.1 什么是索引 索引(index)是帮助Mysql高效获取数据的数据结构(有序).提高数据的检索效率,降低数据库的IO成本(不需要全表扫描).通过索引列对数据进行排序,降低数据排序成本,降低了CPU的消耗. 1.2 mysql索引使用的B树? 1. 没有使用二叉树&#xff0c;最坏情况o&…

Docker拉不下来镜像问题解决法案

打开docker的设置界面 配置如下&#xff1a; vi /etc/docker/daemon.json {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"registry-mirrors": ["…

春招项目=图床+ k8s 控制台(唬人专用)

1. 春招伊始 马上要春招了&#xff0c;一个大气的项目&#xff08;冲击波项目&#xff09;直观重要&#xff0c;虽然大家都说基础很重要&#xff0c;但是一个足够新颖的项目完全可以把你的简历添加一个足够闪亮的点。 这就不得不推荐下我的 k8s 图床了&#xff0c;去年折腾快…

wordpress主题插件开发中高频使用的38个函数

核心模板函数 get_header()/get_footer()/get_sidebar() – 加载模板部件 the_title()/the_content()/the_excerpt() – 显示文章标题、内容、摘要 the_post() – 循环中获取文章数据 bloginfo(‘url’) – 获取站点URL wp_head()/wp_footer() – 输出头部/尾部代码 wp_n…

vue点击左边导航,右边出现页面步骤

vue点击左边导航&#xff0c;右边出现页面 步骤 一定要import不然会出错 index.js Course作为Homeview子路由 Homeview加入<Routerview> 点击跳转<RouterLink to> 父Homeview中有RouterView&#xff08;路由出口&#xff0c;跳转至相应路径&#xff09;和Router…

阿里云视频点播,基于thinkphp8上传视频

前端参考官方示例(jQuery版) <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>阿里云 JavaScript上传SDK Demo (使用jquery)</title><script src"__STATIC__/jquery.min.js"></script><sc…

力扣 66.加一 (Java实现)

题目分析 给定一个数组&#xff0c;可以组成一个数字&#xff0c;将数字加一后&#xff0c;返回新数组 思路分析 首先跟着题目思路走&#xff0c;将数组按位*10可以得到数字&#xff0c;再加一&#xff0c;加一后按位%10&#xff0c;可以得到新的数组。但是此处数字会过大&…

[特殊字符] 用Rust重塑Web开发速度极限:Hyperlane框架——开启高性能服务的「光年时代」[特殊字符]

&#x1f525; 每秒百万级请求&#xff1f;Rust超新星Hyperlane框架让Web开发突破性能次元壁&#xff01;&#x1f525; &#x1f31f; 颠覆性技术亮点&#xff1a;为何全球顶尖工程师正疯狂迁移至Hyperlane&#xff1f; ⚡️ 「速度即正义」&#xff1a;重新定义Web性能天花…

DeepSeek与ChatGPT:AI语言模型的全面对决

DeepSeek与ChatGPT&#xff1a;AI语言模型的全面对决 引言&#xff1a;AI 语言模型的时代浪潮一、认识 DeepSeek 与 ChatGPT&#xff08;一&#xff09;DeepSeek&#xff1a;国产新星的崛起&#xff08;二&#xff09;ChatGPT&#xff1a;AI 界的开拓者 二、DeepSeek 与 ChatGP…

visutal studio 2022使用qcustomplot基础教程

编译 下载&#xff0c;2.1.1版支持到Qt6.4 。 拷贝qcustomplot.h和qcustomplot.cpp到项目源目录&#xff08;Qt project&#xff09;。 在msvc中将它俩加入项目中。 使用Qt6.8&#xff0c;需要修改两处代码&#xff1a; L6779 # if QT_VERSION > QT_VERSION_CHECK(5, 2, …

联想笔记本电脑摄像头灯亮,但没有画面怎么解决,

联想小新电脑&#xff0c;遇到电脑黑屏。 解决方法&#xff0c;搜索打开任务管理器 打开联想管家的路径 打开BatterySetting.exe 程序 然后右下角会弹出一个东西&#xff0c;关闭这个摄像头的隐私模式。就可以打开了 就可以了

蓝桥杯单片机大模板(西风)

#include <REGX52.H> #include "Key.h" #include "Seg.h" //变量声明区 unsigned char Key_Val,Key_Down,Key_Old;//按键扫描专用变量 unsigned char Key_Slow_Down;//按键减速专用变量 10ms unsigned int Seg_Slow_Down;//按键扫描专用变量 500ms …

ubuntu服务器 如何配置安全加固措施

下面提供一个更详细、一步步的服务器安全加固指南&#xff0c;适合新手操作。我们将从 Fail2Ban、SSH&#xff08;密钥认证及端口更改&#xff09;、Nginx 速率限制和日志轮转四个方面进行优化&#xff0c;同时补充一些额外的安全建议。 新的服务器&#xff0c;通常我们会创建一…

ESP32通过MQTT连接阿里云平台实现消息发布与订阅

文章目录 前言 一、准备工作 二、阿里云平台配置 三、代码实现 总结 前言 本文将介绍如何使用ESP32开发板通过MQTT协议连接阿里云物联网平台&#xff0c;并实现消息的发布与订阅功能。我们将使用Arduino IDE进行开发&#xff0c;并借助PubSubClient库实现MQTT通信。 一、准备…

Ubuntu下载安装Docker-Desktop

下载 Ubuntu | Docker Docs 预备工作 Ubuntu增加docker apt库-CSDN博客 安装 sudo apt-get updatesudo apt install gnome-terminal# sudo apt install -y docker-composesudo apt-get install ./docker-desktop-amd64.deb 测试 sudo docker run hello-worldHello from D…

Python爬虫实战:获取笔趣阁图书信息,并做数据分析

注意:以下内容仅供技术研究,请遵守目标网站的robots.txt规定,控制请求频率避免对目标服务器造成过大压力! 1. 环境准备与反爬策略 python import requests from bs4 import BeautifulSoup import pandas as pd import re import time import random from fake_useragent …

前端实现防抖功能的详细解读

在前端开发中&#xff0c;防抖&#xff08;Debounce&#xff09; 是一种优化技术&#xff0c;用于限制某个函数在短时间内被频繁调用的次数。它的核心思想是&#xff1a;在一定时间内&#xff0c;无论触发多少次事件&#xff0c;只执行最后一次操作。防抖通常用于处理用户输入、…