问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Qt实现QTableView鼠标悬浮行高亮显示

创作时间:
作者:
@小白创作中心

Qt实现QTableView鼠标悬浮行高亮显示

引用
CSDN
1.
https://m.blog.csdn.net/chenjin_2/article/details/144965549

在Qt开发中,QTableView是一个常用的表格控件,但默认情况下并不支持鼠标悬浮时的行高亮显示功能。本文将详细介绍如何通过自定义委托类HoverDelegate实现这一功能,并提供完整的代码示例。

1. 自定义委托类 HoverDelegate

首先,我们需要创建一个自定义的委托类HoverDelegate,继承自QStyledItemDelegate。这个类的主要作用是在鼠标悬浮时改变行的背景颜色。

hoverdelegate.h

#ifndef HOVERDELEGATE_H
#define HOVERDELEGATE_H
#include <QObject>
#include <QStyledItemDelegate>
class hoverdelegate : public QStyledItemDelegate
{
    Q_OBJECT // 添加 Q_OBJECT 宏
public:
    explicit hoverdelegate(QObject *parent = nullptr);
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    void setHoverRow(int row);
signals:
    void hoverChanged(int newRow);// 带参数的信号,表示新的悬停行
private:
    int hoverRow;
};
#endif // HOVERDELEGATE_H

hoverdelegate.cpp

#include "hoverdelegate.h"
#include "qdebug.h"
#include <QPainter>
hoverdelegate::hoverdelegate(QObject *parent)
    : QStyledItemDelegate{parent}
{}
void hoverdelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index); // 确保初始化样式选项
    if (index.row() == hoverRow &&  !(opt.state & QStyle::State_Selected)) {
        qDebug() << "xxxx";
        // 如果是悬停行,则修改背景颜色
        opt.backgroundBrush = QBrush(QColor(200, 230, 255)); // 浅蓝色背景
        qDebug() << "============";
        //qDebug() << "xxxx";
    }
    // 显式绘制背景
    painter->save();
    painter->fillRect(opt.rect, opt.backgroundBrush);
    painter->restore();
    QStyledItemDelegate::paint(painter, opt, index);
}
void hoverdelegate::setHoverRow(int row)
{
    if (hoverRow != row) {
        hoverRow = row;
        emit hoverChanged(hoverRow);
    }
}

2. 如何使用

接下来,我们将展示如何在QTableView中使用这个自定义的委托类。

设置QTableView 样式

/* 标题头 */
 QHeaderView {
            background: rgba(86, 186, 202, 1);
            color: #000000;
            font-size: 16px;
            line-height: 22px;
 }
QHeaderView::section {
            font-size: 16px;
            color: #000000;
![](https://wy-static.wenxiaobai.com/chat-rag-image/3557550344371299754)
            line-height: 22px;
            height: 31px;
            background: rgba(195, 231, 254, 1);
            border: none;
        }
/* 整个表格控件 */
QTableView {
            color: #000000;
            border: 0px solid rgba(56, 66, 70, 1);
            font-size: 16px;
            line-height: 24px;
 }
QTableView::item {
            border-bottom: 1px solid rgb(159, 212, 235);
 }
/* 每个单元格被选中状态 */
        QTableView::item:selected {
            background: rgba(86, 186, 202, 1);
            color: #000000;
 }
/* 可选:鼠标悬停时改变行颜色 */
 /*QTableView::item:hover {
            background-color: rgba(200, 230, 255, 1); /* 浅蓝色背景 */
/*}

初始化表格 使表格好看

QStringList title;
title <<LOCAL("id") << LOCAL("姓名") <<LOCAL("身份证") << LOCAL("性别") << LOCAL("学院")<< LOCAL("账号") << LOCAL("密码");
teacherModel->setHorizontalHeaderLabels(title);
teacherModel->setColumnCount(7);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView->setColumnHidden(0, true);// 隐藏 ID 列 (假设 ID 是第 0 列)
ui->tableView->verticalHeader()->hide(); // 隐藏每行标题头
ui->tableView->setFocusPolicy(Qt::NoFocus);//禁用虚线框
ui->tableView->horizontalHeader()->setHighlightSections(false);//关闭标题栏自动加粗。
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//选中整行。
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);// 设置选择模式为单选

在要使用hoverdelegate 的头文件中

定义 QStandardItemModel* teacherModel;

private:
    QStandardItemModel*  teacherModel;
    hoverdelegate *delegate;
    int m_hoverRow; // 当前悬停行
private slots:
    void onHoverChanged(int newRow);
protected:
    bool eventFilter(QObject *object, QEvent *event);

在使用hoverdelegate 的源文件中

初始化teacherModel 和 delegate

teacherModel = new QStandardItemModel(this);
delegate = new hoverdelegate(this);

设置数据模型

// 设置数据模型
ui->tableView->setModel(teacherModel);

设置自定义委托

// 设置自定义委托
ui->tableView->setItemDelegate(delegate);

安装事件过滤器到 tableView 的视口

// 安装事件过滤器到 tableView 的视口
ui->tableView->viewport()->installEventFilter(this);

启用鼠标跟踪

// 启用鼠标跟踪
ui->tableView->setMouseTracking(true);

连接到 hoverChanged 信号

// 连接到 hoverChanged 信号
connect(delegate, &hoverdelegate::hoverChanged, this, &UserManager::onHoverChanged);

编写鼠标监听事件

bool UserManager::eventFilter(QObject *object, QEvent *event)
{
    // if (event->type() == QEvent::MouseMove && object == ui->tableView->viewport()) {
    //     QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    //     QModelIndex index = ui->tableView->indexAt(mouseEvent->pos());
    //     if (index.isValid()) {
    //         int newRow = index.row();
    //         if (newRow != m_hoverRow) {
    //             m_hoverRow = newRow;
    //             delegate->setHoverRow(m_hoverRow);
    //             ui->tableView->viewport()->update(); // 强制重新绘制
    //             ui->tableView->repaint(); // 强制立即重绘整个视图
    //         }
    //     } else {
    //         if (m_hoverRow != -1) {
    //             m_hoverRow = -1;
    //             delegate->setHoverRow(m_hoverRow);
    //             ui->tableView->viewport()->update(); // 强制重新绘制
    //             ui->tableView->repaint(); // 强制立即重绘整个视图
    //         }
    //     }
    //     return true; // 表示事件已经被处理
    // }
    if (event->type() == QEvent::MouseMove) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        QTableView *tableView = qobject_cast<QTableView*>(object->parent());
        if (tableView) {
            QModelIndex index = tableView->indexAt(mouseEvent->pos());
            int newRow = index.isValid() ? index.row() : -1;
            // 检查是否需要更新悬停行
            if (newRow != m_hoverRow) {
                m_hoverRow = newRow;
                delegate->setHoverRow(m_hoverRow);
                // 更新视图以反映新的悬停状态
                tableView->viewport()->update();
            }
            return true; // 表示事件已经被处理
        }
    }
    return QObject::eventFilter(object, event);
}

编写onHoverChanged 方法

void UserManager::onHoverChanged(int newRow)
{
    qDebug() << "Hover row changed to:" << newRow;
    // 更新当前悬停行并强制重新绘制表格
    m_hoverRow = newRow;
    ui->tableView->viewport()->update();
}

点击运行。效果如下

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号