QT笔记- QTreeView设置三态setAutoTristate() 树形视图自动复选框——源码分享

2023-11-06

说明

        Qt中函数QStandardItem::setAutoTristate()无实际功能,仅作为一个布尔标记。若要实现自动三态复选框功能,需要自行代码构建。

        本文通过编写两个派生类,完成了这个功能。类源码和一个示例如下:

源码

//[自动三态item](用于AutoTristateTreeView)
#include "QStandardItem"
class AutoTristateItem : public QStandardItem
{
    struct{
        int oldCheckState;
        bool oldShock;
    }info;
    void setAutoTristate(bool tristate);
public:
    AutoTristateItem() : QStandardItem()
    {info.oldCheckState = checkState(); info.oldShock = isAutoTristate();}
    AutoTristateItem(const QString &text) : QStandardItem(text)
    {info.oldCheckState = checkState(); info.oldShock = isAutoTristate();}
    int oldCheckState(){return info.oldCheckState;}
    void updateOldCheckState()
    {info.oldCheckState = checkState();}//setCheckState()后一般要调用一下该函数, 否则下一次可能不会触发后面的树

    //触发当前item之下的所有树的check box与当前item保持一致
    void shocking(){info.oldShock = isAutoTristate(); QStandardItem::setAutoTristate(!info.oldShock);}
    bool oldShock(){return info.oldShock;}
};

//[自动三态树形视图]
#include "QTreeView"
class AutoTristateTreeView : public QTreeView
{
    Q_OBJECT
public:
    enum AutoMode{
        AutoTristateMode,//必须同时设置setUserTristate(true)
        AutoTwoStateMode,//必须同时设置setUserTristate(false)
        None
    };
    explicit AutoTristateTreeView(QWidget *parent = 0) : QTreeView(parent){}
    virtual void setModel(QStandardItemModel *model);
    AutoMode autoMode(){return info.autoMode;}
    void setAutoMode(AutoMode mode){info.autoMode = mode;}
signals:
    void tristate_changed_(AutoTristateItem *item);//发送出check box发生变动的item
private slots:
    void _item_changed(QStandardItem *item);
private:
    struct{
        AutoMode autoMode = None;
    }info;
};

实现:

void AutoTristateTreeView::setModel(QStandardItemModel *model)
{
    QTreeView::setModel(model);
    connect(model, &QStandardItemModel::itemChanged, this, &AutoTristateTreeView::_item_changed);
}

void AutoTristateTreeView::_item_changed(QStandardItem *item)
{
    //    cout << "AutoTristateTreeView::_item_changed - " << endl;
    if(((AutoTristateItem *)item)->oldCheckState() != item->checkState() ||//区分是否是checked的改变
            ((AutoTristateItem *)item)->oldShock() != item->isAutoTristate()){
        if(((AutoTristateItem *)item)->oldCheckState() != item->checkState()){
            ((AutoTristateItem *)item)->updateOldCheckState();
            emit tristate_changed_((AutoTristateItem *)item);
            cout << "AutoTristateTreeView::_item_changed - Changed item:"
                 << qPrintable(item->text()) << endl;
        }
        for(int i = 0; i < item->rowCount(); ++i) {//只需控制其直接child即可
            switch (info.autoMode) {
            case AutoTristateMode:
                if(item->child(i)->isUserTristate()){
                    if(item->child(i)->checkState() == item->checkState())
                        ((AutoTristateItem *)(item->child(i)))->shocking();
                    else item->child(i)->setCheckState(item->checkState());
                }
                break;
            case AutoTwoStateMode:
                if(!item->child(i)->isUserTristate()){
                    if(item->child(i)->checkState() == item->checkState())
                        ((AutoTristateItem *)(item->child(i)))->shocking();
                    else item->child(i)->setCheckState(item->checkState());
                }
                break;
            default:
                break;
            }
        }
    }
}

示例:

        AutoTristateTreeView类中带有一个信号函数tristate_changed_(),用于将复选框发生变动的item发送出去。下面示例中使用了这个信号,用于将触发的item输出到窗口,但这里并没有贴出其槽函数的实现。

QStandardItemModel * model = new QStandardItemModel;
AutoTristateItem * item = new AutoTristateItem("test");
item->setCheckable(true);
item->setUserTristate(true);
AutoTristateItem * item2 = new AutoTristateItem("test_2");
item2->setCheckable(true);
item2->setUserTristate(true);
item->appendRow(item2);
AutoTristateItem * item3 = new AutoTristateItem("test_3");
item3->setCheckable(true);
item3->setUserTristate(true);
item->appendRow(item3);
AutoTristateItem * item4 = new AutoTristateItem("test_4");
item4->setCheckable(true);
item4->setUserTristate(true);
item3->appendRow(item4);
model->appendRow(item);

ui->treeView->setModel(model);
ui->treeView->setAutoMode(AutoTristateTreeView::AutoTristateMode);
connect(ui->treeView, &AutoTristateTreeView::tristate_changed_, this, &Widget::_tristate_changed);

调试:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QT笔记- QTreeView设置三态setAutoTristate() 树形视图自动复选框——源码分享 的相关文章

