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;
            else
                mode = 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控件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

利用 Avalonia UI 构建 Blazor 混合应用程序

Blazor 是一个 .NET 前端框架&#xff0c;用于仅使用 .NET 技术构建 Web 应用程序。2021 年&#xff0c;Blazor 扩展到桌面端&#xff0c;推出了 Blazor Hybrid&#xff08;混合&#xff09;&#xff0c;使开发者可以在桌面平台上使用已有的技能。 Blazor 混合应用程序是传统的…

MFC中Excel的导入以及使用步骤

参考地址 在需要对EXCEL表进行操作的类中添加以下头文件&#xff1a;若出现大量错误将其放入stdafx.h中 #include "resource.h" // 主符号 #include "CWorkbook.h" //单个工作簿 #include "CRange.h" //区域类&#xff0c;对Excel大…

【深入浅出】Linux进程(三)

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

2024 第五次周赛

A: 直接遍历即可 #include<bits/stdc.h> using namespace std;typedef long long ll; typedef pair<ll, ll>PII; const int N 2e6 10; const int MOD 998244353; const int INF 0X3F3F3F3F;int n, m; int main() {cin >> n;int cnt 0;for(int i 0; i …

gitlab无法创建合并请求是所有分支都不显示

点击Merge Requests ------> New merge request 创建新的合并请求时&#xff0c;在Source branch和Target branch中一个分支都不显示 排查思路&#xff1a; 1.怀疑是权限问题。 发现只有我的一个账号出现&#xff0c;检查了账号的权限&#xff0c;尝试了master、develop角色…

Linux中给普通账户一次性提权

我在以前文章中Linux常见指令大全&#xff08;必要知识点&#xff09;-CSDN博客 写过sudo的概念与用法。其实本质就是提权用的但是在某些场景下就算提权了也不能使用。 例如&#xff1a;打开主工作目录 他不相信你这个用户&#xff0c;虽然你是erman 解决方法 使用root账号打开…

【C++】—掌握STL string类:string的模拟实现

文章目录 &#x1f49e;1.浅拷贝&#x1f49e;2.深拷贝&#x1f49e;3. string类的模拟实现&#x1f49e;3.1 string的构造函数&#x1f49e;3.2 string的析构函数&#x1f49e;3.3 string的拷贝构造&#x1f49e;3.4 string的size&#x1f49e;3.5 string的operator[]&#x1…

详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送

在C#中&#xff0c;SendMessage方法是一个强大的工具&#xff0c;它允许我们与Windows API交互&#xff0c;模拟键盘和鼠标事件。本文将详细介绍如何使用SendMessage方法来发送鼠标和键盘消息。 1. SendMessage方法概述 SendMessage是Windows API中的一个函数&#xff0c;它用…

15.UE5等级、经验、血条,魔法恢复和消耗制作

2-17 等级、经验、血条、魔法消耗_哔哩哔哩_bilibili 目录 1.制作UI&#xff0c;等级&#xff0c;经验&#xff0c;血条 ​2.为属性面板绑定角色真实的属性&#xff0c;实现动态更新 3.魔法的消耗和恢复 1.制作UI&#xff0c;等级&#xff0c;经验&#xff0c;血条 创建控…

<项目代码>YOLOv8 玉米地杂草识别<目标检测>

YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv8具有更高的…

现场工程师日记-MSYS2迅速部署PostgreSQL主从备份数据库

文章目录 一、概要二、整体架构流程1. 安装 MSYS2 环境2. 安装postgresql 三、技术名词解释1.MSYS22.postgresql 四、技术细节1. 创建主数据库2.添加从数据库复制权限3. 按需修改参数&#xff08;1&#xff09;WAL保留空间&#xff08;2&#xff09;监听地址 4. 启动主服务器5.…

堆排序与链式二叉树:数据结构与排序算法的双重探索

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 引言 一.堆排序 1.1 版本一 核心概念 堆排序过程 1.2 版本二 堆排序函数 HeapSort 向下调整算法 AdjustDown 向上调整算法 AdjustUp 二.链式二叉树 2.1 前中后序遍历 链式二叉树的结构 创建链式二叉树 前序遍历…

【LinuxC编程】06 - 守护进程,线程

进程组和会话 概念和特性 进程组&#xff0c;也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在waitpid函数和kill函数的参数中都曾使用到。操作系统设计的进程组的概念&#xff0c;是为了简化对多个进程的管…

【MongoDB】MongoDB的聚合(Aggregate、Map Reduce)与管道(Pipline) 及索引详解(附详细案例)

文章目录 MongoDB的聚合操作&#xff08;Aggregate&#xff09;MongoDB的管道&#xff08;Pipline操作&#xff09;MongoDB的聚合&#xff08;Map Reduce&#xff09;MongoDB的索引 更多相关内容可查看 MongoDB的聚合操作&#xff08;Aggregate&#xff09; 简单理解&#xff…

Python的函数(补充浅拷贝和深拷贝)

一、定义 函数的定义&#xff1a;实现【特定功能】的代码块。 形参&#xff1a;函数定义时的参数&#xff0c;没有实际意义 实参&#xff1a;函数调用/使用时的参数&#xff0c;有实际意义 函数的作用&#xff1a; 简化代码提高代码重用性便于维护和修改提高代码的可扩展性…

Unity常见问题合集(一)

PS&#xff1a;不定期更新...... 目录 &#xff08;1&#xff09;无法关闭自动编译&#xff08;Edit — Preference — General — Auto Refresh&#xff09; &#xff08;1&#xff09;无法关闭自动编译&#xff08;Edit — Preference — General — Auto Refresh&#xff0…

HTB:Sightless[WriteUP]

目录 连接至HTB服务器并启动靶机 使用nmap对靶机TCP端口进行开放扫描 继续使用nmap对靶机开放的TCP端口进行脚本、服务扫描 首先尝试对靶机FTP服务进行匿名登录 使用curl访问靶机80端口 使用浏览器可以直接访问该域名 使用浏览器直接访问该子域 Getshell 横向移动 查…

深度学习-神经网络基础-网络搭建-损失函数-网络优化-正则化方法

一. 神经网络搭建和参数计算 一个继承(nn.model), 两个方法(init, forward) 简介 在pytorch中定义深度神经网络其实就是层堆叠的过程&#xff0c;继承自nn.Module&#xff0c;实现两个方法&#xff1a; init方法中定义网络中的层结构&#xff0c;主要是全连接层&#xff0c;…

全彩LED显示屏有几种安装方式?

全彩LED显示屏的安装方式多样&#xff0c;根据不同的使用场景和安装环境&#xff0c;可以选择最合适的安装方法。以下是一些常见的全彩LED显示屏安装方式&#xff1a; 室内显示屏安装方式 吊装&#xff1a;适用于室内承重混凝土顶&#xff0c;可以使用标准吊件&#xff0c;吊杆…

ZISUOJ 2024算法基础公选课练习二

一、前言 先把代码丢上来&#xff0c;后续再补上思路 二、题目总览 三、具体题目 3.1 问题 A: 成绩排序1 参考代码 简单排序 #include <bits/stdc.h> using i64 long long;int main() {std::cin.tie(nullptr)->sync_with_stdio(false);int t 1;std::cin >&g…