基于QToolButton封装,解决Icon不能设置hover和press态的问题
1 #pragma once 2 #include <QToolButton> 3 #include <QBoxLayout> 4 #include <QLabel> 5 6 /* 基于QToolButton封装,解决Icon不能设置hover和press态的问题 7 QSS使用方法: 8 qproperty-dpiAdaptionImage: url(:/img/res/imgmainframe/icon_exit_presentation.png); 9 qproperty-iconSize: 18px 18px; 10 qproperty-buttonStyle:3; 对应ToolButtonStyle的枚举值,默认为2(左右) 11 qproperty-space:16; icon和文字的间隔,默认是8 12 */ 13 class CenteredToolButtonStyle; 14 class IconTextButton : public QToolButton { 15 Q_OBJECT 16 Q_PROPERTY(QString dpiAdaptionImage READ getDpiAdaptionImage WRITE setDpiAdaptionImage) 17 Q_PROPERTY(QString buttonType READ getButtonTypeFromQss WRITE setButtonTypeFromQss) 18 Q_PROPERTY(QString buttonStyle READ getToolButtonStyleFromQss WRITE setToolButtonStyleFromQss) 19 Q_PROPERTY(QString space READ getSpaceFromQss WRITE setSpaceFromQss) 20 21 enum class ImageType 22 { 23 THREE_STATUS = 3, //三态图片 24 FOUR_STATUS = 4, //四态图片 25 }; 26 27 enum class ButtonStatus 28 { 29 NORMAL = 0, //正常 30 HOVER = 1, //悬浮 31 PRESS = 2, //按下 32 DISABLE = 3, //禁用态 33 }; 34 35 public: 36 IconTextButton(QWidget* parent = nullptr, ImageType type = ImageType::THREE_STATUS); 37 IconTextButton(const QString& text, QWidget* parent = nullptr, ImageType type = ImageType::THREE_STATUS); 38 39 protected: 40 QString getDpiAdaptionImage(); 41 void setDpiAdaptionImage(const QString& strIconPath); 42 void setButtonTypeFromQss(const QString& strType); 43 QString getButtonTypeFromQss(); 44 void setToolButtonStyleFromQss(const QString& strStyle); 45 QString getToolButtonStyleFromQss(); 46 void setSpaceFromQss(const QString& strStyle); 47 QString getSpaceFromQss(); 48 49 virtual void leaveEvent(QEvent* event) override; 50 virtual void enterEvent(QEvent* event) override; 51 virtual void mousePressEvent(QMouseEvent* event) override; 52 virtual void mouseReleaseEvent(QMouseEvent* event) override; 53 virtual void paintEvent(QPaintEvent* event) override; 54 virtual void showEvent(QShowEvent* event) override; 55 56 private: 57 bool m_bLeftPress = false; 58 ButtonStatus m_btnStatus = ButtonStatus::NORMAL; 59 ImageType m_ImageType = ImageType::THREE_STATUS; 60 int m_nImageWidth = 0; 61 int m_nImageHeight = 0; 62 QString m_strImagePath; 63 QPixmap m_pixmap; 64 Qt::ToolButtonStyle m_ToolButtonStyle = Qt::ToolButtonTextBesideIcon; 65 CenteredToolButtonStyle* m_pCenteredToolButtonStyle = nullptr; 66 int m_nSpace = 8; 67 };
.cpp
#include "IconTextButton.h" #include "qevent.h" #include "CenteredToolButtonStyle.h" IconTextButton::IconTextButton(QWidget* parent /*= nullptr*/, ImageType type /*= IconPicType::THREE_STATUS*/) : IconTextButton("", parent, type) { } IconTextButton::IconTextButton(const QString& text, QWidget* parent /*= nullptr*/, ImageType type /*= IconPicType::THREE_STATUS*/) : QToolButton(parent) , m_ImageType(type) { setText(text); setToolButtonStyle(m_ToolButtonStyle); } void IconTextButton::setDpiAdaptionImage(const QString& strIconPath) { if (0 == strIconPath.compare(m_strImagePath)) { return; } m_strImagePath = strIconPath; m_pixmap.load(m_strImagePath); m_nImageWidth = m_pixmap.width() / static_cast<int>(m_ImageType); m_nImageHeight = m_pixmap.height(); int nSub = static_cast<int>(m_btnStatus); QPixmap iconPixmap = m_pixmap.copy(m_nImageWidth * nSub, 0, m_nImageWidth, m_nImageHeight) .scaled(iconSize().width(), iconSize().height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); setIcon(iconPixmap); } void IconTextButton::setButtonTypeFromQss(const QString& strType) { m_ImageType = static_cast<ImageType>(strType.toInt()); } QString IconTextButton::getDpiAdaptionImage() { return m_strImagePath; } QString IconTextButton::getButtonTypeFromQss() { return QString("%1").arg(static_cast<int>(m_ImageType)); } void IconTextButton::setToolButtonStyleFromQss(const QString& strStyle) { m_ToolButtonStyle = static_cast<Qt::ToolButtonStyle>(strStyle.toInt()); setToolButtonStyle(m_ToolButtonStyle); } QString IconTextButton::getToolButtonStyleFromQss() { return QString("%1").arg(static_cast<int>(m_ToolButtonStyle)); } void IconTextButton::setSpaceFromQss(const QString& strStyle) { m_nSpace = strStyle.toInt(); } QString IconTextButton::getSpaceFromQss() { return QString("%1").arg(static_cast<int>(m_nSpace)); } void IconTextButton::leaveEvent(QEvent* event) { __super::leaveEvent(event); m_btnStatus = ButtonStatus::NORMAL; } void IconTextButton::enterEvent(QEvent* event) { __super::enterEvent(event); m_btnStatus = ButtonStatus::HOVER; } void IconTextButton::mousePressEvent(QMouseEvent* event) { __super::mousePressEvent(event); if (event->button() == Qt::LeftButton) { m_bLeftPress = true; m_btnStatus = ButtonStatus::PRESS; } } void IconTextButton::mouseReleaseEvent(QMouseEvent* event) { __super::mouseReleaseEvent(event); if (m_bLeftPress) { m_bLeftPress = false; m_btnStatus = ButtonStatus::NORMAL; } } void IconTextButton::paintEvent(QPaintEvent* event) { __super::paintEvent(event); ButtonStatus status = m_btnStatus; if (isChecked()) { status = ButtonStatus::PRESS; } if (!isEnabled()) { status = ButtonStatus::DISABLE; } int nSub = static_cast<int>(status); QPixmap iconPixmap = m_pixmap.copy(m_nImageWidth * nSub, 0, m_nImageWidth, m_nImageHeight) .scaled(iconSize().width(), iconSize().height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); setIcon(iconPixmap); // 自定义样式用于居中 if (m_ToolButtonStyle == Qt::ToolButtonTextBesideIcon || m_ToolButtonStyle == Qt::ToolButtonTextUnderIcon) { if (m_pCenteredToolButtonStyle == nullptr) { m_pCenteredToolButtonStyle = new CenteredToolButtonStyle(this, m_ToolButtonStyle, iconSize(), m_nSpace); setStyle(m_pCenteredToolButtonStyle); } } } void IconTextButton::showEvent(QShowEvent* event) { QToolButton::showEvent(event); m_btnStatus = ButtonStatus::NORMAL; update(); }
自定义居中样式:
.h
#pragma once #include <QProxyStyle> #include <QToolButton> class CenteredToolButtonStyle : public QProxyStyle { Q_OBJECT public: CenteredToolButtonStyle(QToolButton* parent, Qt::ToolButtonStyle buttonStyle, const QSize& sIcon, const int& space); virtual void drawItemPixmap(QPainter* painter, const QRect& rect, int, const QPixmap& pixmap) const override; virtual void drawItemText(QPainter* painter, const QRect& rect, int flags, const QPalette& pal, bool enabled, const QString& text, QPalette::ColorRole textRole = QPalette::NoRole) const override; void Draw(QPainter* painter) const; private: const QToolButton* m_pParent = nullptr; const QSize m_iconSize; mutable QString m_text; mutable QPixmap m_pixMap; mutable QRect m_rect; mutable int m_nFlag = 0; mutable int m_ny = -1; mutable int m_nx = 1; mutable bool m_bEnabled = true; mutable QPalette m_palette; mutable QPalette::ColorRole m_textRole = QPalette::NoRole; bool m_bDrawFinished = false; Qt::ToolButtonStyle m_buttonStyle = Qt::ToolButtonTextBesideIcon; int m_nSpace = 8; };
.cpp
#include "CenteredToolButtonStyle.h" namespace { constexpr auto SPACE = 6; } CenteredToolButtonStyle::CenteredToolButtonStyle(QToolButton* parent, Qt::ToolButtonStyle buttonStyle, const QSize& sIcon, const int& space) : QProxyStyle(), m_pParent(parent), m_iconSize(sIcon), m_buttonStyle(buttonStyle), m_nSpace(space) { if (parent != nullptr) { setParent(parent); } } void CenteredToolButtonStyle::drawItemPixmap(QPainter* painter, const QRect& rect, int, const QPixmap& pixmap) const { m_pixMap = pixmap; m_ny = rect.y(); m_nx = rect.x(); Draw(painter); } void CenteredToolButtonStyle::drawItemText(QPainter* painter, const QRect& rect, int flags, const QPalette& pal, bool enabled, const QString& text, QPalette::ColorRole textRole /* = QPalette::NoRole*/) const { m_text = text; m_rect = rect; m_nFlag = flags | Qt::AlignCenter; m_bEnabled = enabled; m_palette = pal; m_textRole = textRole; Draw(painter); } void CenteredToolButtonStyle::Draw(QPainter* painter) const { if (m_pParent == nullptr) { return; } if (m_buttonStyle == Qt::ToolButtonTextUnderIcon) { if (m_nx >= 0) { if (m_rect.x() != m_nx) return; auto iconRect = m_rect; m_nx = 0; iconRect.adjust(0, -m_iconSize.height() - m_nSpace, 0, -itemTextRect(m_pParent->fontMetrics(), m_rect, m_nFlag, m_bEnabled, m_text).height()); QProxyStyle::drawItemPixmap(painter, iconRect, Qt::AlignCenter, m_pixMap); } } else if (m_buttonStyle == Qt::ToolButtonTextBesideIcon) { if (m_ny >= 0) { if (m_rect.y() != m_ny) return; auto iconRect = m_rect; m_ny = 0; iconRect.adjust(-m_iconSize.width() - m_nSpace, 0, -itemTextRect(m_pParent->fontMetrics(), m_rect, m_nFlag, m_bEnabled, m_text).width(), 0); QProxyStyle::drawItemPixmap(painter, iconRect, Qt::AlignCenter, m_pixMap); } } QProxyStyle::drawItemText(painter, m_rect, m_nFlag, m_palette, m_bEnabled, m_text, m_textRole); }