用代理(QStyledItemDelegate)实现在QTableView的一列或者一行的每个单元格中添加多个按钮控件

OperationColumnDelegate.h



#include <QStyledItemDelegate>
#include <QPushButton>

//默认界面的代理类
class OperationColumnDelegate : public QStyledItemDelegate
{
    Q_OBJECT
    enum
    {
        mouse_state_none = 0,
        mouse_state_hover,
        mouse_state_pressed,
    };
public:
    explicit OperationColumnDelegate(QObject *parent = nullptr);

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);

Q_SIGNALS:
    void requsetView(QPoint point, QString content);
    void requsetVideoWidget(int row, QStringList userIds);
    void requsetDetails(int row, DdTaskInfo info);
    void requsetShowUsers(QPoint point, QStringList userIds);

private:
    QScopedPointer<QPushButton> m_pViewButtonPoint;    
    QScopedPointer<QPushButton> m_pUsersButtonPoint;     
    QScopedPointer<QPushButton> m_pOperationButtonPoint;      

    int m_nMouseState;    // 鼠标状态
    QPoint m_mousePoint;  // 当前鼠标位置

};

OperationColumnDelegate.cpp


#include <QApplication>
#include <QMouseEvent>
#include <QPainter>
#include <QHBoxLayout>
#include <QToolTip>

#define BUTTON_WIDTH  140
#define BUTTON_HEIGHT 23
#define BUTTON_SPACING 6

OperationColumnDelegate::OperationColumnDelegate(QObject *parent)
    : QStyledItemDelegate{parent},
    m_pViewButtonPoint(new QPushButton(tr("View"))),
    m_pUsersButtonPoint(new QPushButton(tr("Users"))),
    m_pOperationButtonPoint(new QPushButton(tr("details")))
{
}

void OperationColumnDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // item的轮廓
    QStyleOptionViewItemV4 viewOption(option);

    QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &viewOption, painter, option.widget);

    int buttonNumber = 0;
    int nTop = (option.rect.height() - BUTTON_HEIGHT) / 2;
    QStyleOptionButton styleOptionButton;
    styleOptionButton.rect = QRect(option.rect.left()+10, option.rect.top() + nTop,  BUTTON_WIDTH, BUTTON_HEIGHT);
    styleOptionButton.state |= QStyle::State_Enabled;
    styleOptionButton.state |= QStyle::State_Active;

    QPushButton *button = nullptr;
    if (styleOptionButton.rect.contains(m_mousePoint))// 鼠标在当前按钮区域
    {
        switch (m_nMouseState)
        {
        case mouse_state_hover:
            styleOptionButton.state |= QStyle::State_MouseOver;           // 按钮hover
            break;
        case mouse_state_pressed:
            styleOptionButton.state |= QStyle::State_Sunken;              // 按钮hover
            break;
        }
    }
    if (index.column() == PlanModel::column_planContent)
    {
        button = m_pViewButtonPoint.data();
        styleOptionButton.text = button->text();
    }
    else if (index.column() == PlanModel::column_userIds)
    {
        button = m_pUsersButtonPoint.data();
        QString data = index.data().toString();
        styleOptionButton.text = data;
    }
    else if (index.column() == PlanModel::column_operation)
    {
        button = m_pOperationButtonPoint.data();
        styleOptionButton.text = button->text();
    }
    QApplication::style()->drawControl(QStyle::CE_PushButton, &styleOptionButton, painter, button);
}

bool OperationColumnDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    m_mousePoint = mouseEvent->pos();
    m_nMouseState = mouse_state_none;

    QApplication::restoreOverrideCursor(); // 恢复手型

    int nTop = (option.rect.height() - BUTTON_HEIGHT) / 2;

    QStyleOptionButton button;
    button.rect = QRect(option.rect.left() + BUTTON_WIDTH/2 - BUTTON_SPACING,
                        option.rect.top() + nTop,  BUTTON_WIDTH, BUTTON_HEIGHT);
    if (button.rect.contains(m_mousePoint))
    {
        DdTaskInfo info = index.data(Qt::UserRole).value<DdTaskInfo>();
        switch (event->type())
        {
        // 鼠标滑过
        case QEvent::MouseMove:
        {

            m_nMouseState = mouse_state_hover;
            return true;                                                // 返回ture表示要重新重绘这个item的区域
            break;
        }
        case QEvent::Enter:
        {

            m_nMouseState = mouse_state_hover;
            return true;                                                // 返回ture表示要重新重绘这个item的区域
            break;
        }
        case QEvent::Leave:
        {

            m_nMouseState = mouse_state_none;
            return true;                                                // 返回ture表示要重新重绘这个item的区域
            break;
        }
        // 鼠标按下
        case QEvent::MouseButtonPress:
        {
            if((mouseEvent->button() &Qt::LeftButton) == Qt::LeftButton)
            {
                // 鼠标左键按下
                m_nMouseState = mouse_state_pressed;
                return true;
            }
            break;
        }
        // 鼠标释放
        case QEvent::MouseButtonRelease:
        {
            if((mouseEvent->button() &Qt::LeftButton) == Qt::LeftButton)
            {
                // 鼠标左键释放
                m_nMouseState = mouse_state_none;

                if(index.column() == PlanModel::column_planContent)
                {
                    QPoint mousePos = mouseEvent->pos();
                    QRect buttonRect = QApplication::style()->subElementRect(QStyle::SE_PushButtonContents, &option, nullptr);//获取按钮的矩形区域

                    if(buttonRect.contains(mousePos))
                    {
                        emit requsetView(buttonRect.topLeft(), info.description);
                    }
                }
                if(index.column() == PlanModel::column_userIds )
                {
                    if( info.policeList.size() <=3)
                    {
                        emit requsetVideoWidget(index.row(), info.policeList);
                    }
                    else
                    {
                        QPoint mousePos = mouseEvent->pos();
                        QRect buttonRect = QApplication::style()->subElementRect(QStyle::SE_PushButtonContents, &option, nullptr);//获取按钮的矩形区域
                        if(buttonRect.contains(mousePos))
                        {
                            emit requsetShowUsers(buttonRect.topLeft(), info.policeList);
                        }
                    }
                }

                if(index.column() == PlanModel::column_operation)
                {
                    emit requsetDetails(index.row(), info);
                }
                return true;
            }
            break;
        }
        case QEvent::MouseButtonDblClick:
        {
            if((mouseEvent->button() &Qt::LeftButton) == Qt::LeftButton)
            {
                if(index.column() == PlanModel::column_userIds && info.policeList.size() > 3)
                {
                    emit requsetVideoWidget(index.row(), info.policeList);
                }
            }
        }
        default:
            break;
        }
    }
    return QStyledItemDelegate::editorEvent(event, model, option, index);
}

使用
//列代理
 m_delegate = new OperationColumnDelegate(this);
 ui->tableView->setItemDelegateForColumn(1, m_delegate);

//行代理
m_delegate = new OperationColumnDelegate(this);
ui->tableView->setItemDelegateForRow(1, m_delegate);

效果

在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

commonbelive

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

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

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

打赏作者

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

抵扣说明:

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

余额充值