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

目录

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_OBJECTpublic: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_OBJECTpublic: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 rolereturn 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 2case 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_OBJECTpublic: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);}

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.mzph.cn/news/737014.shtml

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

相关文章

力扣大厂热门面试算法题 15-17

15. 三数之和&#xff0c;16. 最接近的三数之和&#xff0c;17. 电话号码的字母组合&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.11 可通过leetcode所有测试用例。 目录 15. 三数之和 解题思路 完整代码 Java Python ​…

Ubuntu 24.04 抢先体验换国内源 清华源 阿里源 中科大源 163源

Update 240307:Ubuntu 24.04 LTS 进入功能冻结期 预计4月25日正式发布。 Ubuntu22.04换源 Ubuntu 24.04重要升级daily版本下载换源步骤 (阿里源)清华源中科大源网易163源 Ubuntu 24.04 LTS&#xff0c;代号 「Noble Numbat」&#xff0c;即将与我们见面&#xff01; Canonica…

vue provide 与 inject使用

在vue项目中&#xff0c;如果遇到跨组件多层次传值的话&#xff0c;一般会用到vuex&#xff0c;或者其他第三方共享状态管理模式&#xff0c;如pinia等&#xff0c;但是对于父组件与多层次孙子组件时&#xff0c;建议使用provide 与 inject&#xff0c;与之其他方式相比&#x…

如何使用Everything+cpolar实现公网远程搜索下载内网储存文件资料

文章目录 前言1.软件安装完成后&#xff0c;打开Everything2.登录cpolar官网 设置空白数据隧道3.将空白数据隧道与本地Everything软件结合起来总结 前言 要搭建一个在线资料库&#xff0c;我们需要两个软件的支持&#xff0c;分别是cpolar&#xff08;用于搭建内网穿透数据隧道…

高分1、2号卫星原始遥感影像数据

高分一号 高分一号卫高分一号卫星是中国高分辨率对地观测系统的首发星&#xff0c;突破了高空间分辨率、多光谱与宽覆盖相结合的光学遥感等关键技术&#xff0c;设计寿命5至8年。 高分辨率对地观测系统工程是《国家中长期科学和技术发展规划纲要(2006&#xff5e;2020年)》确定…

StarRocks实战——欢聚集团极速的数据分析能力

目录 一、大数据平台架构 二、OLAP选型及改进 三、StarRocks 经验沉淀 3.1 资源隔离&#xff0c;助力业务推广 3.1.1 面临的挑战 3.1.2 整体效果 3.2 稳定优先&#xff0c;监控先行&#xff0c;优化运维 3.3降低门槛&#xff0c;不折腾用户 3.3.1 与现有的平台做打通 …

分库分表浅析原理

数据库存放数据大了&#xff0c;查询等操作就会存在瓶颈&#xff0c;怎么办&#xff1f; 1. 如果是单张表数据大了&#xff0c;可以在原有库上新建几张表table_0、table_1、table_2、.....table_n 写程序对数据进行分表&#xff1a; --这里提供一种一种分表策略,这里只需维护…

容器安全是什么?

容器安全定义 容器安全是指保护容器的完整性。这包括从其保管的应用到其所依赖的基础架构等全部内容。容器安全需要完整且持续。通常而言&#xff0c;企业拥有持续的容器安全涵盖两方面&#xff1a; 保护容器流水线和应用保护容器部署环境和基础架构 如何将安全内置于容器流…

Java开发从入门到精通(一):Java的基础语法项目案例

Java大数据开发和安全开发 Java 案例练习案例一:买飞机票案例二:开发验证码案例三:评委打分案例四:数字加密案例五:数组拷贝案例六: 抢红包案例七:找素数案例八:模拟双色球[拓展案例] Java 案例练习 案例一:买飞机票 分析: 方法是需要接收数据?需要接收机票原价、当前月份、舱…

新手如何快速上手学习单片机?

