目录
1. 前言
因为QColumnView、QHeaderView、QListView、QTableView、QTreeView、QListWidget 、QUndoView、QTableWidget、QTreeWidget都是从QAbstractItemView继承,故本博文所说的技术点也适用于这些类,本博文以QTableView类来讲解。
2. 需求
业务需求是:鼠标在QTableView的项上方移动(不是按下)时,项背景色改变。即像下面那样的效果:
鼠标移动,项背景色改变的具体实现,参见鼠标在QAbstractItemView类如:QTreeView、QTableView、QTableWidget的项上移动,背景色改变
3. 问题现象
要实现2节提到的功能,就需要监测鼠标进入视图项的信号,Qt官方已经为QAbstractItemView类提供了entered信号,如下:
[signal] void QAbstractItemView::entered(const QModelIndex &index)
当连接entered信号,发现槽函数CLogItemDelegate::enterItem不响应、不进入,且connect返回值为true,证明连接是成功的,如下:
bool b = connect(ui->logTv, &QAbstractItemView::entered, pLogItemDelegate, &CLogItemDelegate::enterItem);
其中b为true,ui->logTv为QTableView类或 从QTableView类派生的子类。
4. 问题解决
该问题分为两种情况:
第1种情况:ui->logTv为QTableView类。此时只需要将鼠标跟踪属性设置为true,即:
ui->logTv->setMouseTracking(true);
第2种情况:ui->logTv为QTableView类的派生类。有时QTableView类不能满足业务需求,需要从QTableView类派生出类,以重载某些函数实现自己个性化需求,如下:
#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
#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();
}
对于这种派生类,不仅需要像第1种情况那样将鼠标跟踪属性设置为true,且不能重载mouseMoveEvent函数,否则QAbstractItemView::entered信号不会触发,如果非要重载mouseMoveEvent函数,则在该函数中发送自定义鼠标进入视图项的信号,如CLogTableView类的mouseEnterItemSigal信号,然后捕捉mouseEnterItemSigal信号。