Qt之模型/视图(自定义按钮)

来源:互联网 发布:淘宝历史宝贝精灵 编辑:程序博客网 时间:2024/05/19 23:15

简述

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

  • 简述
  • 效果
  • QStyledItemDelegate
    • 源码
  • 衍伸

效果

这里写图片描述

QStyledItemDelegate

源码

.h

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

class TableViewDelegate: public QStyledItemDelegate{    Q_OBJECTpublic:    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来设置按钮的图标与图标大小,通过响应按钮来实现我们自己的事件。

11 0
原创粉丝点击