当前位置:网站首页>qt自定义滑动按钮(美观且使用方便)
qt自定义滑动按钮(美观且使用方便)
2022-07-28 05:25:00 【小土同学!】
前言
某一次qt界面需要用到类似苹果上的滑动按钮,但发现qt中并没有类似的控件。百度之后发现有位博主的自己设计了这种控件,美观度和操作性都很高。但该博主没有介绍用法,所以特此记录,以便新手使用。
链接:原文链接
先上截图:

代码:
switchbutton.h
#ifndef switchbutton_H
#define switchbutton_H
#include <QWidget>
#include <QTimer>
#include <QColor>
class switchbutton : public QWidget
{
Q_OBJECT
public:
explicit switchbutton(QWidget *parent = 0);
~switchbutton(){
}
signals:
void statusChanged(bool checked);
public slots:
void updateValue();
private:
void drawBackGround(QPainter *painter);
void drawSlider(QPainter *painter);
protected:
void paintEvent(QPaintEvent *ev);
void mousePressEvent(QMouseEvent *ev);
private:
int m_space; //滑块距离边界距离
int m_radius; //圆角角度
bool m_checked; //是否选中
bool m_showText; //是否显示文字
bool m_showCircle; //是否显示圆圈
bool m_animation; //是否使用动画
QColor m_bgColorOn; //打开时候的背景色
QColor m_bgColorOff; //关闭时候的背景色
QColor m_sliderColorOn; //打开时候滑块颜色
QColor m_sliderColorOff; //关闭时候滑块颜色
QColor m_textColor; //文字颜色
QString m_textOn; //打开时候的文字
QString m_textOff; //关闭时候的文字
QTimer *m_timer; //动画定时器
int m_step; //动画步长
int m_startX; //滑块开始X轴坐标
int m_endX; //滑块结束X轴坐标
public:
int space() const;
int radius() const;
bool checked() const;
bool showText() const;
bool showCircel() const;
bool animation() const;
QColor bgColorOn() const;
QColor bgColorOff() const;
QColor sliderColorOn() const;
QColor sliderColorOff() const;
QColor textColor() const;
QString textOn() const;
QString textOff() const;
int step() const;
int startX() const;
int endX() const;
public Q_SLOTS:
void setSpace(int space);
void setRadius(int radius);
void setChecked(bool checked);
void setShowText(bool show);
void setShowCircle(bool show);
void setAnimation(bool ok);
void setBgColorOn(const QColor &color);
void setBgColorOff(const QColor &color);
void setSliderColorOn(const QColor &color);
void setSliderColorOff(const QColor &color);
void setTextColor(const QColor &color);
void setTextOn(const QString &text);
void setTextOff(const QString &text);
};
#endif // switchbutton_H
switchbutton.cpp
#pragma execution_character_set("utf-8")
#include "switchbutton.h"
#include <QPainter>
switchbutton::switchbutton(QWidget *parent) : QWidget(parent)
{
m_space = 2;
m_radius = 5;
m_checked = false;
m_showText = true;
m_showText = false;
m_animation = true;
m_bgColorOn = QColor(102, 205, 170);//设置按钮内部颜色
m_bgColorOff = QColor(190, 190, 190);
m_sliderColorOn = QColor(255, 255, 255);
m_sliderColorOff = QColor(255, 255, 255);
m_textColor = QColor(255, 255, 255);
m_textOn = "开启";//设置按钮中的文字
m_textOff = "关闭";
m_step = 0;
m_startX = 0;
m_endX = 0;
m_timer = new QTimer(this);
m_timer->setInterval(30);
connect(m_timer, SIGNAL(timeout()), this, SLOT(updateValue()));
}
void switchbutton::drawBackGround(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
QColor bgColor = m_checked ? m_bgColorOn : m_bgColorOff;
if (isEnabled()) {
bgColor.setAlpha(150);
}
painter->setBrush(bgColor);
QRect rect(0, 0, width(), height());
int side = qMin(width(), height());
//左侧半圆
QPainterPath path1;
path1.addEllipse(rect.x(), rect.y(), side, side);
//右侧半圆
QPainterPath path2;
path2.addEllipse(rect.width() - side, rect.y(), side, side);
//中间的矩形
QPainterPath path3;
path3.addRect(rect.x() + side / 2, rect.y(), rect.width() - side, height());
QPainterPath path = path1 + path2 + path3;
painter->drawPath(path);
//绘制文本
//滑块半径
int sliderWidth = qMin(height(), width()) - m_space * 2 - 5;
if (m_checked){
QRect textRect(0, 0, width() - sliderWidth, height());
painter->setPen(QPen(m_textColor));
painter->drawText(textRect, Qt::AlignCenter, m_textOn);
} else {
QRect textRect(sliderWidth, 0, width() - sliderWidth, height());
painter->setPen(QPen(m_textColor));
painter->drawText(textRect, Qt::AlignCenter, m_textOff);
}
painter->restore();
}
void switchbutton::drawSlider(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
QColor color = m_checked ? m_sliderColorOn : m_sliderColorOff;
painter->setBrush(QBrush(color));
int sliderWidth = qMin(width(), height()) - m_space * 2;
QRect rect(m_space + m_startX, m_space, sliderWidth, sliderWidth);
painter->drawEllipse(rect);
painter->restore();
}
void switchbutton::paintEvent(QPaintEvent *ev)
{
//启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
//绘制背景
drawBackGround(&painter);
//绘制滑块
drawSlider(&painter);
}
void switchbutton::mousePressEvent(QMouseEvent *ev)
{
Q_UNUSED(ev)
m_checked = !m_checked;
emit statusChanged(m_checked);
//计算步长
m_step = width() / 10;
//计算滑块X轴终点坐标
if (m_checked) {
m_endX = width() - height();
} else {
m_endX = 0;
}
//判断是否使用动画
if (m_animation) {
m_timer->start();
} else{
m_startX = m_endX;
update();
}
}
void switchbutton::updateValue()
{
if (m_checked) {
if (m_startX < m_endX) {
m_startX += m_step;
} else {
m_startX = m_endX;
m_timer->stop();
}
} else {
if (m_startX > m_endX) {
m_startX -= m_step;
} else {
m_startX = m_endX;
m_timer->stop();
}
}
update();
}
int switchbutton::space() const
{
return m_space;
}
int switchbutton::radius() const
{
return m_radius;
}
bool switchbutton::checked() const
{
return m_checked;
}
bool switchbutton::showText() const
{
return m_showText;
}
bool switchbutton::showCircel() const
{
return m_showCircle;
}
bool switchbutton::animation() const
{
return m_animation;
}
QColor switchbutton::bgColorOn() const
{
return m_bgColorOn;
}
QColor switchbutton::bgColorOff() const
{
return m_bgColorOff;
}
QColor switchbutton::sliderColorOn() const
{
return m_sliderColorOn;
}
QColor switchbutton::sliderColorOff() const
{
return m_sliderColorOff;
}
QColor switchbutton::textColor() const
{
return m_textColor;
}
QString switchbutton::textOn() const
{
return m_textOn;
}
QString switchbutton::textOff() const
{
return m_textOff;
}
int switchbutton::step() const
{
return m_step;
}
int switchbutton::startX() const
{
return m_startX;
}
int switchbutton::endX() const
{
return m_endX;
}
void switchbutton::setSpace(int space)
{
if (m_space != space) {
m_space = space;
update();
}
}
void switchbutton::setRadius(int radius)
{
if (m_radius != radius) {
m_radius = radius;
update();
}
}
void switchbutton::setChecked(bool checked)
{
if (m_checked != checked) {
m_checked = checked;
update();
}
}
void switchbutton::setShowText(bool show)
{
if (m_showText != show) {
m_showText = show;
update();
}
}
void switchbutton::setShowCircle(bool show)
{
if (m_showCircle != show) {
m_showCircle = show;
update();
}
}
void switchbutton::setAnimation(bool ok)
{
if (m_animation != ok) {
m_animation = ok;
update();
}
}
void switchbutton::setBgColorOn(const QColor &color)
{
if (m_bgColorOn != color) {
m_bgColorOn = color;
update();
}
}
void switchbutton::setBgColorOff(const QColor &color)
{
if (m_bgColorOff != color) {
m_bgColorOff = color;
update();
}
}
void switchbutton::setSliderColorOn(const QColor &color)
{
if (m_sliderColorOn != color) {
m_sliderColorOn = color;
update();
}
}
void switchbutton::setSliderColorOff(const QColor &color)
{
if (m_sliderColorOff != color) {
m_sliderColorOff = color;
update();
}
}
void switchbutton::setTextColor(const QColor &color)
{
if (m_textColor != color) {
m_textColor = color;
update();
}
}
void switchbutton::setTextOn(const QString &text)
{
if (m_textOn != text) {
m_textOn = text;
update();
}
}
void switchbutton::setTextOff(const QString &text)
{
if (m_textOff != text) {
m_textOff = text;
update();
}
}
源码:
下面介绍一下按钮的基本使用,只需要switchbutton.h和switchbutton.cpp文件即可
先将两个类添加到代码中
因为我一直是将图形界面和代码分开的,所以只介绍通过qt designer的使用方法。在ui文件中,通过添加一个widget容器,然后把容器提升为类,就能灵活使用滑动按钮了。调整该widget的大小就是调整按钮的大小,我们可以任意调整按钮的布局的大小

