qt5-入门-自定义委托-简单例子

news2024/11/27 6:32:33

参考:
Qt 自定义委托_w3cschool
https://www.w3cschool.cn/learnroadqt/ov8h1j4z.html

C++ GUI Programming with Qt 4, Second Edition

本地环境:
win10专业版,64位,Qt 5.12


理论知识

Qt的model/view架构中,view只是1.对model数据的展示 2.处理用户输入。但是view只是讲用户输入委托给delegate处理

在Qt中,委托(Delegate)是一种用于控制如何显示和编辑视图中的数据的机制。它允许我们:对于不同的单元格,可以:

  • 自定义不同的外观,比如使用自定义的图标、颜色或对齐方式
  • 自定义不同的行为,比如为某些单元格提供特殊的编辑器,比如自定义的下拉列表、输入控件

委托和视图之间的区别在于:

  • 视图负责显示和编辑数据,而委托负责定义和实现如何显示和编辑特定单元格。
  • 视图是整个可见区域,如QTableViewQTreeView,而委托是针对特定单元格的。

Qt 4.4版本之后提供了两个可以被继承的 delegate 类:QItemDelegateQStyledItemDelegate。默认的 delegate 是 QStyledItemDelegate

这两个类可以被相互替代,主要区别在于,QStyledItemDelegate 使用当前的风格(style)去绘制组件。所以,在自定义 delegate 或者需要使用 Qt style sheets 时,建议使用 QStyledItemDelegate 作为父类。使用这两个类的代码通常是一样的,除了需要使用 style进行绘制的部份。如果你希望为 view item 自定义绘制函数,最好实现一个自定义的 style。这个你可以通过 QStyle 类来实现。

如果 delegate 没有支持为你的数据类型进行绘制,或者你希望自己绘制 item,那么就可以继承 QStyledItemDelegate 类,并且重写 paint() 或者还需要重写 sizeHint() 函数。paint() 函数会被每一个 item 独立调用,而 sizeHint()函数则可以定义每一个 item 的大小。在重写 paint() 函数的时候,通常需要用 if 语句找到你需要进行渲染的数据类型并进行绘制,其他的数据类型需要调用父类的实现进行绘制。

一个自定义的 delegate 也可以直接提供一个编辑器,而不是使用内置的编辑器工厂(editor item factory)。如果你需要这种功能,那么需要实现一下几个函数:

  • createEditor():返回修改数据的组件;
  • setEditorData():为 editor 提供编辑的原始数据;
  • updateEditorGeometry():保证 editor 显示在 item view 的合适位置以及大小;
  • setModelData():根据 editor 的数据更新 model 的数据。

实现效果

假设有一个table,每个单元格显示的是当前数据的平方值(原始数据是1~5)
在这里插入图片描述
双击单元格,可以编辑,编辑完成后立刻显示。
在这里插入图片描述
在这里插入图片描述

实现

model

#ifndef CUSTOMTABLEMODEL_H
#define CUSTOMTABLEMODEL_H

#include <QAbstractTableModel>

class CustomTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit CustomTableModel(QObject* parent = nullptr)
        : QAbstractTableModel(parent)
    {
        // 初始化数据
        m_data << 1 << 2 << 3 << 4 << 5;
    }

    int rowCount(const QModelIndex& parent = QModelIndex()) const override
    {
        return m_data.size();
    }

    int columnCount(const QModelIndex& parent = QModelIndex()) const override
    {
        return 1;
    }

    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override
    {
        if (!index.isValid())
            return QVariant();

        if (role == Qt::DisplayRole) {
            return m_data.at(index.row());
        }

        return QVariant();
    }

    Qt::ItemFlags flags(const QModelIndex& index) const override
    {
        if (!index.isValid())
            return Qt::NoItemFlags;

        return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
    }

    bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override
    {
        if (index.isValid() && role == Qt::EditRole) {
            m_data.replace(index.row(), value.toInt());
            emit dataChanged(index, index);
            return true;
        }

        return false;
    }

private:
    QList<int> m_data;
};

#endif // CUSTOMTABLEMODEL_H

自定义委托

#ifndef SQUAREDELEGATE_H
#define SQUAREDELEGATE_H

#include <QStyledItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>
#include <QPainter>



