Qt扫盲-QTableView理论总结
QTableView理论总结
- 一、概述
- 二、导航
- 三、视觉外观
- 四、坐标系统
- 五、示例代码
- 1. 性别代理
- 2. 学生信息模型
- 3. 对应视图
一、概述
QTableView实现了一个tableview 来显示model 中的元素。这个类用于提供之前由QTable类提供的标准表,但这个是使用Qt的model/view架构提供的更灵活的方法。
QTableView类是Model/View类之一,是Qt的Model/View框架的一部分。
QTableView实现了由QAbstractItemView类定义的接口,以允许它显示由QAbstractItemModel类派生的 model 提供的数据。
总的来说,model/view 的方式来查看修改数据更加的方便和容易的。
二、导航
我们可以通过鼠标点击一个单元格,或者使用箭头键来导航表格中的单元格。因为 QTableView 默认启用tabKeyNavigation,我们还可以按Tab键和Backtab键在单元格之间移动。
三、视觉外观
表格的垂直头部可以通过函数verticalHeader()获得,水平头部可以通过函数horizontalHeader()获得。可以使用rowHeight()来获得表中每一行的高度。类似地,列的宽度可以使用columnWidth()得到。由于这两个部件都是普通部件,因此可以使用它们的hide()函数隐藏它们。
可以使用hideRow()、hideColumn()、showRow()和showColumn()来隐藏和显示行和列。可以使用selectRow()和selectColumn()来选择列。表格会根据 showGrid 属性显示一个网格。就想我把这个设置为 false 之后。就没有网格线啦。
表视图中显示的项与其他项视图中的项一样,都使用标准委托进行渲染和编辑。
我们还可以用 代理的方式:用下列列表来选择性别的方式
然而,对于某些任务来说,能够在表中插入其他控件有时是有用的。
用setIndexWidget()函数为特定的索引设置窗口组件,然后用indexWidget()检索窗口组件。
默认情况下,表中的单元格不会扩展以填充可用空间。
您可以通过拉伸最后的标题部分来让单元格填充可用空间。使用 horizontalHeader() 或 verticalHeader() 访问相关的 headerview 标题对象,并设置标题的stretchLastSection属性。
要根据每一列或每一行的空间需求来分配可用空间,可以调用视图的resizeColumnsToContents()或resizeRowsToContents()函数。来实现出下面这种效果。
四、坐标系统
对于某些特殊形式的表,能够在行和列索引以及控件坐标之间进行转换是很有用的。
rowAt()函数提供了指定行的视图的y坐标;行索引可以通过rowViewportPosition()获得对应的y坐标。
columnAt()和columnViewportPosition()函数提供了x坐标和列索引之间等价的转换操作。
五、示例代码
1. 性别代理
// SexComboxDelegate.h
#ifndef SEXCOMBOXDELEGATE_H
#define SEXCOMBOXDELEGATE_H#include <QObject>
#include <QStyledItemDelegate>
#include <QComboBox>class SexComboxDelegate : public QStyledItemDelegate
{Q_OBJECT
public:SexComboxDelegate(QObject *parent = nullptr);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 // SEXCOMBOXDELEGATE_H// SexComboxDelegate.cpp
#include "SexComboxDelegate.h"SexComboxDelegate::SexComboxDelegate(QObject *parent)
{}QWidget *SexComboxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QComboBox *editor = new QComboBox(parent);editor->addItems(QStringList{"男", "女"});editor->setFrame(false);return editor;
}void SexComboxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QComboBox *combox = static_cast<QComboBox*>(editor);combox->setCurrentIndex(combox->findText(index.model()->data(index, Qt::DisplayRole).toString()));
}void SexComboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{QComboBox *combox = static_cast<QComboBox*>(editor);model->setData(index, combox->currentText(), Qt::EditRole);
}void SexComboxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{editor->setGeometry(option.rect);
}
2. 学生信息模型
// StudentModel.h
#ifndef STUDENTMODEL_H
#define STUDENTMODEL_H#include <QAbstractTableModel>
#include <QDebug>
#include <QColor>
#include <QBrush>
#include <QFont>class StudentModel: public QAbstractTableModel
{Q_OBJECT
public:StudentModel(QObject *parent = nullptr);int rowCount(const QModelIndex &parent = QModelIndex()) const override;int columnCount(const QModelIndex &parent = QModelIndex()) const override;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;QVariant headerData(int section, Qt::Orientation orientation, int role) const override;bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;Qt::ItemFlags flags(const QModelIndex &index) const override;void setRow(int newRow);void setColumn(int newColumn);void setTableHeader(QList<QString> *header);void setTableData(QList<QList<QString>> *data);signals:void editCompleted(const QString &);public slots:void SlotUpdateTable();
private:int row = 0;int column = 0;QList<QString> *m_header;QList<QList<QString>> *m_data;
};#endif // STUDENTMODEL_H// StudentModel.cpp
#include "StudentModel.h"StudentModel::StudentModel(QObject *parent) : QAbstractTableModel(parent)
{}int StudentModel::rowCount(const QModelIndex &parent) const
{return row;
}int StudentModel::columnCount(const QModelIndex &parent) const
{return column;
}QVariant StudentModel::data(const QModelIndex &index, int role) const
{if(role == Qt::DisplayRole || role == Qt::EditRole){return (*m_data)[index.row()][index.column()];}if(role == Qt::TextAlignmentRole){return Qt::AlignCenter;}if(role == Qt::BackgroundRole && index.row() % 2 == 0){return QBrush(QColor(50, 50, 50));}return QVariant();
}QVariant StudentModel::headerData(int section, Qt::Orientation orientation, int role) const
{if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {if(m_header->count() - 1 >= section)return m_header->at(section);}//qDebug()<<role << "--" << Qt::BackgroundRole;// if(role == Qt::BackgroundRole)
// {
// return QBrush(QColor(156, 233, 248));
// }
// if(role == Qt::ForegroundRole)
// {
// return QBrush(QColor(156, 233, 248));
// }if(role == Qt::FontRole){return QFont(tr("微软雅黑"),10, QFont::DemiBold);}return QVariant();
}bool StudentModel::setData(const QModelIndex &index, const QVariant &value, int role)
{if (role == Qt::EditRole) {if (!checkIndex(index))return false;//save value from editor to member m_gridData(*m_data)[index.row()][index.column()] = value.toString();return true;}return false;
}Qt::ItemFlags StudentModel::flags(const QModelIndex &index) const
{return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}void StudentModel::setRow(int newRow)
{row = newRow;
}void StudentModel::setColumn(int newColumn)
{column = newColumn;
}void StudentModel::setTableHeader(QList<QString> *header)
{m_header = header;
}void StudentModel::setTableData(QList<QList<QString> > *data)
{m_data = data;
}void StudentModel::SlotUpdateTable()
{emit dataChanged(createIndex(0, 0), createIndex(row, column), {Qt::DisplayRole});
}
3. 对应视图
// StudentWD.h
#ifndef STUDENTWD_H
#define STUDENTWD_H#include <QWidget>
#include <Model/StudentModel.h>
#include <QFileDialog>
#include <QStandardPaths>
#include <QFile>
#include <QTextStream>
#include <Delegate/SpinBoxDelegate.h>
#include <Delegate/SexComboxDelegate.h>namespace Ui {
class StudentWD;
}class StudentWD : public QWidget
{Q_OBJECTpublic:explicit StudentWD(QWidget *parent = nullptr);~StudentWD();private slots:void on_ImportBtn_clicked();private:Ui::StudentWD *ui;StudentModel *model;SpinBoxDelegate *spinBoxDelegate;SexComboxDelegate *sexBoxDeleage;QList<QList<QString>> subject_table;QList<QString> subject_title;
};#endif // STUDENTWD_H
// StudentWD.cpp
#include "StudentWD.h"
#include "ui_StudentWD.h"StudentWD::StudentWD(QWidget *parent) :QWidget(parent),ui(new Ui::StudentWD),model(new StudentModel),spinBoxDelegate(new SpinBoxDelegate),sexBoxDeleage(new SexComboxDelegate)
{ui->setupUi(this);ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);}StudentWD::~StudentWD()
{delete ui;
}void StudentWD::on_ImportBtn_clicked()
{QString fileName = QFileDialog::getOpenFileName(this,tr("打开 csv 文件"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), tr("Txt Files (*.txt *.csv *.*)"));subject_table.clear();subject_title.clear();if(!fileName.isNull() && !fileName.isEmpty()){QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text))return;int i = 0;QTextStream in(&file);in.setCodec("UTF-8");while (!file.atEnd()) {QString line = file.readLine();if(i == 0){subject_title = line.split(",", QString::SkipEmptyParts);subject_title.last() = subject_title.last().trimmed();i++;continue;}subject_table.append(line.split(",", QString::SkipEmptyParts));subject_table.last().last() = subject_table.last().last().trimmed();}ui->Total_Subject_SB->setValue(subject_title.count());ui->Total_People_SB->setValue(subject_table.count());model->setColumn(subject_title.count());model->setRow(subject_table.count());model->setTableData(& subject_table);model->setTableHeader(& subject_title);ui->tableView->setModel(model);ui->tableView->setItemDelegateForColumn(0, spinBoxDelegate);ui->tableView->setShowGrid(true);ui->tableView->setItemDelegateForColumn(1, sexBoxDeleage);for (int i = 2; i < subject_table.count(); ++i) {ui->tableView->setItemDelegateForColumn(i, spinBoxDelegate);}ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents);}}
对应的ui文件
相关文章:

Qt扫盲-QTableView理论总结
QTableView理论总结 一、概述二、导航三、视觉外观四、坐标系统五、示例代码1. 性别代理2. 学生信息模型3. 对应视图 一、概述 QTableView实现了一个tableview 来显示model 中的元素。这个类用于提供之前由QTable类提供的标准表,但这个是使用Qt的model/view架构提供…...
从外部访问K8s中Pod的五种方式
hostNetwork、 hostPort、 NodePort、 LoadBalancer、 Ingress 暴露Pod与Service一样,因为Pod就是Service的backend 1、hostNetwork:true 这是一种直接定义 Pod 网络的方式。 如果在 Pod 中使用 hostNetwork:true 配置, pod 中运行的应用程序…...
什么是A股交易接口_(股票交易c接口)开发原理
A股交易接口是指用于与国内的证券交易所(上海证券交易所和深圳证券交易所)进行股票买卖交易的电子接口或软件系统。A股交易接口是金融机构、券商以及个人投资者的必备掌握操作技能之一,它提供了实时的股票行情、交易下单、撤单、查询账户信息…...

STM32F4X NVIC中断概念
STM32F4X NVIC中断概念 CPU查询状态两种方式轮询查询中断查询 STM32有关中断的概念中断向量表系统中断外设中断中断号中断优先级 STM32F4X NVIC控制器NVIC控制器简介NVIC寄存器优先级分组 STM32F4X中断配置优先级分组设置配置外设中断 CPU查询状态两种方式 在讲解中断的概念之…...

