鼠标在QTreeView、QTableView、QTableWidget项上移动,背景色改变

news2024/12/25 13:36:43

目录

1. 前言

2. 需求

3. 功能实现   

3.1. 代码实现

3.2. 功能讲解

4. 附录


1. 前言

       本博文用到了Qt的model/view framework框架,如果对Qt的“模型/视图/委托”框架不懂,本博文很难读懂。如果不懂这方面的知识,请在Qt Assistant 中输入Model/View Programming 学习了解。读者本机Qt安装目录下的Examples\Qt-XX.XX.XX\widgets\itemviews目录下有很多model/view framework的例子,可以进行自学了解,其中XX.XX.XX为Qt的版本号,如:5.14.1。
       因为QColumnView、QHeaderView、QListView、QTableView、QTreeView、QListWidget 、QUndoView、QTableWidget、QTreeWidget都是从QAbstractItemView继承,故本博文所说的技术点也适用于这些类,本博文以QTableView类来讲解。

2. 需求

      业务需求是:鼠标在QTableView的项上方移动(不是按下)时,项背景色改变。即像下面那样的效果:

3. 功能实现   

3.1. 代码实现

logTableView.h:

#ifndef LOG_TABLE_VIEW_H
#define LOG_TABLE_VIEW_H

#include <QTableView>


class CLogTableView : public QTableView
{
    Q_OBJECT

public:
    explicit CLogTableView(QWidget *parent = nullptr);

signals:

   // void mouseEnterItemSigal(const QModelIndex &);
private:

    /* 注意:不能重载mouseMoveEvent函数,否则QAbstractItemView::entered信号不会触发,
            如果非要重载mouseMoveEvent函数,则在该函数中发送自定义鼠标进入视图项的信号,如本 
            类中的mouseEnterItemSigal信号
    */
    //virtual void mouseMoveEvent(QMouseEvent *event) override;
};

#endif // LOG_TABLE_VIEW_H

logTableView.cpp:

#include "logTableView.h"
#include<QMouseEvent>
CLogTableView::CLogTableView(QWidget *parent)
    : QTableView(parent)
{
    setMouseTracking(true);
}

/* 注意:不能重载mouseMoveEvent函数,否则QAbstractItemView::entered信号不会触发,
        如果非要重载mouseMoveEvent函数,则在该函数中发送自定义鼠标进入视图项的信号,如本类
        中的mouseEnterItemSigal信号
*/
//void CLogTableView::mouseMoveEvent(QMouseEvent *event)
//{
//   auto pos = event->pos();
//   auto modelIndex = this->indexAt(pos);
//  // emit mouseEnterItemSigal(modelIndex);
//   //update();
//}
logTableModel.h:
#ifndef LOGTABLEMODEL_H
#define LOGTABLEMODEL_H

#include <QAbstractTableModel>

class CLogTableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit CLogTableModel(QObject *parent = nullptr);

public:

    /*功能:向外层发送日志信息
     *参数1:日志具体内容
     *参数2:日志来源的模块,如:设备管理模块
     *参数3:日志级别
    */
    void addLog(const QString&qsLog, const QString&qsLogSrcModule, int nLogEvel);

private:
    // Basic functionality:
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
private:
    QVariant doDecorationRole(int nLogEvel) const;

    QVariant doForegroundRole(int nLogEvel) const;


private:

    QStringList m_lstLogInfo;

};

#endif // LOGTABLEMODEL_H
logTableModel.cpp:
#include "logTableModel.h"
#include<QIcon>
#include<QBrush>

CLogTableModel::CLogTableModel(QObject *parent)
    : QAbstractTableModel(parent)
{
    
}

int CLogTableModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return static_cast<int>(m_lstLogInfo.size() / 3);
}

int CLogTableModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return 1;
}

