当前位置: 首页 > news >正文

QT6(QStandardItemModel和QTableView及自定义代理)

QT6


QStandardItemModel和QTableView

  • QStandardItemModel:jag:基于项的模型类在,每个项是一个QStandarditem对象
  • QtableView:显示二维数据的组件
  • QItemSelectionModel:选择模型,用于跟踪视图组件的单元格选择状态,通过它可以获得选中单元格的模型索引,设置选择状态

QTableView常用方法和属性

外观属性

属性/方法名类型/返回值说明
showGridbool是否显示网格线
gridStyleQt::PenStyle网格线样式(如 Qt::SolidLine, Qt::DotLine
alternatingRowColorsbool是否使用交替行颜色

表头控制

属性/方法名类型/返回值说明
horizontalHeader()QHeaderView*获取水平表头对象
verticalHeader()QHeaderView*获取垂直表头对象
horizontalHeaderVisiblebool水平表头是否可见
verticalHeaderVisiblebool垂直表头是否可见

选择行为

属性/方法名类型/返回值说明
selectionBehaviorQAbstractItemView::SelectionBehavior选择行为(选择项、行或列)
selectionModeQAbstractItemView::SelectionMode选择模式(如单选、多选)

编辑特性

属性/方法名类型/返回值说明
editTriggersQAbstractItemView::EditTriggers编辑触发器(如双击编辑)

排序功能

属性/方法名类型/返回值说明
sortingEnabledbool是否启用排序

调整尺寸

属性/方法名类型/返回值说明
resizeColumnToContents(int)void调整某列宽度以适应内容
resizeColumnsToContents()void调整所有列宽度以适应内容
resizeRowToContents(int)void调整某行高度以适应内容
resizeRowsToContents()void调整所有行高度以适应内容

模型操作

属性/方法名类型/返回值说明
setModel(QAbstractItemModel*)void设置数据模型
model()QAbstractItemModel*获取当前数据模型

交互相关

属性/方法名类型/返回值说明
setIndexWidget(const QModelIndex &, QWidget*)void在指定索引处设置部件

代码测试

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QLabel>
#include <QStandardItemModel>
#include <QItemSelectionModel>
#include <QFileDialog>
#include <QFile>
#include <QRegularExpression>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);labCurrFile = new QLabel("当前文件",this);labCurrFile->setMinimumWidth(200);labCellpos = new QLabel("当前单元格",this);labCurrFile->setMinimumWidth(200);labCellText = new QLabel("单元格内容",this);labCellText->setMinimumWidth(200);ui->statusbar->addWidget(labCurrFile);ui->statusbar->addWidget(labCellpos);ui->statusbar->addWidget(labCellText);m_model = new QStandardItemModel(2,FixedColumCount,this);m_selection = new QItemSelectionModel(m_model,this);ui->tableView->setModel(m_model);ui->tableView->setSelectionModel(m_selection);ui->tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);ui->tableView->setSelectionBehavior(QAbstractItemView::SelectItems);connect(m_selection,&QItemSelectionModel::currentChanged,this,&MainWindow::do_currentChanged);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::do_currentChanged(const QModelIndex &current, const QModelIndex &prevous)
{if(current.isValid()){labCellpos->setText(QString::asprintf("当前单元格:%d行,%d列",current.row(),current.column()));QStandardItem* aItem = m_model->itemFromIndex(current);labCellText->setText("单元格内容:"+ aItem->text());// 判断当前选择的item是否为粗体ui->actionBold->setChecked(aItem->font().bold());}
}void MainWindow::on_actionOpenFile_triggered()
{QString curPath = QCoreApplication::applicationFilePath();QString aFileName = QFileDialog::getOpenFileName(this,"打开一个文件",curPath,"数据文件(*.txt);;所有文件(*.*)");if(aFileName.isEmpty())return;QFile aFile(aFileName);if(!aFile.open(QIODevice::ReadOnly|QIODevice::Text))return;QStringList aFileContent;ui->plainTextEdit->clear();QTextStream aStream(&aFile);while(!aStream.atEnd()){QString str = aStream.readLine();ui->plainTextEdit->appendPlainText(str);aFileContent.append(str);}aFile.close();labCurrFile->setText("当前文件" + aFileName);ui->actionAddLine->setEnabled(true);ui->actionInsertLine->setEnabled(true);ui->actionDelLine->setEnabled(true);iniModelData(aFileContent);
}void MainWindow::iniModelData(QStringList& aFileContext)
{int rowCnt = aFileContext.size();m_model->setRowCount(rowCnt - 1);QString header = aFileContext.at(0);QStandardItem *aItem;int j;// 获取表头QStringList headerList = header.split(QRegularExpression(R"(\s)"),Qt::SkipEmptyParts);// 设置表头m_model->setHorizontalHeaderLabels(headerList);for(int i = 0; i < rowCnt ; i++){QString aLineText = aFileContext.at(i);QStringList tempList = aLineText.split(QRegularExpression(R"(\s)"),Qt::SkipEmptyParts);for(j = 0 ; j < FixedColumCount -1 ; ++j){aItem = new QStandardItem(tempList.at(j));// 设置每一项m_model->setItem(i-1,j,aItem);}// 设置最后一项aItem = new QStandardItem(headerList.at(j));aItem->setCheckable(true);aItem->setBackground(QBrush(Qt::yellow));if(tempList.at(j) == "0")aItem->setCheckState(Qt::Unchecked);elseaItem->setCheckState(Qt::Checked);m_model->setItem(i-1,j,aItem);}
}void MainWindow::on_actionDataPreview_triggered()
{ui->plainTextEdit->clear();QStandardItem* aItem;QString str;int j;for(int i = 0; i<m_model->columnCount();i++){aItem = m_model->horizontalHeaderItem(i);str+=aItem->text();str+="\t";}ui->plainTextEdit->appendPlainText(str);for(int i = 0;i < m_model->rowCount();i++){str="";for(j = 0; j<m_model->columnCount() -1;j++){aItem = m_model->item(i,j);str+=aItem->text();str+="\t";}aItem = m_model->item(i,j);if(aItem->checkState()==Qt::Checked){str+="是";}else{str+="否";}ui->plainTextEdit->appendPlainText(str);}
}void MainWindow::on_actionAddLine_triggered()
{QList<QStandardItem*> aItemList;QStandardItem* aItem;for(int i = 0;i<m_model->columnCount()-1;i++){aItem = new QStandardItem("0");aItemList << aItem;}QString str = m_model->headerData(m_model->columnCount() - 1,Qt::Horizontal).toString();aItem = new QStandardItem(str);aItem->setCheckable(true);aItem->setBackground(QBrush(Qt::yellow));aItemList << aItem;m_model->insertRow(m_model->rowCount(),aItemList);m_selection->clearSelection();m_selection->setCurrentIndex(m_model->index(m_model->rowCount() - 1,0),QItemSelectionModel::Select);
}void MainWindow::on_actionInsertLine_triggered()
{QList<QStandardItem*> aItemList;QStandardItem* aItem;for(int i = 0;i<m_model->columnCount()-1;i++){aItem = new QStandardItem("123");aItemList << aItem;}QString str = m_model->headerData(m_model->columnCount() - 1,Qt::Horizontal).toString();aItem = new QStandardItem(str);aItem->setCheckable(true);aItem->setBackground(QBrush(Qt::yellow));aItemList << aItem;QModelIndex curIndex = m_selection->currentIndex();m_model->insertRow(m_selection->currentIndex().row(),aItemList);m_selection->clearSelection();m_selection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}void MainWindow::on_actionDelLine_triggered()
{QModelIndex curIndex = m_selection->currentIndex();if(curIndex.row() != m_model->columnCount()-1){m_selection->setCurrentIndex(curIndex,QItemSelectionModel::Select);m_model->removeRow(curIndex.row());}else{m_model->removeRow(curIndex.row());}
}void MainWindow::on_actionLeft_triggered()
{if(!m_selection->hasSelection())return;QModelIndexList indexList = m_selection->selectedIndexes();for(auto index:indexList){m_model->itemFromIndex(index)->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter);}
}void MainWindow::on_actionCenter_triggered()
{if(!m_selection->hasSelection())return;QModelIndexList indexList = m_selection->selectedIndexes();for(auto index:indexList){m_model->itemFromIndex(index)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);}
}void MainWindow::on_actionRight_triggered()
{if(!m_selection->hasSelection())return;QModelIndexList indexList = m_selection->selectedIndexes();for(auto index:indexList){m_model->itemFromIndex(index)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);}
}void MainWindow::on_actionBold_triggered(bool checked)
{if(!m_selection->hasSelection())return;QModelIndexList indexList = m_selection->selectedIndexes();for(auto index:indexList){QFont font = m_model->itemFromIndex(index)->font();font.setBold(checked);m_model->itemFromIndex(index)->setFont(font);}
}

