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

简述

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

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

效果

QStyledItemDelegate

源码

.h

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

class TableViewDelegate: public QStyledItemDelegate
{
Q_OBJECT public:
explicit TableViewDelegate(QWidget *parent = 0);
~TableViewDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index); signals:
void open(const QModelIndex &index);
void deleteData(const QModelIndex &index); private:
QPoint m_mousePoint; // 鼠标位置
QScopedPointer<QPushButton> m_pOpenButton;
QScopedPointer<QPushButton> m_pDeleteButton;
QStringList m_list;
int m_nSpacing; // 按钮之间的间距
int m_nWidth; // 按钮宽度
int m_nHeight; // 按钮高度
int m_nType; // 按钮状态-1:划过 2:按下
};

.cpp

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

TableViewDelegate::TableViewDelegate(QWidget *parent)
: QStyledItemDelegate(parent),
m_pOpenButton(new QPushButton()),
m_pDeleteButton(new QPushButton()),
m_nSpacing(5),
m_nWidth(25),
m_nHeight(20)
{
// 设置按钮正常、划过、按下样式
m_pOpenButton->setStyleSheet("QPushButton {border: none; background-color: transparent; image:url(:/Images/open);} \
QPushButton:hover {image:url(:/Images/openHover);} \
QPushButton:pressed {image:url(:/Images/openPressed);}"); m_pDeleteButton->setStyleSheet("QPushButton {border: none; background-color: transparent; image:url(:/Images/delete);} \
QPushButton:hover {image:url(:/Images/deleteHover);} \
QPushButton:pressed {image:url(:/Images/deletePressed);}");
m_list << QStringLiteral("打开") << QStringLiteral("删除");
} TableViewDelegate::~TableViewDelegate()
{ } // 绘制按钮
void TableViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
viewOption.state = viewOption.state ^ QStyle::State_HasFocus; QStyledItemDelegate::paint(painter, viewOption, index); if (index.column() == FILE_OPERATE_COLUMN)
{
// 计算按钮显示区域
int nCount = m_list.count();
int nHalf = (option.rect.width() - m_nWidth * nCount - m_nSpacing * (nCount - 1)) / 2;
int nTop = (option.rect.height() - m_nHeight) / 2; for (int i = 0; i < nCount; ++i)
{
// 绘制按钮
QStyleOptionButton button;
button.rect = QRect(option.rect.left() + nHalf + m_nWidth * i + m_nSpacing * i,
option.rect.top() + nTop, m_nWidth, m_nHeight);
button.state |= QStyle::State_Enabled;
//button.iconSize = QSize(16, 16);
//button.icon = QIcon(QString(":/Images/%1").arg(m_list.at(i))); if (button.rect.contains(m_mousePoint))
{
if (m_nType == 0)
{
button.state |= QStyle::State_MouseOver;
//button.icon = QIcon(QString(":/Images/%1Hover").arg(m_list.at(i)));
}
else if (m_nType == 1)
{
button.state |= QStyle::State_Sunken;
//button.icon = QIcon(QString(":/Images/%1Pressed").arg(m_list.at(i)));
}
} QWidget *pWidget = (i == 0) ? m_pOpenButton.data() : m_pDeleteButton.data();
QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, pWidget);
}
}
} // 响应按钮事件 - 划过、按下
bool TableViewDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
if (index.column() != FILE_OPERATE_COLUMN)
return false; m_nType = -1;
bool bRepaint = false;
QMouseEvent *pEvent = static_cast<QMouseEvent *> (event);
m_mousePoint = pEvent->pos(); int nCount = m_list.count();
int nHalf = (option.rect.width() - m_nWidth * nCount - m_nSpacing * (nCount - 1)) / 2;
int nTop = (option.rect.height() - m_nHeight) / 2; // 还原鼠标样式
QApplication::restoreOverrideCursor(); for (int i = 0; i < nCount; ++i)
{
QStyleOptionButton button;
button.rect = QRect(option.rect.left() + nHalf + m_nWidth * i + m_nSpacing * i,
option.rect.top() + nTop, m_nWidth, m_nHeight); // 鼠标位于按钮之上
if (!button.rect.contains(m_mousePoint))
continue; bRepaint = true;
switch (event->type())
{
// 鼠标滑过
case QEvent::MouseMove:
{
// 设置鼠标样式为手型
QApplication::setOverrideCursor(Qt::PointingHandCursor); m_nType = 0;
QToolTip::showText(pEvent->globalPos(), m_list.at(i));
break;
}
// 鼠标按下
case QEvent::MouseButtonPress:
{
m_nType = 1;
break;
}
// 鼠标释放
case QEvent::MouseButtonRelease:
{
if (i == 0)
{
emit open(index);
}
else
{
emit deleteData(index);
}
break;
}
default:
break;
}
} return bRepaint;
}

衍伸

通过上面的实现,我们可以自定义按钮的样式、文本、显示区域、等,我们也可以通过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. [转] vagrant系列(2):使用Vagrantfile实现集成预安装

    在我们的开发目录下,有一个文件Vagrantfile,里面包含有大量的配置信息,主要包括三个方面:虚拟机配置.SSH配置.基础配置.Vagrant是使用Ruby开发的,所以它的配置语法也是Ruby的, ...

  2. ORACLE INSERT ALL 用法

    1INSERT ALL 1.1句法 multi_table_insert :: = conditional_insert_clause :: = 1.2multi_table_insert 在多表插入 ...

  3. Ubuntu 18.04上搭建FTP服务器

    1.准备工作需要安装并运行的Ubuntu Server 18.04系统.当然还需要一个具有sudo权限的账号. 2.安装VSFTPVSFTP程序位于标准存储库中,因此可以使用单个命令删除安装.打开终端 ...

  4. Java万年历,输入年月获取该年月日历表

    //输入年份和月份,打印出这个月的日历表 /* 1.1900年1月1日是星期一 2.计算输入的年份距离1900年有多少天再计算当年1月1日距这个月有多少天 1) 3.总天数%7得出从星期几开始 注:计 ...

  5. PL/SQL Developer中输入SQL语句时如何自动提示字段

    在PL/SQL Developer中编写sql语句时,如果无法自动提示字段那是一件痛苦的事情,工作效率又低,在此演示下如何在PL/SQL Developer工具中自动提示字段,让开发者省时又省心,操作 ...

  6. MySQL查询近一个月的数据

    MySQL查询近一个月的数据 近一个月统计SQL select user_id, user_name, createtime from t_user where DATE_SUB(CURDATE(), ...

  7. CCF 201409-4 最优配餐

    问题描述 试题编号: 201409-4 试题名称: 最优配餐 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 栋栋最近开了一家餐饮连锁店,提供外卖服务.随着连锁店越来越多,怎么 ...

  8. Linux 命令 -- chmod

    chmod命令用来变更文件或目录的权限.在UNIX系统家族里,文件或目录权限的控制分别以读取.写入.执行3种一般权限来区分,另有3种特殊权限可供运用.用户可以使用chmod指令去变更文件与目录的权限, ...

  9. WEB项目构建优化之自动清除CSS中的图片缓存

    在web项目构建发布时,经常遇到css中图片的修改优化,那么如何清除图片的缓存成为必须要解决的问题.曾经有过傻傻的方法就是直接在图片后面添加随机数.今天主要是从构建自动化方式来解决这个问题,提高开发及 ...

  10. ansible roles 目录规范

    我的ansible roles项目的目录结构: (ansible_venv) [root@localhost ansible_home]# tree ansible_playbooks/ ansibl ...