右键widget,选择提升为,注意基类名要和switchbutton.h的基类名保持一致。点击右边的添加,就会出现图片上方这个样子。选中后,右下角点击提升

- qt designer右方可以看到widget变成了switchbutton类,也就是说这个widget就是switchbutton类的一个对象。我们可以通过控件名直接使用类中的变量和方法

- 通过信号和槽来获取按钮的值,原博主设置了statusChanged信号和updateValue()槽,很方便的获取和设置按钮的值
connect(ui->widget, &switchbutton::statusChanged, this, &Widget::switchButton_Status);

码字不易,如果这篇博客对你有帮助,麻烦点赞收藏,非常感谢!有不对的地方
边栏推荐
- mysql join技巧
- 论文神器 VS Code + LaTex + LaTex Workshop
- RS232 RS485 RS422 communication learning and notes
- A NOVEL DEEP PARALLEL TIME-SERIES RELATION NETWORK FOR FAULT DIAGNOSIS
- 测量电脑电池容量
- Detailed explanation of word mail merge function: after merging, multiple word documents are generated and blank pages are deleted
- Detailed explanation of creepage distance and electrical clearance
- ICC2使用report_placement检查floorplan
- Pycharm2019设置编辑器主题和默认代码
- MySQL delete tables without deleting databases
猜你喜欢