效果展示

在这里插入图片描述


自定义代理

  • 在模型视图结构中,代理的作用就是在视图组件进入编辑状态编辑某个项时,提供一个临时的编辑器用于数据编辑,默认的代理编辑器是QLineEdit编辑框
  • 可以对这个默认的编辑框进行替换,比如QSpinBox、QDoubleSpinBox、ComboBox

继承关系

QObject
QAbstractItemDelegate
QStyledItemDelegate
QItemDelegate
QSqqlRelationalDelegate
自定义委托
自定义委托

必须实现以下几个函数

  • createEditor():创建用于编辑模型数据的widget组件,如QSpinBox,QComboBox
  • setEditorData():从数据模型获取数据,供widget组件进行编辑
  • setModelData():将widget上的数据更新到数据模型
  • updateditorGeometry():用于给widget组件设置一个合适的大小

代码测试

TComboBoxDelegate.cpp
#include "tcomboboxdelegate.h"
#include <QComboBox>
TComboBoxDelegate::TComboBoxDelegate(QObject *parent): QStyledItemDelegate{parent}
{}QWidget *TComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{Q_UNUSED(option);Q_UNUSED(index);QComboBox* editor = new QComboBox(parent);editor->setEditable(m_editTable);for(auto item:m_itemList){editor->addItem(item);}return editor;
}void TComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QComboBox* comBoBox = dynamic_cast<QComboBox*>(editor);QString str = index.model()->data(index,Qt::EditRole).toString();comBoBox->setCurrentText(str);
}void TComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{QComboBox* comBoBox = dynamic_cast<QComboBox*>(editor);QString str = comBoBox->currentText();model->setData(index,str,Qt::EditRole);
}void TComboBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{Q_UNUSED(index);editor->setGeometry(option.rect);}void TComboBoxDelegate::setItems(QStringList itemList, bool editTable)
{m_itemList = itemList;m_editTable = editTable;
}
TFloatSpinDelegate.cpp
#include "tfloatspindelegate.h"
#include <QDoubleSpinBox>
TFloatSpinDelegate::TFloatSpinDelegate(QObject *parent): QStyledItemDelegate{parent}
{}QWidget *TFloatSpinDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QDoubleSpinBox* editor = new QDoubleSpinBox(parent);editor->setFrame(false);editor->setMinimum(0);editor->setMaximum(5000);return editor;
}void TFloatSpinDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);double value = index.model()->data(index,Qt::EditRole).toDouble();spinBox->setValue(value);
}void TFloatSpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);double value = spinBox->value();model->setData(index,value,Qt::EditRole);
}void TFloatSpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{Q_UNUSED(index);editor->setGeometry(option.rect);
}
TSpinBoxDelegate.cpp
#include "tspinboxdelegate.h"
#include <QSpinBox>
TSpinBoxDelegate::TSpinBoxDelegate(QObject *parent): QStyledItemDelegate{parent}{}QWidget *TSpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QSpinBox* editor = new QSpinBox(parent);editor->setFrame(false);editor->setMinimum(0);editor->setMaximum(5000);return editor;
}void TSpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QSpinBox* spinBox = dynamic_cast<QSpinBox*>(editor);int value = index.model()->data(index,Qt::EditRole).toInt();spinBox->setValue(value);
}void TSpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{QSpinBox* spinBox = dynamic_cast<QSpinBox*>(editor);int value = spinBox->value();model->setData(index,value,Qt::EditRole);
}void TSpinBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{Q_UNUSED(index);editor->setGeometry(option.rect);
}
MainWindow.cpp
	// 创建代理类对象intSpinDelegate = new TSpinBoxDelegate(this);// 通过列来设置ui->tableView->setItemDelegateForColumn(0,intSpinDelegate);doubleSpinDelegate = new TFloatSpinDelegate(this);ui->tableView->setItemDelegateForColumn(1,doubleSpinDelegate);ui->tableView->setItemDelegateForColumn(2,doubleSpinDelegate);ui->tableView->setItemDelegateForColumn(3,doubleSpinDelegate);comBoDelegate = new TComboBoxDelegate(this);QStringList strList;strList << "优" << "良" << "中" << "差";comBoDelegate->setItems(strList,false);ui->tableView->setItemDelegateForColumn(4,comBoDelegate);

