【Qt 控件】自定义按钮
效果图
核心源代码
MyButton.h
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QMouseEvent>
class MyButton : public QWidget
{
Q_OBJECT
public:
explicit MyButton(const bool& bType = false, QWidget *parent = 0);
void SetPaintText(const QString& sText); // 设置绘制文本
void SetBlockColor(const QColor& color); // 设置色块颜色
QString GetPaintText(); // 获得绘制文本
QColor GetBlockColor(); // 获得色块颜色
protected:
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; // 绘制事件
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; // 鼠标按下事件
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; // 鼠标释放事件
signals:
// 状态改变时,发射信号
void toggled();
private:
bool m_bChecked; // 是否选中
QColor m_checkColor; // 选中颜色
QString m_sText; // 绘制文本
bool m_bType; // 为0则显示文本,为1则显示色块
};
#endif // MYBUTTON_H
MyButton.cpp
#include "MyButton.h"
MyButton::MyButton(const bool& bType, QWidget *parent)
: QWidget(parent)
{
// 鼠标滑过光标形状 - 手型
setCursor(Qt::PointingHandCursor);
m_checkColor = QColor(0, 150, 136);
m_bChecked = false;
m_bType = bType;
this->setFixedSize(128, 60);
}
// 绘制开关
void MyButton::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
// 根据按钮状态,设置绘制颜色
QColor paintColor;
if (isEnabled()) { // 判断按钮是否可用
// 可用状态
if (m_bChecked)
paintColor = QColor(73, 143, 248);
else
paintColor = QColor(112, 112, 112);
} else {
// 不可用状态
paintColor = QColor(190, 190, 190, 0.26);
}
QPainter painter(this);
// 反走样
painter.setRenderHint(QPainter::Antialiasing, true);
// 设置画笔颜色
QPen pen;
pen.setWidth(3);
pen.setColor(paintColor);
painter.setPen(pen);
// 绘制边框
painter.drawRoundRect(0, 0, 128, 60, 8);
// 绘制多边形-倒三角形箭头
const QPointF points[4] = {QPointF(84, 20), QPointF(106, 20), QPointF(95, 40), QPointF(84, 20)};
painter.setBrush(paintColor);
painter.drawPolygon(points, 4);
if (!m_bType) {
// 绘制文本
QFont font;
font.setFamily("Microsoft YaHei");
font.setPointSize(20);
painter.setFont(font);
painter.drawText(QRect(14, 11, 128, 60), m_sText);
} else {
// 绘制色块
if (m_checkColor.red() == 255) {
painter.setPen(QPen(QColor(191, 191, 191), 1)); // 设置边框颜色
painter.setBrush(m_checkColor);
painter.drawRoundRect(12, 10, 41, 41, 5, 5);
} else {
painter.setPen(m_checkColor);
painter.setBrush(m_checkColor);
painter.drawRoundRect(12, 10, 41, 41, 5, 5);
}
}
}
// 鼠标按下事件
void MyButton::mousePressEvent(QMouseEvent *event)
{
if (isEnabled()) {
if (event->buttons() & Qt::LeftButton) {
m_bChecked = true;
this->update();
}
}
}
// 鼠标释放事件 - 切换开关状态、发射toggled()信号
void MyButton::mouseReleaseEvent(QMouseEvent *event)
{
if (isEnabled()) {
if ((event->type() == QMouseEvent::MouseButtonRelease) \
&& (event->button() == Qt::LeftButton)) {
event->accept();
emit toggled();
m_bChecked = false;
this->update();
}
}
}
// 设置绘制文本
void MyButton::SetPaintText(const QString& sText)
{
m_sText = sText;
this->update();
}
// 设置色块颜色
void MyButton::SetBlockColor(const QColor& color)
{
m_checkColor = color;
}
// 获得绘制文本
QString MyButton::GetPaintText()
{
return m_sText;
}
// 获得色块颜色
QColor MyButton::GetBlockColor()
{
return m_checkColor;
}
Widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
// 初始化自定义按钮
MyButton *pBtnPos = new MyButton(false);
MyButton *pBtnSize = new MyButton(false);
MyButton *pBtnColor = new MyButton(true);
pBtnPos->SetPaintText(QString::fromLocal8Bit("居中"));
pBtnColor->SetBlockColor(QColor(196, 68, 21));
pBtnSize->SetPaintText(QString::fromLocal8Bit("20px"));
// 水平布局
QHBoxLayout *pHLayoutMain = new QHBoxLayout(this);
pHLayoutMain->addWidget(pBtnPos);
pHLayoutMain->addWidget(pBtnColor);
pHLayoutMain->addWidget(pBtnSize);
// 连接信号槽
connect(pBtnPos, SIGNAL(toggled()), this, SLOT(onToggled()));
connect(pBtnColor, SIGNAL(toggled()), this, SLOT(onToggled()));
connect(pBtnSize, SIGNAL(toggled()), this, SLOT(onToggled()));
}
Widget::~Widget()
{
delete ui;
}
// 自定义按钮触发信号槽
void Widget::onToggled()
{
qDebug() << "clicked";
}
GitHub代码下载
下载链接为:https://github.com/confidentFeng/QtAppProject/tree/MyButton
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探