关于consul的下载方法
linux下 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo sudo yum -y install consulwindow下 https://developer.hashicorp.com/consul/downloads 然后把里面的exe文件放在gopath下就行了 验证…...

应用在汽车前照灯系统中的环境光传感芯片
为了保证行车照明的安全性和方便性,减轻驾驶员的劳动强度。近年来,出现了许多新的照明控制系统,例如用于日间驾驶的自动照明系统、光束调节系统、延迟控制等。尤其是汽车自适应前照灯系统,它是一种能够自动改变两种以上的光型以适…...

Python Flask+Echarts+sklearn+MySQL(评论情感分析、用户推荐、BI报表)项目分享
Python FlaskEchartssklearnMySQL(评论情感分析、用户推荐、BI报表)项目分享 项目背景: 随着互联网的快速发展和智能手机的普及,人们越来越倾向于在网上查找餐厅、购物中心、酒店和旅游景点等商户的点评和评分信息,以便做出更好的消费决策。…...

开源项目-高校自动排课系统
哈喽,大家好,今天给大家带来一个开源项目-基于遗传算法的一个高校自动排课系统,同时也是一个前后端分离项目。 前端:React 后端:SpringBoot+MyBatis+MySQL数据库 高校自动排课系统的主要功能包括查询模块,安排教学区域,排课页面三部分 登录 查询模块 可以根据学年…...

