当前位置: 首页 > news >正文

在Qt中实现SwitchButton(开关按钮)

Qt的官方UI控件中是并不包含SwitchButton的,不过可以直接手动创建一个类作为switchbutton来实现这样的效果。

效果图象:

switchbutton.h代码:

#ifndef SWITCHBUTTON_H
#define SWITCHBUTTON_H#include <QWidget>
#include <QPropertyAnimation>
#include <QPainter>
#include <QMouseEvent>class SwitchButton : public QWidget
{Q_OBJECTQ_PROPERTY(int sliderPosition READ getSliderPosition WRITE setSliderPosition)public:explicit SwitchButton(QWidget *parent = nullptr);// 获取当前状态bool isChecked() const { return m_checked; }// 设置状态void setChecked(bool checked);// 设置背景颜色void setBackgroundColor(const QColor &onColor, const QColor &offColor);// 设置滑块颜色void setSliderColor(const QColor &color);signals:// 状态改变信号void toggled(bool checked);protected:void paintEvent(QPaintEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void resizeEvent(QResizeEvent *event) override;private:int getSliderPosition() const { return m_sliderPosition; }void setSliderPosition(int position);void updateSliderPosition();bool m_checked = false;int m_sliderPosition = 0;QColor m_onColor = QColor(0, 150, 255);QColor m_offColor = QColor(150, 150, 150);QColor m_sliderColor = Qt::white;int m_sliderMargin = 2;int m_sliderRadius = 0;QPropertyAnimation *m_animation;
};#endif // SWITCHBUTTON_H

switchbutton.cpp代码

#include "switchbutton.h"SwitchButton::SwitchButton(QWidget *parent): QWidget(parent)
{setFixedSize(60, 30);// 初始化动画m_animation = new QPropertyAnimation(this, "sliderPosition");m_animation->setDuration(200);updateSliderPosition();
}void SwitchButton::setChecked(bool checked)
{if (m_checked != checked) {m_checked = checked;updateSliderPosition();update();emit toggled(m_checked);}
}void SwitchButton::setBackgroundColor(const QColor &onColor, const QColor &offColor)
{m_onColor = onColor;m_offColor = offColor;update();
}void SwitchButton::setSliderColor(const QColor &color)
{m_sliderColor = color;update();
}void SwitchButton::paintEvent(QPaintEvent *event)
{Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 绘制背景QColor bgColor = m_checked ? m_onColor : m_offColor;painter.setBrush(bgColor);painter.setPen(Qt::NoPen);// 绘制圆角矩形背景int cornerRadius = height() / 2;painter.drawRoundedRect(rect(), cornerRadius, cornerRadius);// 绘制滑块painter.setBrush(m_sliderColor);int sliderDiameter = height() - 2 * m_sliderMargin;QRect sliderRect(m_sliderPosition, m_sliderMargin,sliderDiameter, sliderDiameter);painter.drawEllipse(sliderRect);
}void SwitchButton::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {setChecked(!m_checked);event->accept();} else {QWidget::mousePressEvent(event);}
}void SwitchButton::resizeEvent(QResizeEvent *event)
{Q_UNUSED(event);updateSliderPosition();
}void SwitchButton::setSliderPosition(int position)
{if (m_sliderPosition != position) {m_sliderPosition = position;update();}
}void SwitchButton::updateSliderPosition()
{int startPos = m_sliderMargin;int endPos = width() - height() + m_sliderMargin;if (m_checked) {m_sliderPosition = endPos;} else {m_sliderPosition = startPos;}// 设置动画m_animation->stop();m_animation->setStartValue(m_sliderPosition);m_animation->setEndValue(m_checked ? endPos : startPos);m_animation->start();
}

mainwindow.h代码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "switchbutton.h"class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void onSwitch1Toggled(bool checked);void onSwitch2Toggled(bool checked);void onSwitch3Toggled(bool checked);private:void setupUI();SwitchButton *m_switch1;SwitchButton *m_switch2;SwitchButton *m_switch3;QLabel *m_statusLabel1;QLabel *m_statusLabel2;QLabel *m_statusLabel3;
};#endif // MAINWINDOW_H

mainwindow.cpp代码

