QAntAbstractButton.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. //
  2. // Created by Louis on 25-4-1.
  3. //
  4. #include "QAntAbstractButton.h"
  5. QAntAbstractButton::QAntAbstractButton(QWidget *parent) {
  6. // 接收悬停事件
  7. setAttribute(Qt::WA_Hover);
  8. // 设置布局方案
  9. setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
  10. }
  11. QAntAbstractButton::~QAntAbstractButton() = default;
  12. QString QAntAbstractButton::text() const {
  13. return m_text;
  14. }
  15. void QAntAbstractButton::setText(const QString &text) {
  16. if (text != m_text) {
  17. m_text = text;
  18. update();
  19. emit textChanged(text);
  20. }
  21. }
  22. QIcon QAntAbstractButton::icon() const {
  23. return m_icon;
  24. }
  25. void QAntAbstractButton::setIcon(const QIcon &icon) {
  26. if (icon.cacheKey() != m_icon.cacheKey()) {
  27. m_icon = icon;
  28. update();
  29. emit iconChanged(icon);
  30. }
  31. }
  32. QSize QAntAbstractButton::iconSize() const {
  33. return m_iconSize;
  34. }
  35. void QAntAbstractButton::setIconSize(const QSize &size) {
  36. if (m_iconSize != size) {
  37. m_iconSize = size;
  38. updateGeometry();
  39. update();
  40. }
  41. }
  42. QMargins QAntAbstractButton::padding() const {
  43. return m_padding;
  44. }
  45. void QAntAbstractButton::setPadding(const QMargins &margins) {
  46. if (m_padding != margins) {
  47. m_padding = margins;
  48. updateGeometry();
  49. update();
  50. }
  51. }
  52. QAntAbstractButton::ButtonState QAntAbstractButton::currentState() const {
  53. return m_state;
  54. }
  55. void QAntAbstractButton::paintText(QPainter &painter, const QRect &textRect) {
  56. painter.save();
  57. painter.setPen(palette().color(foregroundRole()));
  58. painter.setFont(font());
  59. painter.drawText(textRect, Qt::AlignCenter, m_text);
  60. painter.restore();
  61. }
  62. void QAntAbstractButton::paintIcon(QPainter &painter, const QRect &iconRect) {
  63. QIcon::Mode mode = QIcon::Normal;
  64. if (!isEnabled()) {
  65. mode = QIcon::Disabled;
  66. }
  67. else if (m_state == PressedState) {
  68. mode = QIcon::Selected;
  69. }
  70. m_icon.paint(&painter, iconRect, Qt::AlignCenter, mode);
  71. }
  72. void QAntAbstractButton::paintFocusIndicator(QPainter &painter) {
  73. painter.save();
  74. QPen pen(palette().highlight(), 1, Qt::DotLine);
  75. painter.setPen(pen);
  76. painter.setBrush(Qt::NoBrush);
  77. painter.drawRect(rect().adjusted(1, 1, -1, -1));
  78. painter.restore();
  79. }
  80. void QAntAbstractButton::paintBackground(QPainter &painter) {
  81. painter.fillRect(rect(), palette().window());
  82. }
  83. void QAntAbstractButton::paintBorder(QPainter &painter) {
  84. painter.save();
  85. QPen pen(palette().shadow(), 1);
  86. painter.setPen(pen);
  87. painter.setBrush(Qt::NoBrush);
  88. painter.drawRect(rect().adjusted(0, 0, -1, -1));
  89. painter.restore();
  90. }
  91. QRect QAntAbstractButton::calculateTextRect(const QRect &contentsRect) const {
  92. QFontMetrics fm(font());
  93. QRect textRect = fm.boundingRect(contentsRect, Qt::AlignCenter, m_text);
  94. if (!m_icon.isNull()) {
  95. textRect.moveLeft(contentsRect.left() + m_iconSize.width() + 4);
  96. }
  97. return textRect;
  98. }
  99. QRect QAntAbstractButton::calculateIconRect(const QRect &contentsRect) const {
  100. return QRect(contentsRect.left(), contentsRect.center().y() - m_iconSize.height() / 2,
  101. m_iconSize.width(), m_iconSize.height());
  102. }
  103. void QAntAbstractButton::paintEvent(QPaintEvent *event) {
  104. Q_UNUSED(event);
  105. QPainter painter(this);
  106. paintBackground(painter);
  107. switch (m_state) {
  108. case NormalState:
  109. paintNormalState(painter);
  110. break;
  111. case HoverState:
  112. paintHoverState(painter);
  113. break;
  114. case PressedState:
  115. paintPressedState(painter);
  116. break;
  117. case DisabledState:
  118. paintDisabledState(painter);
  119. break;
  120. case LoadingState:
  121. paintLoadingState(painter);
  122. break;
  123. }
  124. paintBorder(painter);
  125. QRect contentsRect = rect().marginsRemoved(m_padding);
  126. if (!m_icon.isNull() && m_state != LoadingState) {
  127. QRect iconRect = calculateIconRect(contentsRect);
  128. paintText(painter, iconRect);
  129. }
  130. if (!m_text.isEmpty() && m_state != LoadingState) {
  131. QRect textRect = calculateTextRect(contentsRect);
  132. paintText(painter, textRect);
  133. }
  134. if (hasFocus()) {
  135. paintFocusIndicator(painter);
  136. }
  137. }
  138. void QAntAbstractButton::mousePressEvent(QMouseEvent *event) {
  139. if (event->button() == Qt::LeftButton && !m_loading && isEnabled()) {
  140. m_mousePressed = true;
  141. updateButtonState(PressedState);
  142. emit pressed();
  143. event->accept();
  144. }
  145. }
  146. void QAntAbstractButton::mouseReleaseEvent(QMouseEvent *event) {
  147. if (m_mousePressed && event->button() == Qt::LeftButton) {
  148. m_mousePressed = false;
  149. if (rect().contains(event->pos())) {
  150. emit clicked();
  151. updateButtonState(HoverState);
  152. }
  153. else {
  154. updateButtonState(NormalState);
  155. }
  156. }
  157. emit release();
  158. event->accept();
  159. }
  160. void QAntAbstractButton::mouseMoveEvent(QMouseEvent *event) {
  161. if (m_mousePressed) {
  162. if (rect().contains(event->pos())) {
  163. updateButtonState(PressedState);
  164. }
  165. else {
  166. QWidget::mouseMoveEvent(event);
  167. }
  168. }
  169. }
  170. void QAntAbstractButton::enterEvent(QEnterEvent *event) {
  171. if (isEnabled() && !m_loading && !m_mousePressed) {
  172. updateButtonState(HoverState);
  173. }
  174. QWidget::enterEvent(event);
  175. }
  176. void QAntAbstractButton::leaveEvent(QEvent *event) {
  177. if (isEnabled() && !m_loading) {
  178. updateButtonState(NormalState);
  179. }
  180. QWidget::leaveEvent(event);
  181. }
  182. void QAntAbstractButton::focusInEvent(QFocusEvent *event) {
  183. update();
  184. QWidget::focusInEvent(event);
  185. }
  186. void QAntAbstractButton::focusOutEvent(QFocusEvent *event) {
  187. update();
  188. QWidget::focusOutEvent(event);
  189. }
  190. void QAntAbstractButton::changeEvent(QEvent *event) {
  191. if (event->type() == QEvent::EnabledChange) {
  192. if (isEnabled()) {
  193. updateButtonState(NormalState);
  194. }
  195. else {
  196. updateButtonState(DisabledState);
  197. }
  198. emit enabledChanged(isEnabled());
  199. }
  200. QWidget::changeEvent(event);
  201. }
  202. void QAntAbstractButton::updateButtonState(ButtonState newState) {
  203. if (newState == m_state)
  204. return;
  205. ButtonState oldState = m_state;
  206. m_state = newState;
  207. animateStateChange(oldState, m_state);
  208. update();
  209. }
  210. void QAntAbstractButton::animateStateChange(ButtonState oldState, ButtonState newState) {
  211. Q_UNUSED(oldState);
  212. Q_UNUSED(newState);
  213. }