效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/360403.html

相关文章:

  • 第3章 乱码的前世今生-字符集和比较规则
  • 部署在windows的docker中的dify知识库存储位置
  • 常见线程池的创建方式及应用场景
  • Cookie、Session 和 JWT
  • 【K8s-Day 22】深入解析 Kubernetes Deployment:现代应用部署的基石与滚动更新的艺术
  • 服装管理软件与工厂计件系统精选
  • 【OpenGL】LearnOpenGL学习笔记18 - Uniform缓冲对象UBO
  • [每周一更]-(第158期):构建高性能数据库:MySQL 与 PostgreSQL 系统化问题管理与优化指南
  • XPlayer播放器APP:安卓平台上的全能视频播放器
  • 网络代理协议深度对比
  • Linux/UNIX系统编程手册笔记:系统和进程信息、文件I/O缓冲、系统编程概念以及文件属性
  • Multi-Head RAG: Solving Multi-Aspect Problems with LLMs
  • ST-2110概述
  • MySQL专题Day(1)————事务
  • postman 用于接口测试,举例
  • Linux shell 脚本基础 003
  • centos7安装jdk17
  • c++程序员日常超实用工具(长期记录更新)
  • PS自由变换
  • 【人工智能99问】LLaMA中的RoPE是什么?(35/99)
  • 学习Python中Selenium模块的基本用法(12:操作Cookie)
  • 【系统分析师】高分论文:论大数据架构的应用
  • 写一个 RTX 5080 上的 cuda gemm fp16
  • 使用yt-dlp下载网页视频
  • synchronized的锁对象 和 wait,notify的调用者之间的关系
  • Wi-Fi技术——初识
  • Flink NettyBufferPool
  • Docker中使用Compose配置现有网络
  • C语言————深入理解指针1(通俗易懂)
  • Linux 网络编程:深入理解套接字与通信机制