当前位置:   article > 正文

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

qtreeview 鼠标移动消息

目录

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:

  1. #ifndef LOG_TABLE_VIEW_H
  2. #define LOG_TABLE_VIEW_H
  3. #include <QTableView>
  4. class CLogTableView : public QTableView
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit CLogTableView(QWidget *parent = nullptr);
  9. signals:
  10. // void mouseEnterItemSigal(const QModelIndex &);
  11. private:
  12. /* 注意:不能重载mouseMoveEvent函数,否则QAbstractItemView::entered信号不会触发,
  13. 如果非要重载mouseMoveEvent函数,则在该函数中发送自定义鼠标进入视图项的信号,如本
  14. 类中的mouseEnterItemSigal信号
  15. */
  16. //virtual void mouseMoveEvent(QMouseEvent *event) override;
  17. };
  18. #endif // LOG_TABLE_VIEW_H

logTableView.cpp:

  1. #include "logTableView.h"
  2. #include<QMouseEvent>
  3. CLogTableView::CLogTableView(QWidget *parent)
  4. : QTableView(parent)
  5. {
  6. setMouseTracking(true);
  7. }
  8. /* 注意:不能重载mouseMoveEvent函数,否则QAbstractItemView::entered信号不会触发,
  9. 如果非要重载mouseMoveEvent函数,则在该函数中发送自定义鼠标进入视图项的信号,如本类
  10. 中的mouseEnterItemSigal信号
  11. */
  12. //void CLogTableView::mouseMoveEvent(QMouseEvent *event)
  13. //{
  14. // auto pos = event->pos();
  15. // auto modelIndex = this->indexAt(pos);
  16. // // emit mouseEnterItemSigal(modelIndex);
  17. // //update();
  18. //}
logTableModel.h:
  1. #ifndef LOGTABLEMODEL_H
  2. #define LOGTABLEMODEL_H
  3. #include <QAbstractTableModel>
  4. class CLogTableModel : public QAbstractTableModel
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit CLogTableModel(QObject *parent = nullptr);
  9. public:
  10. /*功能:向外层发送日志信息
  11. *参数1:日志具体内容
  12. *参数2:日志来源的模块,如:设备管理模块
  13. *参数3:日志级别
  14. */
  15. void addLog(const QString&qsLog, const QString&qsLogSrcModule, int nLogEvel);
  16. private:
  17. // Basic functionality:
  18. int rowCount(const QModelIndex &parent = QModelIndex()) const override;
  19. int columnCount(const QModelIndex &parent = QModelIndex()) const override;
  20. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
  21. virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
  22. private:
  23. QVariant doDecorationRole(int nLogEvel) const;
  24. QVariant doForegroundRole(int nLogEvel) const;
  25. private:
  26. QStringList m_lstLogInfo;
  27. };
  28. #endif // LOGTABLEMODEL_H
logTableModel.cpp:
  1. #include "logTableModel.h"
  2. #include<QIcon>
  3. #include<QBrush>
  4. CLogTableModel::CLogTableModel(QObject *parent)
  5. : QAbstractTableModel(parent)
  6. {
  7. }
  8. int CLogTableModel::rowCount(const QModelIndex &parent) const
  9. {
  10. if (parent.isValid())
  11. return 0;
  12. return static_cast<int>(m_lstLogInfo.size() / 3);
  13. }
  14. int CLogTableModel::columnCount(const QModelIndex &parent) const
  15. {
  16. if (parent.isValid())
  17. return 0;
  18. return 1;
  19. }
  20. QVariant CLogTableModel::data(const QModelIndex &index, int role) const
  21. {
  22. if (!index.isValid())
  23. return QVariant();
  24. auto rowIndex = index.row();
  25. auto rowCount = m_lstLogInfo.size() / 3;
  26. if((rowIndex < 0) || ( rowCount <= rowIndex))
  27. {
  28. Q_ASSERT(0);
  29. return QVariant();
  30. }
  31. // 以下这么做的目的是为了让最近产生的日志排在最顶部,最久产生的日志排在最底部
  32. auto logIndex = 3 * rowIndex;
  33. auto qsLog = m_lstLogInfo[logIndex];
  34. auto qsLogSrcModule = m_lstLogInfo[logIndex + 1];
  35. auto nLogEvel = m_lstLogInfo[logIndex + 2].toInt();
  36. auto columnIndex = index.column();
  37. switch (role)
  38. {
  39. case Qt::DisplayRole:
  40. {
  41. switch (columnIndex)
  42. {
  43. case 0:
  44. {
  45. return qsLog;
  46. }
  47. }
  48. }
  49. break;
  50. case Qt::DecorationRole:
  51. {
  52. return doDecorationRole(nLogEvel);
  53. }
  54. break;
  55. case Qt::ForegroundRole:
  56. {
  57. return doForegroundRole(nLogEvel);
  58. }
  59. break;
  60. } // end switch role
  61. return QVariant();
  62. }
  63. Qt::ItemFlags CLogTableModel::flags(const QModelIndex &index) const
  64. {
  65. Q_UNUSED(index);
  66. return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
  67. }
  68. QVariant CLogTableModel::doForegroundRole(int nLogEvel) const
  69. {
  70. switch (nLogEvel)
  71. {
  72. case 1:
  73. {
  74. return QBrush(Qt::yellow);
  75. }
  76. break;
  77. case 2
  78. case 3:
  79. {
  80. return QBrush(Qt::red);
  81. }
  82. break;
  83. default:
  84. {
  85. }
  86. break;
  87. }
  88. return QVariant();
  89. }
  90. QVariant CLogTableModel::doDecorationRole(int nLogEvel) const
  91. {
  92. QIcon icon;
  93. switch (nLogEvel)
  94. {
  95. case 0:
  96. {
  97. icon.addFile(QLatin1String(":/logWnd/image/log/normal.png"));
  98. return icon;
  99. }
  100. break;
  101. case 1:
  102. {
  103. icon.addFile(QLatin1String(":/logWnd/image/log/warn.png"));
  104. return icon;
  105. }
  106. break;
  107. case 2:
  108. case 3:
  109. {
  110. icon.addFile(QLatin1String(":/logWnd/image/log/error.png"));
  111. return icon;
  112. }
  113. break;
  114. default:
  115. {
  116. return icon;
  117. }
  118. break;
  119. }
  120. return QVariant();
  121. }
  122. void CLogTableModel::addLog(const QString&qsLog, const QString&qsLogSrcModule, int nLogEvel)
  123. {
  124. beginResetModel();
  125. if(m_lstLogInfo.size() >= 50)
  126. {
  127. m_lstLogInfo.clear();
  128. }
  129. auto qsLogEvel = QString::number(nLogEvel);
  130. m_lstLogInfo.insert(0, qsLog);
  131. m_lstLogInfo.insert(1, qsLogSrcModule);
  132. m_lstLogInfo.insert(2, qsLogEvel);
  133. endResetModel();
  134. }
