簡述
衍伸前面的章節,我們對QTableView實作了資料顯示、自定義排序、顯示複選框、進度條等功能的實作,本節主要針對自定義按鈕進行講解,這節過後,也希望大家對自定義有更深入的了解,在以後的功能開發過程中,相信無論遇到什麼樣式形式,我們都可以很好地實作。
|版權聲明:一去、二三裡,未經部落客允許不得轉載。
效果
QStyledItemDelegate
源碼
.h
包含顯示按鈕需要用到的智能指針,按鈕的寬度、高度、按鈕之間的間距、滑鼠的坐标等。
class TableViewDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
explicit TableViewDelegate(QWidget *parent = );
~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(),
m_nWidth(),
m_nHeight()
{
// 設定按鈕正常、劃過、按下樣式
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 - )) / ;
int nTop = (option.rect.height() - m_nHeight) / ;
for (int i = ; 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 == )
{
button.state |= QStyle::State_MouseOver;
//button.icon = QIcon(QString(":/Images/%1Hover").arg(m_list.at(i)));
}
else if (m_nType == )
{
button.state |= QStyle::State_Sunken;
//button.icon = QIcon(QString(":/Images/%1Pressed").arg(m_list.at(i)));
}
}
QWidget *pWidget = (i == ) ? 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 = -;
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 - )) / ;
int nTop = (option.rect.height() - m_nHeight) / ;
// 還原滑鼠樣式
QApplication::restoreOverrideCursor();
for (int i = ; 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 = ;
QToolTip::showText(pEvent->globalPos(), m_list.at(i));
break;
}
// 滑鼠按下
case QEvent::MouseButtonPress:
{
m_nType = ;
break;
}
// 滑鼠釋放
case QEvent::MouseButtonRelease:
{
if (i == )
{
emit open(index);
}
else
{
emit deleteData(index);
}
break;
}
default:
break;
}
}
return bRepaint;
}
衍伸
通過上面的實作,我們可以自定義按鈕的樣式、文本、顯示區域、等,我們也可以通過QStyleOptionButton的icon和iconSize來設定按鈕的圖示與圖示大小,通過響應按鈕來實作我們自己的事件。