class SquareDelegate : public QStyledItemDelegate
{
public:
    QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        return QStyledItemDelegate::sizeHint(option, index);
    }

    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {

        if (index.isValid()) {
            int value = index.model()->data(index).toInt();
            QString text = QString::number(value * value);
            painter->save();
            painter->drawText(option.rect, Qt::AlignCenter, text);
            painter->restore();
        } else {
        	// 这是绘制原来的数据。如果原数据和平方值都要显示,可以把这句放在最前面
            QStyledItemDelegate::paint(painter, option, index);
        }
    }

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        QSpinBox* editor = new QSpinBox(parent);
        editor->setMinimum(0);
        editor->setMaximum(100);
        return editor;
    }

    void setEditorData(QWidget* editor, const QModelIndex& index) const override
    {
        int value = index.model()->data(index).toInt();
        QSpinBox* spinBox = static_cast<QSpinBox*>(editor);
        spinBox->setValue(value);
    }

    void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override
    {
        /*
        QSpinBox* spinBox = static_cast<QSpinBox*>(editor);
        int value = spinBox->value();
        model->setData(index, value);
        */

        if (QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor)) {
            int value = spinBox->value();
            model->setData(index, value, Qt::EditRole);
        } else {
            QStyledItemDelegate::setModelData(editor, model, index);
        }
    }

    void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override
    {
        editor->setGeometry(option.rect);
    }


};


#endif // SQUAREDELEGATE_H

main

QTableView* tableView = new QTableView;
SquareDelegate* delegate = new SquareDelegate;
// 设置委托
tableView->setItemDelegate(delegate);
CustomTableModel* model = new CustomTableModel;
// 设置模型
tableView->setModel(model);
tableView->show();

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

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

相关文章

Mysql实战--为什么表数据删掉一半,表文件大小不变

经常会有同学来问我&#xff0c;我的数据库占用空间太大&#xff0c;我把一个最大的表删掉了一半的数据&#xff0c;怎么表文件的大小还是没变&#xff1f; 那么今天&#xff0c;我就和你聊聊数据库表的空间回收&#xff0c;看看如何解决这个问题。 这里&#xff0c;我们还是针…

2024年04月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2024年04月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…

数据库之迁移常规操作(Postgresql篇)

一、docker安装postgresql 1. 拉取postgres docker pull postgres2. 创建容器 注&#xff1a;默认登录账户postgres, 密码123456, 对外暴露端口5432, 卷映射&#xff1a;可在物理机修改数据库配置文件 引用文章查看&#x1f440; docker run --name postgres -e POSTGRES_P…

《养育女孩》:教你如何培养独立、自信的女儿

粉丝福利&#xff1a;公众号内回复3可免费获取本期《养育女孩》的读书音频哦。​ 养育女孩&#xff0c;是一本由澳大利亚作家史蒂夫比达尔夫所著的育儿书籍。书中深入探讨了女孩的心理发展&#xff0c;以及父母和教育者如何支持她们成长为强大、自信和健康的女性。 比达尔夫将…

设计模式7--建造者模式

定义 案例一 案例二 优缺点

k8s笔记28--快速在ubuntu上基于二进制和源码安装containerd

k8s笔记28--快速在ubuntu上基于二进制和源码安装containerd 介绍containerd 安装方法二进制文件安装源码构建安装 注意事项说明 介绍 Containerd是一个工业标准的容器运行时&#xff0c;它强调简单、健壮和可移植性。它可作为Linux和Windows的守护进程&#xff0c;能管理主机系…

RK3588 NPU研究(一)

使用NPU进行AI计算&#xff0c;具体对应模型推理 对应代码位置 hardware/rockchip/rknpu2 examples: yolo5 编译 下载NDK工具https://developer.android.google.cn/ndk/downloads?hlzh-cn源码中使用16b&#xff0c;测试可以使用16/17/18/19/20&#xff0c;不可以使用21&…

C语言-atoi函数的模拟

模拟术语讲解 首先&#xff0c;需要定义一个标志位变量sign&#xff0c;用于表示转换结果的合法性1。定义一个函数My_atoi&#xff0c;用于实现atoi的功能1。在My_atoi函数中&#xff0c;首先遍历字符串&#xff0c;直到遇到第一个非空格字符1。如果第一个字符不是数字或正负号…

ROS安装教程(鱼香ROS快捷版)

