https://blog.csdn.net/liang19890820/article/details/50974059

简述

衍伸前面的章节,我们对QTableView实现了数据显示、自定义排序、显示复选框、进度条等功能的实现,本节主要针对自定义按钮进行讲解,这节过后,也希望大家对自定义有更深入的了解,在以后的功能开发过程中,相信无论遇到什么样式形式,我们都可以很好地实现。

版权声明:一去、二三里,未经博主允许不得转载。

效果

QStyledItemDelegate

源码

.h

包含显示按钮需要用到的智能指针,按钮的宽度、高度、按钮之间的间距、鼠标的坐标等。

  1. class TableViewDelegate: public QStyledItemDelegate
  2. {
  3. Q_OBJECT
  4. public:
  5. explicit TableViewDelegate(QWidget *parent = 0);
  6. ~TableViewDelegate();
  7. void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
  8. bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
  9. signals:
  10. void open(const QModelIndex &index);
  11. void deleteData(const QModelIndex &index);
  12. private:
  13. QPoint m_mousePoint; // 鼠标位置
  14. QScopedPointer<QPushButton> m_pOpenButton;
  15. QScopedPointer<QPushButton> m_pDeleteButton;
  16. QStringList m_list;
  17. int m_nSpacing; // 按钮之间的间距
  18. int m_nWidth; // 按钮宽度
  19. int m_nHeight; // 按钮高度
  20. int m_nType; // 按钮状态-1:划过 2:按下
  21. };

.cpp

主要设置按钮样式,实现鼠标划过、按下,响应鼠标事件等操作。

  1. TableViewDelegate::TableViewDelegate(QWidget *parent)
  2. : QStyledItemDelegate(parent),
  3. m_pOpenButton(new QPushButton()),
  4. m_pDeleteButton(new QPushButton()),
  5. m_nSpacing(5),
  6. m_nWidth(25),
  7. m_nHeight(20)
  8. {
  9. // 设置按钮正常、划过、按下样式
  10. m_pOpenButton->setStyleSheet("QPushButton {border: none; background-color: transparent; image:url(:/Images/open);} \
  11. QPushButton:hover {image:url(:/Images/openHover);} \
  12. QPushButton:pressed {image:url(:/Images/openPressed);}");
  13. m_pDeleteButton->setStyleSheet("QPushButton {border: none; background-color: transparent; image:url(:/Images/delete);} \
  14. QPushButton:hover {image:url(:/Images/deleteHover);} \
  15. QPushButton:pressed {image:url(:/Images/deletePressed);}");
  16. m_list << QStringLiteral("打开") << QStringLiteral("删除");
  17. }
  18. TableViewDelegate::~TableViewDelegate()
  19. {
  20. }
  21. // 绘制按钮
  22. void TableViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
  23. {
  24. QStyleOptionViewItem viewOption(option);
  25. initStyleOption(&viewOption, index);
  26. if (option.state.testFlag(QStyle::State_HasFocus))
  27. viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
  28. QStyledItemDelegate::paint(painter, viewOption, index);
  29. if (index.column() == FILE_OPERATE_COLUMN)
  30. {
  31. // 计算按钮显示区域
  32. int nCount = m_list.count();
  33. int nHalf = (option.rect.width() - m_nWidth * nCount - m_nSpacing * (nCount - 1)) / 2;
  34. int nTop = (option.rect.height() - m_nHeight) / 2;
  35. for (int i = 0; i < nCount; ++i)
  36. {
  37. // 绘制按钮
  38. QStyleOptionButton button;
  39. button.rect = QRect(option.rect.left() + nHalf + m_nWidth * i + m_nSpacing * i,
  40. option.rect.top() + nTop, m_nWidth, m_nHeight);
  41. button.state |= QStyle::State_Enabled;
  42. //button.iconSize = QSize(16, 16);
  43. //button.icon = QIcon(QString(":/Images/%1").arg(m_list.at(i)));
  44. if (button.rect.contains(m_mousePoint))
  45. {
  46. if (m_nType == 0)
  47. {
  48. button.state |= QStyle::State_MouseOver;
  49. //button.icon = QIcon(QString(":/Images/%1Hover").arg(m_list.at(i)));
  50. }
  51. else if (m_nType == 1)
  52. {
  53. button.state |= QStyle::State_Sunken;
  54. //button.icon = QIcon(QString(":/Images/%1Pressed").arg(m_list.at(i)));
  55. }
  56. }
  57. QWidget *pWidget = (i == 0) ? m_pOpenButton.data() : m_pDeleteButton.data();
  58. QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, pWidget);
  59. }
  60. }
  61. }
  62. // 响应按钮事件 - 划过、按下
  63. bool TableViewDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
  64. {
  65. if (index.column() != FILE_OPERATE_COLUMN)
  66. return false;
  67. m_nType = -1;
  68. bool bRepaint = false;
  69. QMouseEvent *pEvent = static_cast<QMouseEvent *> (event);
  70. m_mousePoint = pEvent->pos();
  71. int nCount = m_list.count();
  72. int nHalf = (option.rect.width() - m_nWidth * nCount - m_nSpacing * (nCount - 1)) / 2;
  73. int nTop = (option.rect.height() - m_nHeight) / 2;
  74. // 还原鼠标样式
  75. QApplication::restoreOverrideCursor();
  76. for (int i = 0; i < nCount; ++i)
  77. {
  78. QStyleOptionButton button;
  79. button.rect = QRect(option.rect.left() + nHalf + m_nWidth * i + m_nSpacing * i,
  80. option.rect.top() + nTop, m_nWidth, m_nHeight);
  81. // 鼠标位于按钮之上
  82. if (!button.rect.contains(m_mousePoint))
  83. continue;
  84. bRepaint = true;
  85. switch (event->type())
  86. {
  87. // 鼠标滑过
  88. case QEvent::MouseMove:
  89. {
  90. // 设置鼠标样式为手型
  91. QApplication::setOverrideCursor(Qt::PointingHandCursor);
  92. m_nType = 0;
  93. QToolTip::showText(pEvent->globalPos(), m_list.at(i));
  94. break;
  95. }
  96. // 鼠标按下
  97. case QEvent::MouseButtonPress:
  98. {
  99. m_nType = 1;
  100. break;
  101. }
  102. // 鼠标释放
  103. case QEvent::MouseButtonRelease:
  104. {
  105. if (i == 0)
  106. {
  107. emit open(index);
  108. }
  109. else
  110. {
  111. emit deleteData(index);
  112. }
  113. break;
  114. }
  115. default:
  116. break;
  117. }
  118. }
  119. return bRepaint;
  120. }