QVariant CLogTableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    auto rowIndex = index.row();
    auto rowCount = m_lstLogInfo.size() / 3;
    if((rowIndex < 0) || ( rowCount <= rowIndex))
    {
        Q_ASSERT(0);
        return QVariant();
    }

    // 以下这么做的目的是为了让最近产生的日志排在最顶部,最久产生的日志排在最底部
    auto logIndex = 3 * rowIndex;
    auto qsLog = m_lstLogInfo[logIndex];
    auto qsLogSrcModule = m_lstLogInfo[logIndex + 1];
    auto nLogEvel = m_lstLogInfo[logIndex + 2].toInt();

    auto columnIndex = index.column();

    switch (role)
    {
        case Qt::DisplayRole:
        {
            switch (columnIndex)
            {
                case 0:
                {
                   return qsLog;
                }
            }
        }
        break;
        case Qt::DecorationRole:
        {
            return doDecorationRole(nLogEvel);
        }
        break;
        case Qt::ForegroundRole:
        {
           return doForegroundRole(nLogEvel);
        }
        break;

    } // end switch role

    return QVariant();
}

Qt::ItemFlags CLogTableModel::flags(const QModelIndex &index) const
{
    Q_UNUSED(index);

    return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}

QVariant CLogTableModel::doForegroundRole(int nLogEvel) const
{
    switch (nLogEvel)
    {
        case 1:
        {
            return QBrush(Qt::yellow);
        }
        break;
        case 2
        case 3:
        {
            return QBrush(Qt::red);
        }
        break;
        default:
        {

        }
        break;
    }

    return QVariant();
}

QVariant CLogTableModel::doDecorationRole(int nLogEvel) const
{
    QIcon icon;
    switch (nLogEvel)
    {
        case 0:
        {
            icon.addFile(QLatin1String(":/logWnd/image/log/normal.png"));
            return icon;
        }
        break;
        case 1:
        {
            icon.addFile(QLatin1String(":/logWnd/image/log/warn.png"));
            return icon;
        }
        break;
        case 2:
        case 3:
        {
            icon.addFile(QLatin1String(":/logWnd/image/log/error.png"));
            return icon;
        }
        break;
        default:
        {
            return icon;
        }
       break;
    }

    return QVariant();
}


void CLogTableModel::addLog(const QString&qsLog, const QString&qsLogSrcModule, int nLogEvel)
{
    beginResetModel();

    if(m_lstLogInfo.size() >= 50)
    {
        m_lstLogInfo.clear();
    }

    auto qsLogEvel = QString::number(nLogEvel);
    m_lstLogInfo.insert(0, qsLog);
    m_lstLogInfo.insert(1, qsLogSrcModule);
    m_lstLogInfo.insert(2, qsLogEvel);

    endResetModel();
}

logItemDelegate.h:
#ifndef CLOGITEMDELEGATE_H
#define CLOGITEMDELEGATE_H

#include <QStyledItemDelegate>

class CLogItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    explicit CLogItemDelegate(QObject *parent = nullptr);

public:
     void enterItem(const QModelIndex &index);
private:
    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const override;

private:

     QModelIndex m_curIndex;
};

#endif // CLOGITEMDELEGATE_H

logItemDelegate.cpp:

#include "logItemDelegate.h"
#include<QPainter>

CLogItemDelegate::CLogItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

void CLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (m_curIndex.row() == index.row())
     {
        // 可以把第2个参数换成你想要的任何颜色
        painter->fillRect(option.rect, option.palette.highlight());
    }

    QStyledItemDelegate::paint(painter, option, index);
}


void CLogItemDelegate::enterItem(const QModelIndex &index)
{
    if(!index.isValid())
    {
        return;
    }

    m_curIndex = index;
}

调用方代码如下:

#include "logWnd.h"
#include "ui_logWnd.h"
#include<QPainter>
#include "logTableModel.h"
#include"logItemDelegate.h"

CLogWnd::CLogWnd(QWidget *parent) : QWidget(parent),
    ui(new Ui::CLogWnd)
{   
    ui->setupUi(this);
    this->resize(650, 1200);
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Window);

    // 创建模型类
    m_pLogTableModel = new CLogTableModel(this);
    ui->logTv->setModel(m_pLogTableModel);

    // 创建委托类
    auto pLogItemDelegate = new CLogItemDelegate(this);
    ui->logTv->setItemDelegate(pLogItemDelegate);

    ui->logTv->horizontalHeader()->hide();
    ui->logTv->verticalHeader()->hide();
    ui->logTv->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);

    // 连接entered信号
    connect(ui->logTv, &CLogTableView::entered, pLogItemDelegate, &CLogItemDelegate::enterItem);

    // connect(ui->logTv, &QAbstractItemView::mouseEnterItemSigal, pLogItemDelegate, &CLogItemDelegate::enterItem);

}