读者朋友能容我&#xff0c;不使博文负真心 新开专栏&#xff0c;期待与诸君共享精彩 个人主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《单片机》 学习单片机是一个有趣且有挑战性的过程。单片机是一种微控制器&#xff0c;广泛应用于各种电子设备和嵌入式系统中。在这…

#QT(本地音乐播放器)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;之前做的音乐播放器只做了一个界面&#xff0c;是因为跟的课程发现到后面需要付费&#xff0c;并且WINGW6.2.0运行QMediaPlayer时无法运行&#xff0c;会崩溃&#xff0c;现在退一步用WINGW5.12.2做一个本地音乐播放器 3.记录&am…

Mysql8的优化(DBA)

Mysql8的优化 1、Mysql的安装优化1.1 修改配置参数&#xff08;命令行、配件文件&#xff09;1.1.1 命令行修改配置参数1.1.2 参数持久化1.1.3 Mysql多实例启动&#xff0c;以及配置密码文件 1.2 查询表的相关参数&#xff0c;以及表空间管理 2、Mysql高级优化&#xff08;SQL&…

Android中显式Intent和隐式Intent的区别

1、intent的中文名 称是意图&#xff0c;Intent是各个组件之间信息沟通的桥梁&#xff0c; 既能在Activity之间沟通&#xff0c;又能在Activity与Service之间沟通&#xff0c;也能在Activity与Broadcast之间沟通 **intent组成元素的列表说明**2、显式Intent&#xff0c;直接指定…

编译支持国密的抓包工具 WireShark

目录 前言WireShark支持国密的 WireShark小结前言 在上一篇文章支持国密的 Web 服务器中,我们搭建了支持国密的 Web 服务器,但是,我们使用 360 安全浏览器去访问,却出现了错误: 是我们的 Web 服务器没有配置好?在这里插入图片描述还是 360 安全浏览器不支持国密?还是两…

C++面试宝典一部分

今天整理书籍资料时&#xff0c;发现多年前打印的面试资料&#xff0c;拍照分享给大家。

基于网络爬虫的购物平台价格监测系统的设计与实现

通过对网络爬虫的购物平台价格监测系统的业务流程进行梳理可知&#xff0c;网络爬虫的购物平台价格监测系统主要由前台买家模块、后台卖家模块以及管理员模块构成。前台功能包含登录功能、注册功能、系统首页功能、唯品会商品详情浏览、唯品会商品收藏、唯品会商品点赞、唯品会…

【Python】科研代码学习:八 FineTune PretrainedModel (用 trainer,用 script);LLM文本生成

【Python】科研代码学习&#xff1a;八 FineTune PretrainedModel [用 trainer&#xff0c;用 script] LLM文本生成 自己整理的 HF 库的核心关系图用 trainer 来微调一个预训练模型用 script 来做训练任务使用 LLM 做生成任务可能犯的错误&#xff0c;以及解决措施 自己整理的 …

ZYNQ实验--PDM波形生成

一、PDM简介 将信号的振幅变化按比例地变换成脉冲宽度的变化&#xff0c;得到脉冲宽度调制(PDM)。详细的原理理论可以参考该文&#xff1a;文献阅读–Pulse-Width Modulation&#xff0c;本文主要介绍PDM的FPGA实现&#xff0c;PDM的生成方式很多具体形式根据需求会有所不同 二…

【Stable Diffusion】入门:原理简介+应用安装(Windows)+生成步骤

【Stable Diffusion】入门&#xff1a;原理简介应用安装&#xff08;Windows&#xff09;生成步骤 原理简介应用安装 原理简介 稳定扩散生成模型(Stable Diffusion)是一种潜在的文本到图像扩散模型&#xff0c;能够在给定任何文本输入的情况下生成照片般逼真的图像。 应用安…

中国广电的独特优势:与三大运营商相比的亮点

2023年&#xff0c;中国广电正式上市了&#xff0c;发出了第一批号段192的号码&#xff0c;然而值得大家了解的是&#xff1a;在中国的通信市场中&#xff0c;中国移动、中国联通和中国电信长期以来占据主导地位。然而&#xff0c;随着中国广电的加入&#xff0c;市场格局正在发…