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控件

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

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

相关文章

微服务实战系列之玩转Docker(十八)

导览 前言Q&#xff1a;如何保障容器云环境下etcd集群的数据安全一、安全机制身份认证必学必看1. 启动参数2. 授权命令3. 开启认证 二、应用实践1. 访问容器2. 查看认证是否开启3. 查看是否已创建用户4. 创建用户5. 开启认证6. 验证是否开启7. 验证数据 结语系列回顾 前言 etc…

如何基于pdf2image实现pdf批量转换为图片

最近为了将pdf报告解析成为文本和图片&#xff0c;需要将大量多页的pdf文件拆分下单独的一页一页的图像&#xff0c;以便后续进行OCR和图像处理&#xff0c;因此就需要实现将pdf2image&#xff0c;本文主要结合开源的pdf2image和poppler&#xff0c;实现了pdf转换为png格式图片…

巧用防火墙的转发功能在云服务器上搭建代理解决Redis,数据库等资源需IP白名单访问的问题

在使用云厂商的云数据库, 如Redis, Polardb出于安全的考虑, 大都默认不提供公网访问的地址&#xff0c; 而且连接来源IP有白名单的机制&#xff0c;但在开发环境中&#xff0c;公网IP往往不是固定的&#xff0c;而且也不处于云数据库的专有网络环境内&#xff0c;所以有时需要直…

Python小游戏23——捕鱼达人

首先&#xff0c;你需要安装Pygame库。如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 运行效果展示 接下来是示例代码&#xff1a; 【python】 import pygame import random # 初始化Pygame pygame.init() # 屏幕尺寸 SCREEN…

如何调整pdf的页面尺寸

用福昕阅读器打开pdf&#xff0c;进入打印页面&#xff0c;选择“属性”&#xff0c;在弹出的页面选择“高级” 选择你想调成的纸张尺寸&#xff0c;然后打印&#xff0c;打印出来的pdf就是调整尺寸后的pdf

《重学Java设计模式》之 原型模式

原型模式主要解决的问题就是创建重复对象&#xff0c;而这部分对象内容本身比较复杂&#xff0c;生成过程可能从库或者RPC接口中获取数据的耗时较长&#xff0c;因此采用克隆的方式节省时间。 案例&#xff1a;上机考试抽题&#xff0c;要求打乱题目、答案数据 工厂结构 选择题…

【CSS】居中样式

对于行内元素&#xff0c;使用 text-align: center。对于已知宽度的块级元素&#xff0c;使用 margin: 0 auto。对于需要灵活布局的元素&#xff0c;使用 Flexbox 或 Grid。 flex .parent {display: flex;justify-content: center; /* 水平居中 */align-items: center; /* 垂…

代码随想录 | Day38 | 动态规划 :01背包应用 目标和一和零

代码随想录 | Day38 | 动态规划 &#xff1a;01背包应用 目标和&&一和零 动态规划应该如何学习&#xff1f;-CSDN博客 01背包模板 | 学习总结-CSDN博客 难点&#xff1a; 代码都不难写&#xff0c;如何想到01背包并把具体问题抽象为01背包才是关键 这真的不能怪笔者…

八,附录 A:其他发现流程示例

八&#xff0c;附录 A&#xff1a;其他发现流程示例 八&#xff0c;附录 A&#xff1a;其他发现流程示例8.1 修改后的发现流程8.2 优化后的发现流程8.3 高级发现流程 八&#xff0c;附录 A&#xff1a;其他发现流程示例 以下部分提供了关于修改后的、优化后的和高级的发现流程…

实战:看懂并分析执行计划——Clustered Index Scan

这是 Clustered Index Scan 的执行计划详情,以下是对每一行的含义及其对查询性能的可能影响的解释。 Clustered Index Scan (Clustered) 解释 Physical Operation: Clustered Index Scan (Clustered) 物理操作,表明数据库引擎在整个聚集索引上进行扫描。Clustered Index Sc…

linux-find和zgrep

zgrep 命令本身并不支持递归搜索&#xff0c;它只能搜索单个压缩文件。但是&#xff0c;你可以结合使用 find 命令和 xargs 来实现递归搜索。下面是一个使用 find 和 xargs 来递归搜索所有 .gz 压缩文件中包含特定文本的例子&#xff1a; find /path/to/directory -type f -na…

C#核心(8) 静态成员

前言 先前我们已经学习了成员变量以及成员属性。 静态成员对于在整个应用程序中共享数据和功能非常有用。它们可以用于跟踪全局状态、共享常量和实现单例模式等。但是需要注意的是&#xff0c;过度使用静态成员可能导致代码变得难以维护和测试&#xff0c;因此应谨慎使用。其…

Jenkins声明式Pipeline流水线语法示例

系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline&#xff1f;1.2、为什么使用pi…

OceanBase中,如何解读 obdiag 收集的火焰图 【DBA早下班系列】

1. 前言 在之前的文章 遇到性能问题&#xff0c;如何给OceanBase“拍CT“&#xff08;火焰图与扁鹊图&#xff09;中&#xff0c;分享了obdiag 快速收集火焰图的方法&#xff0c;那么&#xff0c;紧接着的问题便是&#xff1a;收集到火焰图和扁鹊图之后&#xff0c;该如何解读…

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

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

Browserslist 配置

Browserslist 是一个工具和规范&#xff0c;用于定义和共享支持的浏览器列表&#xff0c;以便在前端开发中管理不同工具的兼容性。这些工具可以包括 Babel、Autoprefixer、ESLint 等&#xff0c;它们都可以使用 Browserslist 提供的配置来确定应支持哪些浏览器及其版本。 主要…

短期电力负荷

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月8日9点40分 论文发表 来自《IEEE Transactions on Smart Grid》2022年7月的13卷第4期&#xff0c;《IEEE Transactions on …

十四:java web(6)-- Spring Spring MVC

目录 Spring MVC 1.1 Spring MVC 概述 1.1.1 什么是 MVC 模式 1.1.2 Spring MVC 工作原理 1.2 Spring MVC 核心组件 1.2.1 DispatcherServlet 1.2.2 控制器&#xff08;Controller&#xff09; 1.2.3 请求映射&#xff08;RequestMapping&#xff09; 1.2.4 视图解析器…

redis与本地缓存

本地缓存是将数据存储在应用程序所在的本地内存中的缓存方式。既然&#xff0c;已经有了 Redis 可以实现分布式缓存了&#xff0c;为什么还需要本地缓存呢&#xff1f;接下来&#xff0c;我们一起来看。 为什么需要本地缓存&#xff1f; 尽管已经有 Redis 缓存了&#xff0c;但…

linux tigerVNC使用

简介 TigerVNC是VNC的一种高性能、平台中立实现&#xff08;虚拟网络计算&#xff09;&#xff0c;一种客户端/服务器应用程序&#xff0c;允许用户启动远程图形应用程序并与之交互机器。TigerVNC提供运行所需的性能级别3D和视频应用程序&#xff0c;并尝试保持普通外观并尽可…