构造函数中传入按钮列表,即可添加多个按钮,可设置按钮样式表,使用信号槽连接按钮事件。
#include
#include
#include
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;
};
#include "qmytableviewbtndelegate.h"
#include
#include
#include
#include
#include
#include
#include
#include
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;
}
// 必须要设置此项,否则样式表的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