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

7.qsqlquerymodel 与 qtableview使用

目录

  • qtableview 委托
  • QStyledItemDelegate
  • QAbstractItemDelegate
  • CheckBoxItemDelegate
  • 使用
    • qtableview控制列宽,行高,隐藏
    • 拖拽行列

qtableview 委托


//设置单元格委托
void setItemDelegate(QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegate() const;//设置列委托
void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegateForColumn(int column) const;//设置行委托
void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
QAbstractItemDelegate *itemDelegateForRow(int row) const;

QStyledItemDelegate

查看qtableview源码会发现itemdelegate默认就是QStyledItemDelegate
如果要自己写自定义的委托请尽量参考QStyledItemDelegate

显示事件

void QStyledItemDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option, const QModelIndex &index) const
{Q_ASSERT(index.isValid());QStyleOptionViewItem opt = option;initStyleOption(&opt, index);const QWidget *widget = QStyledItemDelegatePrivate::widget(option);QStyle *style = widget ? widget->style() : QApplication::style();style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
}

初始化绘制参数配置

void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,const QModelIndex &index) const
{QVariant value = index.data(Qt::FontRole);if (value.isValid() && !value.isNull()) {option->font = qvariant_cast<QFont>(value).resolve(option->font);option->fontMetrics = QFontMetrics(option->font);}value = index.data(Qt::TextAlignmentRole);if (value.isValid() && !value.isNull())option->displayAlignment = Qt::Alignment(value.toInt());value = index.data(Qt::ForegroundRole);if (value.canConvert<QBrush>())option->palette.setBrush(QPalette::Text, qvariant_cast<QBrush>(value));option->index = index;value = index.data(Qt::CheckStateRole);if (value.isValid() && !value.isNull()) {option->features |= QStyleOptionViewItem::HasCheckIndicator;option->checkState = static_cast<Qt::CheckState>(value.toInt());}value = index.data(Qt::DecorationRole);if (value.isValid() && !value.isNull()) {option->features |= QStyleOptionViewItem::HasDecoration;switch (value.type()) {case QVariant::Icon: {option->icon = qvariant_cast<QIcon>(value);QIcon::Mode mode;if (!(option->state & QStyle::State_Enabled))mode = QIcon::Disabled;else if (option->state & QStyle::State_Selected)mode = QIcon::Selected;elsemode = QIcon::Normal;QIcon::State state = option->state & QStyle::State_Open ? QIcon::On : QIcon::Off;QSize actualSize = option->icon.actualSize(option->decorationSize, mode, state);// For highdpi icons actualSize might be larger than decorationSize, which we don't want. Clamp it to decorationSize.option->decorationSize = QSize(qMin(option->decorationSize.width(), actualSize.width()),qMin(option->decorationSize.height(), actualSize.height()));break;}case QVariant::Color: {QPixmap pixmap(option->decorationSize);pixmap.fill(qvariant_cast<QColor>(value));option->icon = QIcon(pixmap);break;}case QVariant::Image: {QImage image = qvariant_cast<QImage>(value);option->icon = QIcon(QPixmap::fromImage(image));option->decorationSize = image.size() / image.devicePixelRatio();break;}case QVariant::Pixmap: {QPixmap pixmap = qvariant_cast<QPixmap>(value);option->icon = QIcon(pixmap);option->decorationSize = pixmap.size() / pixmap.devicePixelRatio();break;}default:break;}}value = index.data(Qt::DisplayRole);if (value.isValid() && !value.isNull()) {option->features |= QStyleOptionViewItem::HasDisplay;option->text = displayText(value, option->locale);}option->backgroundBrush = qvariant_cast<QBrush>(index.data(Qt::BackgroundRole));// disable style animations for checkboxes etc. within itemviews (QTBUG-30146)option->styleObject = 0;
}

当然有些列子https://blog.csdn.net/c1s2d3n4cs/article/details/143203486

行委托一般用来作为背景委托
列委托与单元格委托是一组,就是简单的优先级
列委托优先级》单元格委托

QAbstractItemDelegate

那么为了自定义qtableview 需要使用到这个QAbstractItemDelegate委托类
在这里插入图片描述

很遗憾,官方没给我们提供checkboxitemdelegate或者comboboxdelegate之类的委托
那么我们就需要自己去写一个
请参考https://blog.csdn.net/Gerald_Jones/article/details/106594052

CheckBoxItemDelegate

继承QItemDelegate需要实现一下几个虚函数

编辑模式,因为我们使用qsqlquerymodel 只读模型 所以可以不用写

// 创建编辑器virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;// 设置编辑器数据virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override;// 更新编辑器集合属性virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;// 设置模型数据virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;

//如果是只读的组件那么我们只需要以下两个方法

CheckBoxItemDelegate.h

#ifndef CHECKBOXITEMDELEGATE_H
#define CHECKBOXITEMDELEGATE_H#include <QObject>
#include <QItemDelegate>
#include <QStyledItemDelegate>
#include <QCheckBox>
#include <QStylePainter>
#include <QDebug>
#include <QStyleOptionButton>class CheckBoxItemDelegate : public QItemDelegate
{Q_OBJECT
public:explicit CheckBoxItemDelegate(QObject *parent = nullptr);~CheckBoxItemDelegate();//---只读void paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const override;bool editorEvent(QEvent *event,QAbstractItemModel *model,const QStyleOptionViewItem &option,const QModelIndex &index) override;//---编辑模式// 创建编辑器 ---- 返回组件//     QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;//    // 设置编辑器数据 ---- 初始化组件数据//     void setEditorData(QWidget *editor, const QModelIndex &index) const override;//    // 更新编辑器集合属性 --- 设置位置//     void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;//    // 设置模型数据 ---- 修改数据模型数据//     void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;signals:protected:void initStyleOption(QStyleOptionButton *option,const QStyleOptionViewItem *copy,const QModelIndex &index) const;private:bool m_checked = false;};#endif // CHECKBOXITEMDELEGATE_H

CheckBoxItemDelegate.cpp

#include "CheckBoxItemDelegate.h"
#include <QApplication>CheckBoxItemDelegate::CheckBoxItemDelegate(QObject *parent) : QItemDelegate(parent)
{qDebug()<< __FUNCTION__;
}CheckBoxItemDelegate::~CheckBoxItemDelegate()
{qDebug()<< __FUNCTION__;
}void CheckBoxItemDelegate::paint(QPainter *painter,const QStyleOptionViewItem &option,const QModelIndex &index) const
{QStyleOptionButton opt;initStyleOption(&opt, &option, index);const QWidget *widget = option.widget;QStyle *style = widget ? widget->style() : QApplication::style();style->drawControl(QStyle::CE_CheckBox, &opt, painter, widget);
}bool CheckBoxItemDelegate::editorEvent(QEvent *event,QAbstractItemModel *model,const QStyleOptionViewItem &option,const QModelIndex &index)
{//选中或者取消选中m_checked = true;return false;
}//QWidget *CheckBoxItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
//{//    return new QCheckBox(parent);
//}//void CheckBoxItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
//{
//    QCheckBox *cb = static_cast<QCheckBox *>(editor);
//    cb->setChecked(true);
//}//void CheckBoxItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
//{
//    editor->setGeometry(option.rect);
//}//void CheckBoxItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
//{
//    //    QCheckBox *cb = static_cast<QCheckBox *>(editor);
//    //    model->setData(index, cb->isChecked());
//}void CheckBoxItemDelegate::initStyleOption(QStyleOptionButton *option,const QStyleOptionViewItem *copy,const QModelIndex &index) const
{QRect boxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator,option);option->rect = copy->rect;option->rect.setLeft(copy->rect.left()+(copy->rect.width()-boxRect.width())/2); //居中//option->rect.setTop(copy->rect.top()+(copy->rect.height()-option->rect.height())/2);option->state = m_checked? QStyle::State_On: QStyle::State_Off;
}

至于初始化选中状态由外部的section管理器来决定来决定
所以我们需要
实现一个选择管理器(支持单选,多选,跨页选)
我好想又看到qml有一个TableViewSelection.qml
至于c++有没有这个选择管理器还得自己去实现

使用

部分操作需要基于model之后,否则无效
如对行列隐藏,宽高设置等

qtableview控制列宽,行高,隐藏

    QTableView *view = new QTableView(this);view->setModel(model);view->move(0,400);//修改布局样式需要放到model之后设置CheckBoxItemDelegate* cb_delegate = new CheckBoxItemDelegate(this);view->setItemDelegateForColumn(0,cb_delegate);view->setColumnHidden(1,true);view->setColumnWidth(0,120);view->setRowHidden(0,true);view->setRowHeight(0,60);

而至于为什么view可以操作行列, 实际要查看Qheaderview.cpp
setColumnHidden -> setSectionHidden -> setVisualIndexHidden

    inline void setVisualIndexHidden(int visual, bool hidden) {sectionItems[visual].isHidden = hidden;}

而至于sectionItems怎么来的就跟我们上面的setmodel有关
他们之间有个信号槽,model 的信号 columnsInserted触发headerview中的sectionsInserted槽
sectionsInserted执行了sectionItems的添加操作

            QObject::connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),this, SLOT(sectionsInserted(QModelIndex,int,int)));

行的管理-------是同上的

拖拽行列

请参考https://blog.csdn.net/pyc_01/article/details/123346957

   view->setSelectionBehavior(QAbstractItemView::SelectRows); //选择方式:单元格选择、行选择、列选择view->setSelectionMode(QAbstractItemView::SingleSelection); //选择模式: 多选,单选view->horizontalHeader()->setSectionsMovable(true); //表头支持拖动view->setDragEnabled(true); //启用拖拽view->setAcceptDrops(true); //接受放置view->setDragDropMode(QAbstractItemView::InternalMove); //拖放范围:内部view->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁用编辑功能view->setCursor(Qt::ClosedHandCursor);

//解下来需要重写拖放等相关事件,这需要重写一个DragTableView控件

相关文章:

7.qsqlquerymodel 与 qtableview使用

目录 qtableview 委托QStyledItemDelegateQAbstractItemDelegateCheckBoxItemDelegate使用qtableview控制列宽&#xff0c;行高&#xff0c;隐藏拖拽行列 qtableview 委托 //设置单元格委托 void setItemDelegate(QAbstractItemDelegate *delegate); QAbstractItemDelegate *it…...

状态模式(State Pattern)详解

1. 引言 在很多软件系统中&#xff0c;对象的行为往往依赖于其内部状态&#xff0c;而状态的变化又会影响对象的行为。状态模式&#xff08;State Pattern&#xff09;为解决这一问题提供了一种优雅的方法。通过将状态的行为封装到独立的状态对象中&#xff0c;可以使得对象在…...

ajax微信静默登录不起效不跳转问题

问题描述&#xff1a; 今天通过ajax调用方式做微信静默登录&#xff0c;发现本地可以跳转&#xff0c;到线上地址死活都不跳转&#xff0c;就像没起作用一般&#xff0c;经许久排查发现&#xff0c;是因为https和http域名的问题&#xff0c;线上只配置了http域名&#xff0…...

参数估计理论

估计理论的主要任务是在某种信号假设下&#xff0c;估算该信号中某个参数&#xff08;比如幅度、相位、达到时间&#xff09;的具体取值。 参数估计&#xff1a;先假定研究的问题具有某种数学模型&#xff0c; 如正态分布&#xff0c;二项分布&#xff0c;再用已知类别的学习样…...

mybatis插入数据运行成功但数据库没有数据,id却在增长,是什么原因??

错误描述&#xff1a; mybatis插入数据运行成功&#xff0c;但是数据库却没有数据&#xff0c;id也在增加 原因&#xff1a;在测试方法上面加了 Transactional 虽然日志显示插入语句执行成功&#xff0c;但可能事务在提交过程中出现了问题。比如在后续的操作中有异常抛出导…...

Hadoop简介及单点伪分布式安装

目录 1. 大数据2. Hadoop简介3. Hadoop伪分布式安装4. Hadoop启动参考 1. 大数据 大数据的定义&#xff1a;一种规模大到在获取、存储、管理、分析方面大大超出传统数据库软件工具能力范围的数据集合。   特征&#xff1a;   1.海量的数据规模   2.快速的数据流转   3.…...

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块&#xff0c;适用于执行简单的命令&#xff0c;不支持特殊符号 案列01&#xff0c;批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…...

是时候用开源降低AI落地门槛了

过去三十多年&#xff0c;从Linux到KVM&#xff0c;从OpenStack到Kubernetes&#xff0c;IT领域众多关键技术都来自开源。开源技术不仅大幅降低了IT成本&#xff0c;也降低了企业技术创新的门槛。 那么&#xff0c;在生成式AI时代&#xff0c;开源能够为AI带来什么&#xff1f;…...

操作系统学习笔记-5.1-IO设备

文章目录 I/O控制器I/O 控制器的组成I/O 控制器的工作流程I/O 控制器的类型I/O 控制器的主要功能I/O 控制器与操作系统的交互DMA 的工作原理DMA 传输模式DMA 控制器的组成 组成内存映像I/O&#xff0c;寄存器独立编址 IO软件层次用户层 I/O 软件设备独立性软件层设备驱动程序中…...

页面、组件、应用、生命周期(微信小程序)

文章目录 页面生命周期函数组件生命周期函数应用&#xff08;App&#xff09;生命周期函数页面与组件生命周期的执行顺序注意事项 在微信小程序中&#xff0c;生命周期函数是指页面或组件在不同阶段会被自动调用的特定函数。这些函数可以帮助开发者在适当的时机完成特定的初始化…...

书生第四期实训营进阶岛——L2G4000 InternVL 多模态模型部署微调实践

基础任务 体验InternVL 运行demo 效果如下&#xff1a; 使用XTuner对InternVL进行微调 运行demo 效果如下&#xff1a;...

国内 ChatGPT中文版镜像网站整理合集(2024/11/08)

一、GPT中文镜像站 ① yixiaai.com 支持GPT4、4o以及o1&#xff0c;支持MJ绘画 ② chat.lify.vip 支持通用全模型&#xff0c;支持文件读取、插件、绘画、AIPPT ③ AI Chat 支持GPT3.5/4&#xff0c;4o以及MJ绘画 1. 什么是镜像站 镜像站&#xff08;Mirror Site&#xff…...

SpringBoot整合Liquibase对数据库管理和迁移

简介 Liquibase是一个用于用于跟踪、管理和应用数据库变化的开源工具&#xff0c;通过日志文件(changelog)的形式记录数据库的变更(changeset)&#xff0c;然后执行日志文件中的修改&#xff0c;将数据库更新或回滚(rollback)到一致的状态。它的目标是提供一种数据库类型无关的…...

太空旅游:科技能否让星辰大海变为现实?

内容概要 在这个快速变化的时代&#xff0c;太空旅游成为了一个让人热血沸腾的话题。想象一下&#xff0c;坐在一颗漂浮的太空舱里&#xff0c;手中端着饮料&#xff0c;眺望着无尽的星辰大海&#xff0c;简直就像科幻电影中的情节一样。不过&#xff0c;这不仅仅是一个空洞的…...

[JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决

目录 一. 多线程下使用ArrayList 1.1. 自行判断加锁 1.2 使用Collections.synchronizedList()套壳加锁 1.3 CopyOnWriteArrayList类 二. 总结 一. 多线程下使用ArrayList 多线程下使用ArrayList会涉及到线程安全问题, 例如: public static void main(String[] args) thro…...

Elasticsearch-linux环境部署

本文主要介绍linux下elasticsearch的部署。通过在一台linux服务器中分别对elasticsearch-6.7.2版本&#xff0c;elasticsearch-7.3.0版本来进行安装&#xff0c;记录在安装elasticsearch-7.3.0版本时出现的异常情况&#xff0c;以及elasticsearch-head的安装。 基础环境 本机已…...

LeetCode 每日一题 长度为 K 的子数组的能量值

长度为 K 的子数组的能量值 给你一个长度为 n 的整数数组 nums 和一个正整数 k 。 一个数组的 能量值 定义为&#xff1a; 如果 所有 元素都是依次 连续 且 上升 的&#xff0c;那么能量值为 最大 的元素。 否则为 -1 。 你需要求出 nums 中所有长度为 k 的 子数组 的能量值。 …...

人工智能——小白学习指南

知孤云出岫 目录 1. **智能评测系统**2. **个性化学习路径推荐**3. **虚拟学习助手**4. **学习行为分析**5. **数据驱动的教学决策**6. **自动化课程推荐**7. **数据隐私与安全保护** 人工智能知识点的总结和学习路线&#xff0c;以数据表格形式呈现&#xff0c;并附带在教育行…...

go 集成Gin Web开发框架

引入gin的依赖 下载并安装 gin go get -u github.com/gin-gonic/gin 将 gin 引入到代码中 import "github.com/gin-gonic/gin" 开始 package mainimport "github.com/gin-gonic/gin"func main() {r : gin.Default()r.GET("/ping", func(c …...

c++ 多态性

类的多态 多态概念入门 #include <iostream> using namespace std;/* 多态的前提: 拥有继承关系的类中有相同的函数(返回类型、函数名、形参列表) 多态解决的问题&#xff1a;1、派生类的对象被赋值给基类对象时2、派生类的对象初始化基类的引用时3、基类的指针指向派生…...

块存储、文件存储和对象存储详细介绍

块存储、文件存储和对象存储介绍 块存储&#xff1a;像跑车&#xff0c;因为它们都能提供快速的响应和高性能&#xff0c;适合需要即时数据访问的场景&#xff0c;比如数据库和虚拟化技术。 文件存储&#xff1a;像货车&#xff0c;因为它们都能承载大量货物&#xff08;文件&…...

移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (9) - 编译现有的AWTK应用程序

AWTK 应用程序开发完成后&#xff0c;在配置文件中添加 harmonyos 的选项&#xff0c;通过create_project.py脚本即可生成 DevEco Studio的工程。 安装开发环境 DevEco Studio HarmonyOS 的开发工具。 Python 运行环境。 git 源码管理工具。 下载 awtk 和 awtk-harmonyos…...

ssm基于BS的仓库在线管理系统的设计与实现+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码看文章最下面 需要定制看文章最下面 目 录 第一章 绪论 1 1.1 研究背景 1 1.2 研究意义 1 1.3 研究内容 2 第二章 开发环境与技术3 …...

面试题:Spring(一)

1. Spring框架中bean是单例么&#xff1f; Service Scope("singleton") public class UserServiceImpl implements UserService { }singleton : bean在每个Spring IOC容器中只有一个实例。prototype&#xff1a;一个bean的定义可以有多个实例。 2. Spring框架中的…...

MySQ怎么使用语法介绍(详细)

一、什么是库结构 库结构的意思就是指数据库的结构。所以&#xff0c;理解“库结构”就要先理解“库”是什么。 在数据库的上下文中&#xff0c;库指的是一个数据库。简单来说&#xff0c;数据库&#xff08;库&#xff09;是用来存储和管理数据的容器。它不仅存储实际的数据…...

新能源汽车与公共充电桩布局

近年来,全球范围内对新能源汽车产业的推动力度不断增强,中国新能源汽车市场也呈现蓬勃发展的势头,在政策与市场的共同推动下,新能源汽车销量持续增长。然而,据中国充电联盟数据显示,充电基础设施建设滞后于新能源汽车数量增长的现状导致充电桩供需不平衡,公共充电桩服务空白区域…...

【GIT】sourceTree的“当前分支“,“合并分支“与“检出分支的区别

GIT三款经典可视化 由上文文档得出灵感写出此篇 这三个概念在 Git 操作中都是很常见的&#xff0c; 来逐个解析&#xff1a; 1. 当前分支 “当前分支”就是你目前正在工作的分支。你在进行任何代码修改、提交等操作时&#xff0c;都会应用到“当前分支”上。换句话说&#xf…...

【Git】如何在 Git 中高效合并分支:完整指南

目录 引言1. 切换到主分支1.1 切换分支命令1.2 相关命令1.3 切换分支示意图 2. 合并分支2.1 基本合并命令2.2 合并选项2.3 合并流程示意图 3. 解决冲突3.1 解决冲突的步骤3.2 相关命令3.3 解决冲突示意图 4. 本地更新分支4.1 拉取远程更改4.2 更新主分支4.3 拉取远程更新到本地…...

成都睿明智科技有限公司抖音电商服务效果如何?

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力&#xff0c;成为了众多商家竞相追逐的新蓝海。而在这片波澜壮阔的商海中&#xff0c;成都睿明智科技有限公司犹如一艘稳健的航船&#xff0c;引领着无数企业驶向成功的彼岸。今天&#xff0c;就让我们一起揭开成…...

收集的linux命令/Docker命令/git命令

查看linux发行版本 lsb_release -a显示操作系统的发行版号 uname -r1. 启动 Docker。 sudo systemctl start docker2. 通过运行映像来验证 Docker 引擎安装是否成功。hello-world sudo docker run hello-world查看docker版本 docker -v查看docker配置信息 docker infodoc…...