【服务器使用记录】通过跳板机登录远程服务器并进行文件传输

MySQL join skills

clickhouse聚合之探索聚合内部机制

多个ics日历合并成单个ics日历

Install visual studio 2019 steps and vs2019 offline installation package on win7

Cronbach’s α?KMO系数?因子载荷?史上最易懂的问卷信效度分析教程!!!(SPSS和AMOS)

qt设置加载界面的几种方法

vi和vim命令

Matlab simulation of radar imaging 4 - range resolution analysis

CLIP Learning Transferable Visual Models From Natural Language Supervision
随机推荐
听说你也在实习|当我采访了几个大三实习生之后。
Selection of PLC
ICC2(一)Preparing the Design
Exploration of Clickhouse aggregation internal mechanism of aggregation
t-SNE降维可视化
VI and VIM commands
USB network native driver for esxi updated to support esxi7.0 Update 2
雷达成像 Matlab 仿真 3 —— 多目标检测
Mae mask self encoding is scalable learning
PT physical aware based on multi voltage
An example of bill printing
Beta distribution (probability of probability)
set_case_analysis
Example of frameset usage
Vs code basic configuration and beautification
Monitor the CPU temperature of raspberry pie 4B installed with esxi on ARM
Learning notes on hardware circuit design 2 -- step-down power circuit
MySQL delete tables without deleting databases
PyTorch 学习笔记
PyTorch 学习笔记 1 —— Quick Start