文章目录 前言一、ROS版本二、ROS安装1.添加ROS源2.添加密钥3.安装ROS4.安装python依赖包&#xff08;可选&#xff09;5.初始化rosdep6.ROS 测试 总结 前言 对于初学者来说&#xff0c;ROS的安装往往是一个令人头疼的问题&#xff0c;复杂的步骤和网络问题常常成为入门的第一…

kubernetes-dashboard 安装配置

k8s 1.23以上的版本 https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml 执行命令&#xff1a; kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml 安装完成后&#x…

FSH6罗德与施瓦茨FSH6频谱分析仪

181/2461/8938产品概述&#xff1a; R&S FSH6频谱分析仪坚固耐用、方便易用&#xff0c;专为野外使用而设计。它重量轻、操作简单、设计合理且具有大量测量功能&#xff0c;是任何需要高效测量仪器进行户外工作的人不可或缺的工具。 R&S FSH6是一款手持式频谱分析仪&…

项目:USB键盘和鼠标的复合设备

我们的复合设备使用一个物理设备就可以完成多个功能。 使用复合设备同时完成USB键盘和鼠标功能&#xff0c;它的主要实现方式有两种&#xff0c; 第一个就是我们将多个设备描述符合并成一个&#xff0c;这个相对比较简单&#xff0c;我们只要根据相应的报告描述符处理数据就可…

基于springboot实现在线文档管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现在线文档管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;在线文档管理当然也不能排除在外。在线文档管理系统是以实际运用为开发背景&am…

3分钟教你最大化利用APP消息推送(Push)在运营中的优势

推送通知是指运营团队通过自有产品或外部工具&#xff0c;主动向用户的移动设备发送信息。用户可以直接在手机的锁屏和通知中心看到这些推送通知&#xff0c;点击通知中心的相关内容可以激活应用并跳转至特定页面。例如&#xff0c;我们在手机锁屏时接收到的微信消息&#xff0…

SSM框架学习——MyBatis关联映射

MyBatis关联映射 为什么要关联映射 实际开发中&#xff0c;对数据库操作常常会涉及多张表&#xff0c;所以在OOP中就涉及对象与对象的关联关系。针对多表操作&#xff0c;MyBatis提供关联映射。 关联关系概述 一对一&#xff1a;A类中定义B类的属性b&#xff0c;B类中定义A…

电脑常见故障检测方法与对应问题分析说明

电脑常见故障检测方法与对应问题分析说明 前言说明1、机器无法开机故障2、屏幕无法显示3、无法联网4、能开机但是无法进入系统&#xff0c;提示not boot5、USB接口无法识别U盘 前言说明 本文为小白向&#xff0c;许多内容属于经验学而非科学&#xff0c;还望大佬们轻喷。 如上…

Verilog语法之always语句学习

always语法是Verilog_HDL中最常用的一种语法。 always过程语句和语句块组成的&#xff0c;语法格式如下所示。 always(敏感信号1 or 敏感信号2.....) always实现组合逻辑和时序逻辑。用always实现组合逻辑要将所有的敏感信号加入敏感列表中&#xff1b;用always实现时序逻辑时…

为什么都说”一入Java深似海“?

引言 在当今数字化时代&#xff0c;编程已经成为一项至关重要的技能。而在众多编程语言中&#xff0c;Java以其广泛的应用领域和强大的功能特性&#xff0c;吸引了无数开发者的目光。无论是Web开发、移动应用还是大数据处理&#xff0c;Java都发挥着举足轻重的作用。然而&…

GDAL源码剖析(一)

GDAL源码剖析&#xff08;一&#xff09;_gdal 源码-CSDN博客 一、GDAL简介 GDAL官方网站http://www.gdal.org/&#xff0c;本文章中的基本内容都是参照官网中的信息&#xff0c;如有错误或者与官网中的内容冲突&#xff0c;以官网中的为正确。 在开始文章之前&#xff0c;我…

探索数字物流技术 2024中国国际展览会与您相约七月杭州

数字贸易创新引领合作动能 《十四五规划》明确指出关于“加快数字化发展&#xff0c;建设数字中国”要求&#xff0c;积极为全国数字物流链转型革新试水探路。全力发展以数字化为引领的现代产业体系,打造面向未来、全球的数字物流技术变革高地。数字化成为了物流和供应链企业推…