Qt Model/View 自定义代理(五): 使用代理给QTableView单元格添加按钮QPushButton

Qt Model/View 自定义代理(五): 使用代理给QTableView单元格添加按钮QPushButton

效果图:
在这里插入图片描述

构造函数中传入按钮列表,即可添加多个按钮,可设置按钮样式表,使用信号槽连接按钮事件。

1. 头文件

#include <QObject>
#include <QPushButton>
#include<QStyledItemDelegate>

class QMyTableViewBtnDelegate: public QStyledItemDelegate
{
    Q_OBJECT

public:
    explicit QMyTableViewBtnDelegate(QStringList btnNames, QWidget *parent = 0);
    ~QMyTableViewBtnDelegate();
    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 editData(const QModelIndex &index);
    void deleteData(const QModelIndex &index);

private:
    QPoint m_mousePoint;  // 鼠标位置
    int m_nType;  // 按钮状态:0-划过 1-按下
    QStringList m_btnNames;
};

2. 源文件

#include "qmytableviewbtndelegate.h"

#include <QApplication>
#include <QMouseEvent>
#include <QMessageBox>
#include <QPainter>
#include <QStyleOption>
#include <QDesktopWidget>
#include <QToolTip>
#include <QDebug>

QMyTableViewBtnDelegate::QMyTableViewBtnDelegate(QStringList btnNames, QWidget *parent)
    : QStyledItemDelegate(parent),
      m_btnNames(btnNames)
{
}

QMyTableViewBtnDelegate::~QMyTableViewBtnDelegate()
{

}

// 绘制按钮
void QMyTableViewBtnDelegate::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);

    // 计算按钮显示区域
    int nCount = m_btnNames.count();

    int w = nCount != 0 ? option.rect.width() / nCount : 0;
    if(w < 0) {
        return;
    }

    for (int i = 0; i < nCount; ++i)
    {
        // 绘制按钮
        QStyleOptionButton button;
        button.rect =  option.rect.adjusted(4 + i*w , 4, -(w * ( nCount - i -1 ) + 4)  , -4);
        button.text = m_btnNames.at(i);
        button.state |= QStyle::State_Enabled;

        if (button.rect.contains(m_mousePoint))
        {
            if (m_nType == 0)
            {
                button.state |= QStyle::State_MouseOver;
            }
            else if (m_nType == 1)
            {
                button.state |= QStyle::State_Sunken;
            }
        }
        QPushButton pushBtn;
        if (i == nCount - 1)
        {
            pushBtn.setStyleSheet("QPushButton{border-width: 0px;\
                                position: absolute;\
                                left: 0px;\
                                top: 0px;\
                                max-width: 80px;\
                                width:80px;\
                                height: 30px;\
                                background: inherit;\
                                background-color: rgba(255, 255, 255, 0);\
                                border-width: 1px;\
                                border-style: solid;\
                                border-color: red;\
                                border-radius: 10px;\
                                font-size: 11px;\
                                color: red;}\
                                QPushButton:hover{background-color:red; color:#FFFFFF;}");
        }
        else
        {
            pushBtn.setStyleSheet("QPushButton{border-width: 0px;\
                                position: absolute;\
                                left: 0px;\
                                top: 0px;\
                                max-width:120px; \
                                width:120px;\
                                height: 30px;\
                                background: inherit;\
                                background-color: rgba(255, 255, 255, 0);\
                                border-width: 1px;\
                                border-style: solid;\
                                border-color: rgba(2, 182, 212, 1);\
                                border-radius: 10px;\
                                font-size: 11px;\
                                color: #000000;}\
                                QPushButton:hover{background-color:rgba(2, 182, 212, 1); color:#FFFFFF;}");
        }

        pushBtn.style()->drawControl(QStyle::CE_PushButton, &button, painter, &pushBtn);
    }
}

// 响应按钮事件 - 划过、按下
bool QMyTableViewBtnDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
    m_nType = -1;
    bool bRepaint = false;
    QMouseEvent *pEvent = static_cast<QMouseEvent *> (event);
    m_mousePoint = pEvent->pos();

    int nCount = m_btnNames.count();

    int w = nCount != 0 ? option.rect.width() / nCount : 0;
    if(w < 0) {
        return false;
    }

    // 还原鼠标样式
    QApplication::restoreOverrideCursor();

    for (int i = 0; i < nCount; ++i)
    {
        QStyleOptionButton button;
        button.rect =  option.rect.adjusted(4 + i*w , 4, -(w * ( nCount - i -1 ) + 4)  , -4);

        // 鼠标位于按钮之上
        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_btnNames.at(i));
            break;
        }
        // 鼠标按下
        case QEvent::MouseButtonPress:
        {
            m_nType = 1;
            break;
        }
        // 鼠标释放
        case QEvent::MouseButtonRelease:
        {
            switch (i)
            {
            case 0:
            {
                emit editData(index);
                break;
            }
            case 1:
            {
                emit deleteData(index);
                break;
            }
            default:
            break;
            }
        }
        default:
            break;
        }
    }

    return bRepaint;
}

3. 使用

	// 必须要设置此项,否则样式表的hover无法生效
	ui->tableView->setMouseTracking(true); 
	// 构造函数中传入按钮列表即可添加任意个按钮
    m_btnDelegate = new QMyTableViewBtnDelegate(QStringList()<<"编辑"<<"删除", this); 
    // 为指定列设置代理
    ui->tableView->setItemDelegateForColumn(2, m_btnDelegate);
	// 连接信号槽,根据需要添加
    connect(m_btnDelegate, &QMyTableViewBtnDelegate::editData, this, [=](const QModelIndex &index){
        QMessageBox::information(this, "提示", QString("编辑第 %1 行数据").arg(index.row()+1));
    });
    connect(m_btnDelegate, &QMyTableViewBtnDelegate::deleteData, this, [=](const QModelIndex &index){
        QMessageBox::information(this, "提示", QString("删除第 %1 行数据").arg(index.row()+1));
    });

参考:

https://www.cnblogs.com/li-peng/p/4029885.html
https://blog.csdn.net/liang19890820/article/details/50974059#comments

  • 19
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorAL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值