简述
实现类似企业微信左侧导航栏的上下结构的按钮
效果图
可以用2种方案实现,2种最终效果图如下:
方案1 QToolButton 实现
ui.toolButton->setFixedSize(50, 50);
ui.toolButton->setCheckable(true);
ui.toolButton->setAutoExclusive(true);
ui.toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ui.toolButton_2->setFixedSize(50, 50);
ui.toolButton_2->setCheckable(true);
ui.toolButton_2->setAutoExclusive(true);
ui.toolButton_2->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
connect(ui.toolButton, &QToolButton::toggled, this, [=]() {
ui.toolButton->setIcon(ui.toolButton->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
});
connect(ui.toolButton_2, &QToolButton::toggled, this, [=]() {
ui.toolButton_2->setIcon(ui.toolButton_2->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
});
qss
QToolButton
{
border:none;
background-color: rgba(255,255,255,0);
color: #CADFFF;
}
QToolButton:hover
{
border-radius:5px;
background-color: rgba(255,255,255,15);
color: #CADFFF;
}
QToolButton:checked
{
border-radius:5px;
background-color: rgba(255,255,255,20);
color: #FFFFFF;
}
QToolButton:checked:hover
{
background-color: rgba(255,255,255,30);
color: #FFFFFF;
}
用 QToolButton 实现有个按下效果,按下之后图标会往右偏一点点。
UI像素眼表示不服,重做!
方案2 继承 QPushButton 重写 paintEvent 实现
新建一个继承自QPushButton的子类 QUpdownButton
QUpdownButton.h
#pragma once
#include <QPushButton>
#include "ui_QUpdownButton.h"
class QUpdownButton : public QPushButton
{
Q_OBJECT
public:
QUpdownButton(const QString &text, QString iconNormal, QString iconSelect, QWidget *parent = Q_NULLPTR);
~QUpdownButton();
void paintEvent(QPaintEvent *event);
private:
Ui::QUpdownButton ui;
QString m_text;
QString m_iconNormal;
QString m_iconSelect;
};
QUpdownButton.cpp
#include "QUpdownButton.h"
#include <QPainter>
#include <QPixmap>
QUpdownButton::QUpdownButton(const QString &text, QString iconNormal, QString iconSelect, QWidget *parent)
: QPushButton(parent),
m_text(text)
, m_iconNormal(iconNormal)
, m_iconSelect(iconSelect)
{
ui.setupUi(this);
setFixedSize(50, 50);
setText(text);
setStyleSheet(QString::fromLocal8Bit("\
QPushButton{ border-radius:6px; background-color: rgba(255,255,255,0); color: #CADFFF; font: 9pt \"微软雅黑\"; text-align: bottom; padding-bottom: 6px; }\
QPushButton:hover{ background-color: rgba(255,255,255,15); color: #CADFFF; }\
QPushButton:pressed{ background-color: rgba(255,255,255,20); color: #CADFFF; }\
QPushButton:checked{ background-color: rgba(255,255,255,20); color: #FFFFFF; }\
QPushButton:checked:hover{ background-color: rgba(255,255,255,30); color: #FFFFFF; }\
"));
}
QUpdownButton::~QUpdownButton()
{
}
void QUpdownButton::paintEvent(QPaintEvent *event)
{
QPushButton::paintEvent(event); // 调用基类的 paintEvent
QPainter painter(this);
QRect buttonRect = this->rect();
// 加载图片
QString btIcon = this->isChecked() ? m_iconSelect : m_iconNormal;
QPixmap pixmap(btIcon);
// 图标区域高度占按钮高度的2/3,文字占1/3
int iconAreaHeight = buttonRect.height() - (buttonRect.height() / 3);
// 按钮图标尺寸20*20
int newWidth = 20;
int newHeight = 20;
// 计算图标位置
int x = (buttonRect.width() - newWidth) / 2;
int y = (iconAreaHeight - newHeight) / 2;
// 绘制缩放后的图片
QPixmap scaledPixmap = pixmap.scaled(newWidth, newHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
painter.drawPixmap(x, y, scaledPixmap);
// 绘制文字
//QString text = this->text();
//QRect textRect = QRect(0, scaledHeight-RATIO_X(6), buttonRect.width(), buttonRect.height() - scaledHeight);
//painter.drawText(textRect, Qt::AlignCenter, m_text);
}
使用:
ui.toolButton->setFixedSize(50, 50);
ui.toolButton->setCheckable(true);
ui.toolButton->setAutoExclusive(true);
ui.toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ui.toolButton_2->setFixedSize(50, 50);
ui.toolButton_2->setCheckable(true);
ui.toolButton_2->setAutoExclusive(true);
ui.toolButton_2->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
connect(ui.toolButton, &QToolButton::toggled, this, [=]() {
ui.toolButton->setIcon(ui.toolButton->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
});
connect(ui.toolButton_2, &QToolButton::toggled, this, [=]() {
ui.toolButton_2->setIcon(ui.toolButton_2->isChecked() ? QIcon(":/pafeyDemo/Resources/bar/nav_app_select.png") : QIcon(":/pafeyDemo/Resources/bar/nav_app_normal.png"));
});
m_updownButton = new QUpdownButton(QString::fromLocal8Bit("应用"), QString(":/pafeyDemo/Resources/bar/nav_app_normal.png"), QString(":/pafeyDemo/Resources/bar/nav_app_select.png"));
m_updownButton2 = new QUpdownButton(QString::fromLocal8Bit("应用2"), QString(":/pafeyDemo/Resources/bar/nav_app_normal.png"), QString(":/pafeyDemo/Resources/bar/nav_app_select.png"));
ui.verticalLayout_2->insertWidget(2, m_updownButton);
ui.verticalLayout_2->insertWidget(3, m_updownButton2);
m_updownButton->setCheckable(true);
m_updownButton->setAutoExclusive(true);
m_updownButton2->setCheckable(true);
m_updownButton2->setAutoExclusive(true);
最终效果如下:
第1,2图标是QToolButton,第3,4图标是重写 paintEvent 的 QPushButton 子类
第2种方案实现效果,图标的位置不会动了。
完工。