IP网络广播系统草坪音箱景区系统防水石头,草坪音箱的应用
IP网络广播系统草坪音箱景区系统防水石头,草坪音箱的应用 SV-7045V是深圳锐科达电子有限公司的一款防水网络草坪音箱,具有10/100M以太网接口,可将网络音源通过自带的功放和喇叭输出播放,可达到功率20W。常用场景:公园ip草坪音箱&…...

拒绝摆烂!C语言练习打卡第二天
🔥博客主页:小王又困了 📚系列专栏:每日一练 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、选择题 📝1.第一题 📝2.第二题 📝…...

第四章:前端框架Vue基础入门
文章目录 一、Vue框架概述1.1 声明响应式的数据 二、Vue内置指令2.1、条件渲染指令v-if/v-show2.2 v-for: 列表渲染2.3、v-text/v-html 模板指令2.4 v-on:事件监听器2.6 动态绑定v-bind2.7 v-model表单元素值绑定 三、计算属性与监视3.1 计算属性computed3.2 watch侦听器3.3 wa…...

企业权限管理(十三)-用户关联角色操作
用户关联角色操作 从前台发送请求 <a href"${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id${user.id}" class"btn bg-olive btn-xs">添加角色</a>查询用户以及用户可以添加的角色 usercontroller //查询用户以及用…...

深入理解Vue 3.0x中的Suspense和异步组件
深入理解Vue 3.0x中的Suspense和异步组件 Vue 3.0x作为Vue.js框架的最新版本,引入了许多创新特性,其中Suspense和异步组件是重要的改进之一。在本文中,我们将深入探讨这两个特性,了解它们如何为现代Web应用带来更好的性能和用户体…...
Ajax 笔记(三)—— Ajax 原理
笔记目录 3. Ajax 原理3.1 XMLHttpRequest3.1.1 XHR 使用步骤3.1.2 查询参数3.1.3 数据提交 3.2 Promise3.2.1 Promise 使用步骤3.2.2 Promise 状态3.2.3 Promise 和 XHR 应用小案例 3.3 封装简易 axios3.3.1 核心封装代码3.3.2 支持传递查询参数3.3.3 支持传递请求体数据 Ajax…...

el-tree通过default-expand-all动态控制展开/折叠
1、如下图通过勾选框动态控制展开/折叠,全选/清空 2、实现方式如下:定义key,监听checked2修改treeKey,重新渲染tere;附加全选和清空。 <div class"tree"><el-checkbox v-model"checked1"…...

基于Bsdiff差分算法的汽车OTA升级技术研究(学习)
摘要 针对汽车OTA整包升级时,用户下载时间长,升级时间长,设备服务器端压力大等问题,本文提出了一种基于Bsdiff差分算法的汽车OTA升级技术。该算法能够对比新旧版本的差异,进行差分文件下载,减少软件包的下…...

如何使用CSS实现一个纯CSS的滚动条样式?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现自定义滚动条样式⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣…...

使用维纳过滤器消除驾驶舱噪音(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

vue所有UI库通用)tree-select 下拉多选(设置 maxTagPlaceholder 隐藏 tag 时显示的内容,支持鼠标悬浮展示更多
如果可以实现记得点赞分享,谢谢老铁~ 1.需求描述 引用的下拉树形结构支持多选,限制选中tag的个数,且超过制定个数,鼠标悬浮展示更多已选中。 2.先看下效果图 3.实现思路 首先根据API文档,先设置maxTagC…...

进行 200 瓦太阳能 (PV) 模块设计以测量太阳能光伏阵列的电压、电流和功率、综合负荷频率和电压控制系统的方法研究(Simulink实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...