#include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{setupUI();// 连接信号槽connect(m_switch1, &SwitchButton::toggled, this, &MainWindow::onSwitch1Toggled);connect(m_switch2, &SwitchButton::toggled, this, &MainWindow::onSwitch2Toggled);connect(m_switch3, &SwitchButton::toggled, this, &MainWindow::onSwitch3Toggled);
}MainWindow::~MainWindow()
{
}void MainWindow::setupUI()
{QWidget *centralWidget = new QWidget(this);setCentralWidget(centralWidget);QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);// 创建第一个开关QHBoxLayout *layout1 = new QHBoxLayout();m_switch1 = new SwitchButton(this);m_statusLabel1 = new QLabel("开关1: 关闭", this);layout1->addWidget(new QLabel("WiFi:", this));layout1->addWidget(m_switch1);layout1->addWidget(m_statusLabel1);layout1->addStretch();// 创建第二个开关QHBoxLayout *layout2 = new QHBoxLayout();m_switch2 = new SwitchButton(this);m_switch2->setBackgroundColor(QColor(0, 200, 0), QColor(100, 100, 100)); // 绿色开启状态m_statusLabel2 = new QLabel("开关2: 关闭", this);layout2->addWidget(new QLabel("蓝牙:", this));layout2->addWidget(m_switch2);layout2->addWidget(m_statusLabel2);layout2->addStretch();// 创建第三个开关QHBoxLayout *layout3 = new QHBoxLayout();m_switch3 = new SwitchButton(this);m_switch3->setBackgroundColor(QColor(255, 100, 0), QColor(150, 150, 150)); // 橙色开启状态m_switch3->setSliderColor(QColor(240, 240, 240));m_statusLabel3 = new QLabel("开关3: 关闭", this);layout3->addWidget(new QLabel("飞行模式:", this));layout3->addWidget(m_switch3);layout3->addWidget(m_statusLabel3);layout3->addStretch();// 添加到主布局mainLayout->addLayout(layout1);mainLayout->addLayout(layout2);mainLayout->addLayout(layout3);mainLayout->addStretch();setWindowTitle("Qt SwitchButton 示例");resize(300, 200);
}void MainWindow::onSwitch1Toggled(bool checked)
{m_statusLabel1->setText(QString("开关1: %1").arg(checked ? "开启" : "关闭"));qDebug() << "WiFi" << (checked ? "已开启" : "已关闭");
}void MainWindow::onSwitch2Toggled(bool checked)
{m_statusLabel2->setText(QString("开关2: %1").arg(checked ? "开启" : "关闭"));qDebug() << "蓝牙" << (checked ? "已开启" : "已关闭");
}void MainWindow::onSwitch3Toggled(bool checked)
{m_statusLabel3->setText(QString("开关3: %1").arg(checked ? "开启" : "关闭"));qDebug() << "飞行模式" << (checked ? "已开启" : "已关闭");
}

http://www.dtcms.com/a/478596.html

相关文章:

  • day9_elementPlus2
  • qiankun子应用使用elementUI操作反馈图标不显示
  • Vue3.0: v-model 组件双向绑定学习文档 (v3.4 前后对比 + TypeScript)
  • 中山哪里有做微网站的做ppt图片用的网站
  • 『 QT 』QT窗口坐标体系详解
  • 服务器里怎么建设网站网站开发网站设计素材
  • 从多个数据源(CSV, Excel, SQL)自动整合数据
  • 智慧零售天气预知可视化监控平台
  • C++设计模式_结构型模式_享元模式Flyweight
  • 网站备案名称能重复吗微官网怎么制作
  • SpringBoot + MyBatis 注解开发入门实践
  • Java EE初阶--多线程
  • 深入理解梯度消失:从DNN到RNN的全面解析与解决方案
  • 南京电子商务网站开发公司石油化工工程建设人才招聘网站
  • 大数据实战:Python+Flask 汽车数据分析可视化系统(爬虫+线性回归预测+推荐 源码+文档)✅
  • 算法8.0
  • 网站左侧导航栏设计一个网站的建设要经过哪几个阶段
  • Java-Linux环境下查看JDK安装路径
  • 嘉立创学习
  • QML学习笔记(三十四)QML的GroupBox、RadioButton
  • AI Agent 的技术架构、产业赋能与治理挑战研究 —— 基于 2024-2025 年技术突破与应用实践的分析
  • 设计美观网站有哪些辽宁网站建设价位
  • vtkFillHolesFilter——3D网格补孔的“一键修复”工具,从原理到避坑
  • 网站建设完整代码深圳开公司流程及费用
  • Vue3为什么选择用Vite?使用指南与优势解析
  • 【STL】set容器(2336.无限集中的最小数字)
  • 第一章 计算机系统概论1
  • Cannot invoke “String.length()“ because “<parameter1>“ is null
  • H5使用环信实现视频或语音通话
  • SMTPman高效稳定的smtp服务器使用指南解析