logItemDelegate.h:
  1. #ifndef CLOGITEMDELEGATE_H
  2. #define CLOGITEMDELEGATE_H
  3. #include <QStyledItemDelegate>
  4. class CLogItemDelegate : public QStyledItemDelegate
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit CLogItemDelegate(QObject *parent = nullptr);
  9. public:
  10. void enterItem(const QModelIndex &index);
  11. private:
  12. void paint(QPainter *painter, const QStyleOptionViewItem &option,
  13. const QModelIndex &index) const override;
  14. private:
  15. QModelIndex m_curIndex;
  16. };
  17. #endif // CLOGITEMDELEGATE_H

logItemDelegate.cpp:

  1. #include "logItemDelegate.h"
  2. #include<QPainter>
  3. CLogItemDelegate::CLogItemDelegate(QObject *parent)
  4. : QStyledItemDelegate(parent)
  5. {
  6. }
  7. void CLogItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
  8. {
  9. if (m_curIndex.row() == index.row())
  10. {
  11. // 可以把第2个参数换成你想要的任何颜色
  12. painter->fillRect(option.rect, option.palette.highlight());
  13. }
  14. QStyledItemDelegate::paint(painter, option, index);
  15. }
  16. void CLogItemDelegate::enterItem(const QModelIndex &index)
  17. {
  18. if(!index.isValid())
  19. {
  20. return;
  21. }
  22. m_curIndex = index;
  23. }

调用方代码如下:

  1. #include "logWnd.h"
  2. #include "ui_logWnd.h"
  3. #include<QPainter>
  4. #include "logTableModel.h"
  5. #include"logItemDelegate.h"
  6. CLogWnd::CLogWnd(QWidget *parent) : QWidget(parent),
  7. ui(new Ui::CLogWnd)
  8. {
  9. ui->setupUi(this);
  10. this->resize(650, 1200);
  11. this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Window);
  12. // 创建模型类
  13. m_pLogTableModel = new CLogTableModel(this);
  14. ui->logTv->setModel(m_pLogTableModel);
  15. // 创建委托类
  16. auto pLogItemDelegate = new CLogItemDelegate(this);
  17. ui->logTv->setItemDelegate(pLogItemDelegate);
  18. ui->logTv->horizontalHeader()->hide();
  19. ui->logTv->verticalHeader()->hide();
  20. ui->logTv->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows);
  21. // 连接entered信号
  22. connect(ui->logTv, &CLogTableView::entered, pLogItemDelegate, &CLogItemDelegate::enterItem);
  23. // connect(ui->logTv, &QAbstractItemView::mouseEnterItemSigal, pLogItemDelegate, &CLogItemDelegate::enterItem);
  24. }
  25. void CLogWnd::addLog(const QString&qsLog, const QString&qsLogSrcModule, int nLogEvel)
  26. {
  27. m_pLogTableModel->addLog(qsLog, qsLogSrcModule, nLogEvel);
  28. }

 调用:

  1. auto pLogWnd = new CLogWnd(this);
  2. pLogWnd->addLog("a", "a1", 0);
  3. pLogWnd->addLog("b", "b1", 2);
  4. 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信号的问题解决

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号