衍伸

通过上面的实现,我们可以自定义按钮的样式、文本、显示区域、等,我们也可以通过QStyleOptionButton的icon和iconSize来设置按钮的图标与图标大小,通过响应按钮来实现我们自己的事件。

Qt 之模型/视图(自定义按钮)的更多相关文章

  1. Qt之模型/视图(自定义风格)

    Qt之模型/视图(自定义风格) 关于自定义风格是针对视图与委托而言的,使用事件与QSS都可以进行处理,今天关于美化的细节讲解一下. 先看下图: 先撇开界面的美观性(萝卜青菜,各有所爱),就现有的这些风 ...

  2. Qt之模型/视图(自定义按钮)

    简述 衍伸前面的章节,我们对QTableView实现了数据显示.自定义排序.显示复选框.进度条等功能的实现,本节主要针对自定义按钮进行讲解,这节过后,也希望大家对自定义有更深入的了解,在以后的功能开发 ...

  3. Qt之模型/视图(自定义进度条)

    简述 在之前的章节中分享过关于QHeaderView表头排序.添加复选框等内容,相信大家模型/视图.自定义风格有了一定的了解,下面我们来分享一个更常用的内容-自定义进度条. 实现方式: 从QAbstr ...

  4. 【转】Qt之模型/视图

    [本文转自]http://blog.sina.com.cn/s/blog_a6fb6cc90101hh20.html   作者: 一去丶二三里 关于Qt中MVC的介绍与使用,助手中有一节模型/视图编程 ...

  5. Qt之模型/视图(委托)

    概念 不同于模型 - 视图 - 控制器模式,模型/视图设计不包括用于管理与用户交互的一个完全独立的组件.一般情况,视图负责将模型数据呈现给用户以及处理用户输入.为了输入更加具有灵活性,则由委托来执行交 ...

  6. QT MVC 模型/视图

    1. 模型视图实例一, QFileSystemModel  QTreeView ,model/view示例. #include <QApplication> #include <QF ...

  7. Qt之模型/视图(实时更新数据)

    上两节简单介绍了Qt中对于模型/视图的编程,大部分助手里说的很清楚了,现在就开始实战部分吧! 在实际应用中,视图展示的数据往往并非一成不变的,那么如何实时更新成了一个很重要的问题!功能:(1)添加委托 ...

  8. Qt之模型/视图(自定义按钮)(使用QStyleOption的子类进行drawControl,和我用的方法完全不一样)

    http://blog.csdn.net/liang19890820/article/details/50974059

  9. Qt之模型/视图(自定义按钮)(重绘QStyleOptionButton)

    http://blog.csdn.net/liang19890820/article/details/50974059#comments

随机推荐

  1. sqlserver 并发机制

    一.事务四大属性 分别是原子性.一致性.隔离性.持久性. 1.原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库, ...

  2. linux 安装谷歌浏览器

    1. 下载 rpm 包https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm2. 安装依赖包yum ins ...

  3. python 库 、包 、模块

    概念: 模块: 模块是一种以.py为后缀的文件,在.py文件中定义了一些常量和函数.模块的名称是该.py文件的名称.模块的名称作为一个全局变量__name__的取值可以被其他模块获取或导入. 模块的导 ...

  4. xtts v4for oracle 11g&12c(文档ID 2471245

    xtts v4for oracle 11g&12c(文档ID 2471245.1) 序号 主机 操作项目 操作内容 备注: 阶段一:初始阶段 1.1 源端 环境验证 migrate_check ...

  5. ngx.location.capture 只支持相对路径,不能用绝对路径

    ngx.location.capture 是非阻塞的,ngx.location.capture也可以用来完成http请求,但是它只能请求到相对于当前nginx服务器的路径,不能使用之前的绝对路径进行访 ...

  6. hibernate抓取问题

    当使用xml配置类之间的关系时 ,例如 学生 班级,多对一关系 /** * 默认情况会发出2条SQL语句,一条取student,一条取Classroom,其实这只需要一条sql             ...

  7. java 写入数据到Excel文件中_Demo

    =======第一版:基本功能实现======= import com.google.common.collect.Maps; import org.apache.log4j.Logger; impo ...

  8. SQL Cookbook—插入、更新与删除

    涉及到的问题–1.从一个表向另外的表中复制行–2.复制表定义(包含表记录)–3.一次向多个表中插入记录–4.–5.当相应行存在时更新–6.用其他表中的值更新–7.删除违反参照完整性的记录 –1.从一个 ...

  9. MySQL优化--创建索引,以及怎样索引才会生效 (03)

    1. 创建索引 (看这里) 2.索引在什么情况下才会起作用(重点)

  10. FocusBI: 使用Python爬虫为BI准备数据源(原创)

    关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277 获取学习资料和一起探讨问题. <商业智能教程>pdf下载地址 链接:https://pan.baidu.com/ ...