随机推荐

  • Python金融数据分析(一)

    Python提供了数据挖掘和许多机器学习算法的实现 准备数据 Tickhistory的数据可以精确到每个tick 我就导出一个月的XAU日线OHLC数据 样本如下 Date Open High Low Close Volume 201709
  • session,cookie,url传递的优缺点以及示例代码

    URL传递 Cookie传递和Session传递都是常见的Web开发中用于传递数据的方式 它们各自有自己的优缺点 下面是它们的一些特点和适用场景 URL传递 优点 简单易用 不需要特殊技术 只需要使用URL即可传递数据 可以将数据传递给不同
  • php基于哈希算法出现的强弱比较漏洞

    文章目录 前言 哈希算法 php与哈希算法 php弱比较 0X01 0X02 php强比较 前言 文章同步于我的个人博客https quan9i top phpcompare 在看一些ctf简单题时发现大多用到了 和 这些 因此对其进行总结
  • 源码分析【ReentrantLock】原理

    ReentrackLock底层原理 ReentrackLock介绍 非公平锁VS公平 非公平锁 公平锁 可打断VS不可打断 不可打断 默认 可打断模式 锁超时 条件变量 如何在synchronized和ReentrantLock之间进行选择
  • Python中的retry

    1 通过语言特性实现 for i in range 0 100 while True try do stuff except SomeSpecificException continue break 2 通过第三方库实现 pip insta
  • 前瞻洞察|DoH,隐蔽隧道又添利器,强盾在何方?

    DoH这个词对于很多安全从业人员并不是个新词 但对其前世今生能洞若观火的却不多 本期前瞻洞察将从DNS的隐私与安全问题出发 讲述DoH为什么诞生 DoH的出现到底利弊几何 对其弊端如何应对 为了便于读者理解 对于 何为隐蔽隧道 DoH如何成
  • loguru使用parse解析压缩日志文件(以zip为例)

    loguru保存到zip压缩文件 使用如下代码保存日志文件到zip压缩文件中 from loguru import logger import sys logger remove logger add my cal record filte
  • easyui 表头动态生成

    使用EasyUI实现列不固定的表格 需要引入easyUi中的jQuery easyui min js easyui css icon css 步骤如下 jsp页面 1 新建一个准备放table的div容器 div div 2 在页面加载好后
  • 【netty】Netty堆外内存泄露排查盛宴

    1 概述 转载 Netty堆外内存泄露排查盛宴 2 导读 Netty 是一个异步事件驱动的网络通信层框架 用于快速开发高可用高性能的服务端网络框架与客户端程序 它极大地简化了 TCP 和 UDP 套接字服务器等网络编程 Netty 底层基于
  • jQuery事件冒泡#change(fn)事件结合应用案例--校验用户名是否存在

    事件冒泡即当触发内部节点元素时 同时会触发外部与之关联的节点事件 取消事件冒泡 return false blur fn blur 与change 区别 1 blur fn 失去焦点 触发每一个匹配元素的blur事件 2 change fn
  • 硬件系统工程师宝典(4)-----传输过程的信号要如何描述?

    各位同学大家好 欢迎继续做客电子工程学习圈 今天我们继续来讲这本书 硬件系统工程师宝典 上篇我们说到为实现信号的有效传输 需要保证信号波形的完整和信号时序的完整 并且知道了从时域 频域两个角度去分析信号 那么 在传输过程的信号要如何描述 就
  • OpenGL案例2----keyBoard键盘交互和鼠标交互

    include
  • Docker安装MySQL并配置my.cnf

    1 创建一个临时的mysql 以便复制出my cnf等数据 docker run restart always d v opt data mysql var lib mysql p 3306 3306 name test mysql e M
  • 二进制、十进制、十六进制数值对照表

  • Pandas 日期处理:生成及去除工作日与节假日

    Pandas 日期处理 生成工作日与节假日 Pandas 提供了许多日期处理功能 使得处理时间序列数据变得容易 本文将介绍如何使用 Pandas 生成工作日和节假日 在进行实际操作前 请确保已安装了 Pandas 库 安装方法如下 pip
  • 音视频总结(1) -- 主流音视频平台研究与比较

    虽然本科专业就是图像通信 但是自己真正的从无到有 从0到1的主导和实现一个音视频平台 实现移动互联网时代的音视频通信却是在十几年之后 音视频的使用场景包括视频会议 直播和点播等 下面是对市场上已有产品的研究与调研 流行音视频产品 维基百科上
  • C/C++服务器和客户端交互笔记

    C C 服务器开发 网络与通信Socket Socket通信三要素 通信的目的地址 使用的端口号 http 80 smtp 25 使用的传输协议 TCP UDP nslookup xx 可以查询xx网址的IP地址 Socket通信模型 te
  • 关于qmake报错

    qmake could not find a Qt installation of 或 qmake could not exec usr lib x86 64 linux gnu qt4 bin qmake 或 qmake could no
  • UE5 MediaPlayer无法正确播放视频

    StreamMediaSource 播放流媒体源 流媒体源 Stream Media Source 是一种资源 允许你在虚幻引擎5 UE5 中流送支持的 URL格式视频 定义流后 你可以将其加载并使用 媒体播放器 资源在UE4中播放 并可
  • QT笔记- QTreeView设置三态setAutoTristate() 树形视图自动复选框——源码分享

    说明 Qt中函数QStandardItem setAutoTristate 无实际功能 仅作为一个布尔标记 若要实现自动三态复选框功能 需要自行代码构建 本文通过编写两个派生类 完成了这个功能 类源码和一个示例如下 源码 自动三态item