void CLogWnd::addLog(const QString&qsLog, const QString&qsLogSrcModule, int nLogEvel)
{
    m_pLogTableModel->addLog(qsLog, qsLogSrcModule, nLogEvel);
}

 调用:

auto pLogWnd = new CLogWnd(this);
pLogWnd->addLog("a", "a1", 0);
pLogWnd->addLog("b", "b1", 2);
pLogWnd->addLog("c", "c1", 2;

 

3.2. 功能讲解

        功能实现说明如下:

  • CLogTableView类中将鼠标跟踪属性设置为true,否则不会捕捉QAbstractItemView类的entered信号。
  • 在槽函数CLogItemDelegate类的enterItem记录鼠标光标所在项目的模型索引。
  • 在委托类CLogItemDelegate中的paint函数中检测发现如果是鼠标光标所在项目的模型索引,则改变该项的背景色,否则就采用默认背景色。
  • 不能重载mouseMoveEvent函数,否则QAbstractItemView::entered信号不会触发,如果非要重载mouseMoveEvent函数,则在该函数中发送自定义鼠标进入视图项的信号,如本类中的mouseEnterItemSigal信号。

4. 附录

      现实中,经常发现QAbstractItemView类的entered信号不会激发,解决方法,参见:

QAbstractItemView类如:QTreeView、QTableView、QTableWidget不发送entered信号的问题解决

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

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

相关文章

[iOS]高版本MacOS运行低版本Xcode

Xcode 版本支持文档 目的&#xff1a; 在MacOS Sonoma 系统上安装 Xcode14.3.1 第一步 先在Xcode下载一个Xcode14.3.1的压缩包 第二步 本地解压Xcode&#xff0c;将外层目录名变更为Xcode_14.3.1&#xff0c;将文件拷贝到 /Applications目录下。 第三步 变更xcode-sel…

Docker基础教程 - 12 常用容器部署-Nginx

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 12 常用容器部署-Nginx 下面介绍一下常用容器的部署。可以先简单了解下&#xff0c;用到再来详细查看。 在 Docker 中部署 Nginx&#xff0c;并通过挂载方式将 Nginx 的配置文件和站点目录挂…

leecode算法二

滑动窗口/双指针 滑动窗口 得到K个黑块的最少涂色次数 滑动窗口法 方法一 方法二 水果成篮 二叉树 概念 中序遍历 前序遍历和后序遍历无非就是把result.add房价加在前面和后面。 层序遍历 广度优先算法 深度优先算法 线段树 我的日程安排表II

Day36:安全开发-JavaEE应用第三方组件Log4j日志FastJson序列化JNDI注入

目录 Java-项目管理-工具配置 Java-三方组件-Log4J&JNDI Java-三方组件-FastJson&反射 思维导图 Java知识点&#xff1a; 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用…

[Unity3D]--更换天空盒子

我们原来的天空盒子是这样的。 感觉不是特别满意&#xff0c;想换一个更好看的。 去资源商店找个好看的 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 例如这个 然后在Window>Rendering>Lighting里的环境选项里更换材质 更换&#xff1a; ​ …

SpringBoot注解--08--注解@JsonInclude

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 JsonInclude注解是jackSon中最常用的注解之一&#xff0c;是为实体类在接口序列化返回值时增加规则的注解 1.JsonInclude用法2.JsonInclude注解中的规则有 案例需求…

卷积神经网络CNN(一篇文章 理解)

目录 一、引言 二、CNN算法概述 1 卷积层 2 池化层 3 全连接层 三、CNN算法原理 1 前向传播 2 反向传播 四、CNN算法应用 1 图像分类 2 目标检测 3 人脸识别 六、CNN的优缺点 优点&#xff1a; 1 特征提取能力强 2 平移不变性 3 参数共享 4 层次化表示 缺点…

机器学习-04-分类算法-01决策树案例

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中分类算法&#xff0c;本篇为分类算法开篇与决策树部分。 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 懂业务会选择合适的算法数据处理算法训练算法调优算法融合 算法评估持续调优工程…

一次因PageHelper引起的多线程复用问题的排查和解决方案

目录导航 导读01.Problem Description02.Problem inspection Steps1. Code Review2. Log Check and Prove 03.Analysis Steps1. How to use PageHelpera. Github Official Document Linkb. Analysis Source Code of PageHelper 2. How to solve the problem 导读 本文不仅对遇…

作用域链的理解(超级详细)

文章目录 一、作用域全局作用域函数作用域块级作用域 二、词法作用域三、作用域链 一、作用域 作用域&#xff0c;即变量&#xff08;变量作用域又称上下文&#xff09;和函数生效&#xff08;能被访问&#xff09;的区域或集合 换句话说&#xff0c;作用域决定了代码区块中变…

狂飙Linux平台,PostgreSQL16部署大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

生成式 AI:使用 Pytorch 通过 GAN 生成合成数据

导 读 生成对抗网络&#xff08;GAN&#xff09;因其生成图像的能力而变得非常受欢迎&#xff0c;而语言模型&#xff08;例如 ChatGPT&#xff09;在各个领域的使用也越来越多。这些 GAN 模型可以说是人工智能/机器学习目前主流的原因&#xff1b; 因为它向每个人&#xff0…

vue+elementUI用户修改密码的前端验证

用户登录后修改密码&#xff0c;密码需要一定的验证规则。旧密码后端验证是否正确&#xff1b;前端验证新密码的规范性&#xff0c;新密码规范为&#xff1a;6-16位&#xff0c;至少含数字/字母/特殊字符中的两种&#xff1b;确认密码只需要验证与新密码是否一致&#xff1b; 弹…

数据结构——二叉树的遍历【前序、中序、后序】

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

java-教师管理系统全部资料-164-(代码+说明)

转载地址: http://www.3q2008.com/soft/search.asp?keyword教师管理系统全部资料 第一章 综 述 2 1.1 背景说明 2 1.2 设计目的 2 1.3 系统目标 3 1.4 设计指导思想 3 1.5 开发技术概论 3 1.5.1 JSP技术 3 1.5.2 JAVA 4 1.5.3 JavaBeans 5 1.5.4 Servlet 5 1.5.5 Tomcat应用服…

纯前端Web网页内嵌AutoCAD,支持在线编辑DWG、dxf等文档。

随着企业信息化的发展&#xff0c;越来越多的企业有网页在线浏览和编辑DWG文档&#xff08;AutoCad生成的文档&#xff09;的需求&#xff0c;但是新版浏览器纷纷取消了对NPAPI插件的支持&#xff0c;导致之前一些可以在线在线浏览和编辑DWG文档纷纷失效&#xff0c;今天推荐一…

王道机试C++第 5 章 数据结构二:队列queue和21年蓝桥杯省赛选择题Day32

目录 5.2 队列 1&#xff0e;STL-queue 课上演示&#xff1a; 基本代码展示&#xff1a; 2. 队列的应用 例:约瑟夫问题 No. 2 题目描述&#xff1a; 思路提示&#xff1a; 代码展示&#xff1a; 例&#xff1a;猫狗收容所 题目描述&#xff1a; 代码表示&#xff1…

【深度学习】线性回归

Linear Regression 一个例子线性回归机器学习中的表达评价函数好坏的度量&#xff1a;损失&#xff08;Loss&#xff09;损失函数&#xff08;Loss function&#xff09;哪个数据集的均方误差 (MSE) 高 如何找出最优b和w?寻找最优b和w如何降低损失 (Reducing Loss)梯度下降法梯…

【毕设级项目】基于AI技术的多功能消防机器人(完整工程资料源码)

基于AI技术的多功能消防机器人演示效果 竞赛-基于AI技术的多功能消防机器人视频演示 前言 随着“自动化、智能化”成为数字时代发展的关键词&#xff0c;机器人逐步成为社会经济发展的重要主体之一&#xff0c;“机器换人”成为发展的全新趋势和时代潮流。在可预见的将来&#…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《计及台区资源聚合功率的中低压配电系统低碳优化调度方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…