1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Qt之自定义控件(滑动开关按钮)+源码

Qt之自定义控件(滑动开关按钮)+源码

时间:2023-03-16 00:09:37

相关推荐

Qt之自定义控件(滑动开关按钮)+源码

Qt之自定义控件(滑动开关按钮)

目录

Qt之自定义控件(滑动开关按钮)说明主要实现实现源码一实现源码二

说明

本文主要介绍QT的两种滑动开关按钮的实现,附上源码记录以备二次开发

源码附基本注释

滑动开关效果:

主要实现

重写鼠标按下事件(mousePressEvent)、释放事件(mouseReleaseEvent),用于切换开关状态。

重写绘制事件(paintEvent),用于绘制开关效果。

使用QTimer,定时刷新,让开关切换时产生动画效果。

实现源码一

(作者是老张同学)

mybutton.h

#ifndef MYBUTTON_H#define MYBUTTON_H#include <QWidget>class myButton : public QWidget{Q_OBJECTpublic:explicit myButton(QWidget *parent = 0);void mouseReleaseEvent(QMouseEvent *); //鼠标抬起时间int ii; // 开关标记:开为1,关为0int jj; //初始化标记protected:void paintEvent(QPaintEvent *event); //绘画事件,初始化一次,update()更新signals:void buttonChange();//信号,按钮改变发出信号public slots:};#endif // MYBUTTON_H

mybutton.cpp

#include "mybutton.h"#include <QPainter>myButton::myButton(QWidget *parent) :QWidget(parent){resize(50,35);ii=0;//按钮默认关闭jj=0;//jj=1初始化阶段//update();}//绘制按钮的函数void myButton::paintEvent(QPaintEvent *){QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);if(jj==0){// 初始化,绘制初始化状态按钮painter.setPen(Qt::NoPen);if(ii==0){painter.setBrush(Qt::gray);}else if(ii==1){painter.setBrush(Qt::green);}QRectF re(1,1,20,20);int startAngle = 90*16;int endAngel = 180*16;painter.drawPie(re,startAngle,endAngel);painter.drawRect(11,1,10,20);QRectF re2(11,1,20,20);int startAngle2 = -90*16;int endAngel2 = 180*16;painter.drawPie(re2,startAngle2,endAngel2);if(ii==0){// 关闭状态painter.setBrush(Qt::yellow);painter.drawEllipse(2,2,18,18);}else if(ii==1){// 打开状态painter.setBrush(Qt::yellow);painter.drawEllipse(12,2,18,18);}jj=1;}else{//绘制状态改变后的按钮painter.setPen(Qt::NoPen);if(ii==1){painter.setBrush(Qt::gray);}else if(ii==0){painter.setBrush(Qt::green);}QRectF re(1,1,20,20);//点int startAngle = 90*16;int endAngel = 180*16;painter.drawPie(re,startAngle,endAngel);painter.drawRect(11,1,10,20);QRectF re2(11,1,20,20);int startAngle2 = -90*16;int endAngel2 = 180*16;painter.drawPie(re2,startAngle2,endAngel2);if(ii==0){// 打开painter.setBrush(Qt::yellow);painter.drawEllipse(12,2,18,18);ii=1;}else if(ii==1){// 关闭painter.setBrush(Qt::yellow);painter.drawEllipse(2,2,18,18);ii=0;}emit buttonChange();//发出信号}}//鼠标抬起事件,调用update,重新绘制按钮void myButton::mouseReleaseEvent(QMouseEvent *){update();}

zzz.h(主窗口头文件)

#ifndef ZZZ_H#define ZZZ_H#include "mybutton.h"#include <QWidget>#include <QMainWindow>#include <QtGui>namespace Ui {class zzz;}class zzz : public QWidget{Q_OBJECTpublic:explicit zzz(QWidget *parent = 0);~zzz();myButton *btn1;myButton *btn2;myButton *btn3;QLabel *la;public slots:void textChange();private:Ui::zzz *ui;};#endif // ZZZ_H

zzz.cpp(主窗口头文件)

#include "zzz.h"#include "ui_zzz.h"#include <QtGui>#include <QPushButton>#include <QVBoxLayout>#include <QWidget>#include <QLabel>zzz::zzz(QWidget *parent) :QWidget(parent),ui(new Ui::zzz){QVBoxLayout *layout = new QVBoxLayout();btn1 = new myButton;QGroupBox *gb1 = new QGroupBox(tr("switch1"));QHBoxLayout *l1 = new QHBoxLayout();l1->addWidget(btn1);gb1->setLayout(l1);btn2 = new myButton;QGroupBox *gb2 = new QGroupBox(tr("switch2"));QHBoxLayout *l2 = new QHBoxLayout();l2->addWidget(btn2);gb2->setLayout(l2);btn3 = new myButton;QGroupBox *gb3 = new QGroupBox(tr("switch3"));QHBoxLayout *l3 = new QHBoxLayout();l3->addWidget(btn3);gb3->setLayout(l3);layout->addWidget(gb1);layout->addWidget(gb2);layout->addWidget(gb3);QString str = QString(tr(""));if(btn1->ii==0){str.append("1:off;");}else{str.append("1:on");}if(btn2->ii==0){str.append("2:off;");}else{str.append("2:on");}if(btn3->ii==0){str.append("3:off.");}else{str.append("3:on.");}la = new QLabel(str);layout->addWidget(la);setLayout(layout);connect(btn1,SIGNAL(buttonChange()),this,SLOT(textChange()));connect(btn2,SIGNAL(buttonChange()),this,SLOT(textChange()));connect(btn3,SIGNAL(buttonChange()),this,SLOT(textChange()));resize(200,300);}void zzz::textChange(){QString str = QString(tr(""));if(btn1->ii==0){str.append("1:off;\t");}else{str.append("1:on;\t");}if(btn2->ii==0){str.append("2:off;\t");}else{str.append("2:on;\t");}if(btn3->ii==0){str.append("3:off.");}else{str.append("3:on.");}la->setText(str);}zzz::~zzz(){delete ui;}

main.cpp默认的就行

实现源码二

主要参考自:/weixin_34348805/article/details/90524983(感谢作者)

SwitchControl.h

#ifndef SWITCH_CONTROL#define SWITCH_CONTROL#include <QWidget>#include <QTimer>class SwitchControl : public QWidget{Q_OBJECTpublic:explicit SwitchControl(QWidget *parent = 0);// 返回开关状态 - 打开:true 关闭:falsebool isToggled() const;// 设置开关状态void setToggle(bool checked);// 设置背景颜色void setBackgroundColor(QColor color);// 设置选中颜色void setCheckedColor(QColor color);// 设置不可用颜色void setDisbaledColor(QColor color);protected:// 绘制开关void paintEvent(QPaintEvent *event);// 鼠标按下事件void mousePressEvent(QMouseEvent *event);// 鼠标释放事件 - 切换开关状态、发射toggled()信号void mouseReleaseEvent(QMouseEvent *event);// 大小改变事件void resizeEvent(QResizeEvent *event);// 缺省大小QSize sizeHint();QSize minimumSizeHint();signals:// 状态改变时,发射信号void toggled(bool checked);private slots:// 状态切换时,用于产生滑动效果void onTimeout();private:bool m_bChecked; // 是否选中QColor m_background;// 背景颜色QColor m_checkedColor; // 选中颜色QColor m_disabledColor; // 不可用颜色QColor m_thumbColor;// 拇指颜色qreal m_radius;// 圆角qreal m_nX; // x点坐标qreal m_nY; // y点坐标qint16 m_nHeight; // 高度qint16 m_nMargin; // 外边距QTimer m_timer;// 定时器};#endif // SWITCH_CONTROL

SwitchControl.cpp

#include <QPainter>#include <QMouseEvent>#include "SwitchControl.h"SwitchControl::SwitchControl(QWidget *parent): QWidget(parent),m_nHeight(16),m_bChecked(false),m_radius(8.0),m_nMargin(3),m_checkedColor(0, 150, 136),m_thumbColor(Qt::white),m_disabledColor(190, 190, 190),m_background(Qt::black){// 鼠标滑过光标形状 - 手型setCursor(Qt::PointingHandCursor);// 连接信号槽connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));}// 绘制开关void SwitchControl::paintEvent(QPaintEvent *event){Q_UNUSED(event);QPainter painter(this);painter.setPen(Qt::NoPen);painter.setRenderHint(QPainter::Antialiasing);QPainterPath path;QColor background;QColor thumbColor;qreal dOpacity;if (isEnabled()) {// 可用状态if (m_bChecked) {// 打开状态background = m_checkedColor;thumbColor = m_checkedColor;dOpacity = 0.600;} else {//关闭状态background = m_background;thumbColor = m_thumbColor;dOpacity = 0.800;}} else {// 不可用状态background = m_background;dOpacity = 0.260;thumbColor = m_disabledColor;}// 绘制大椭圆painter.setBrush(background);painter.setOpacity(dOpacity);path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius);painter.drawPath(path.simplified());// 绘制小椭圆painter.setBrush(thumbColor);painter.setOpacity(1.0);painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height()));}// 鼠标按下事件void SwitchControl::mousePressEvent(QMouseEvent *event){if (isEnabled()) {if (event->buttons() & Qt::LeftButton) {event->accept();} else {event->ignore();}}}// 鼠标释放事件 - 切换开关状态、发射toggled()信号void SwitchControl::mouseReleaseEvent(QMouseEvent *event){if (isEnabled()) {if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) {event->accept();m_bChecked = !m_bChecked;emit toggled(m_bChecked);m_timer.start(2);} else {event->ignore();}}}// 大小改变事件void SwitchControl::resizeEvent(QResizeEvent *event){m_nX = m_nHeight / 2;m_nY = m_nHeight / 2;QWidget::resizeEvent(event);}// 默认大小QSize SwitchControl::sizeHint(){return minimumSizeHint();}// 最小大小QSize SwitchControl::minimumSizeHint(){return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin);}// 切换状态 - 滑动void SwitchControl::onTimeout(){if (m_bChecked) {m_nX += 1;if (m_nX >= width() - m_nHeight)m_timer.stop();} else {m_nX -= 1;if (m_nX <= m_nHeight / 2)m_timer.stop();}update();}// 返回开关状态 - 打开:true 关闭:falsebool SwitchControl::isToggled() const{return m_bChecked;}// 设置开关状态void SwitchControl::setToggle(bool checked){m_bChecked = checked;m_timer.start(10);}// 设置背景颜色void SwitchControl::setBackgroundColor(QColor color){m_background = color;}// 设置选中颜色void SwitchControl::setCheckedColor(QColor color){m_checkedColor = color;}// 设置不可用颜色void SwitchControl::setDisbaledColor(QColor color){m_disabledColor = color;}

MainWindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include<switchcontrol.h>#include<QtGui>#include <QMainWindow>namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();QLabel *label1;QLabel *label2;QLabel *label3;private:Ui::MainWindow *ui;public slots:void onToggled1(bool bChecked);void onToggled2(bool bChecked);void onToggled3(bool bChecked);};#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"#include<QDebug>#include <QtGui>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow){ui->setupUi(this);//SwitchControl *pSwitchControl = new SwitchControl(this);//SwitchControl *pGreenSwitchControl = new SwitchControl(this);//SwitchControl *pDisabledSwitchControl = new SwitchControl(this);// 设置状态、样式// pGreenSwitchControl->setToggle(true);// pGreenSwitchControl->setCheckedColor(QColor(0, 160, 230));// pDisabledSwitchControl->setDisabled(true);// pDisabledSwitchControl->setToggle(true);// 连接信号槽connect(pSwitchControl, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)));QVBoxLayout *layout = new QVBoxLayout();SwitchControl *btn1 = new SwitchControl(this);QGroupBox *gb1 = new QGroupBox(tr("LED1"));QHBoxLayout *l1 = new QHBoxLayout();label1 = new QLabel(tr("OFF"));l1->addWidget(label1);l1->addWidget(btn1);gb1->setLayout(l1);SwitchControl *btn2 = new SwitchControl(this);QGroupBox *gb2 = new QGroupBox(tr("LED2"));QHBoxLayout *l2 = new QHBoxLayout();label2 = new QLabel(tr("OFF"));l2->addWidget(label2);l2->addWidget(btn2);gb2->setLayout(l2);SwitchControl *btn3 = new SwitchControl(this);QGroupBox *gb3 = new QGroupBox(tr("LED3"));QHBoxLayout *l3 = new QHBoxLayout();label3 = new QLabel(tr("OFF"));l3->addWidget(label3);l3->addWidget(btn3);gb3->setLayout(l3);connect(btn1, SIGNAL(toggled(bool)), this, SLOT(onToggled1(bool)));connect(btn2, SIGNAL(toggled(bool)), this, SLOT(onToggled2(bool)));connect(btn3, SIGNAL(toggled(bool)), this, SLOT(onToggled3(bool)));layout->addWidget(gb1);layout->addWidget(gb2);layout->addWidget(gb3);QWidget *window = new QWidget;window->setLayout(layout);setWindowTitle(tr("bean"));setCentralWidget(window);}MainWindow::~MainWindow(){delete ui;}void MainWindow::onToggled1(bool bChecked){qDebug() << "State : " << bChecked;if(bChecked){label1->setText("ON");label1->setStyleSheet("color:red");}else{label1->setText("OFF");label1->setStyleSheet("color:black");}}void MainWindow::onToggled2(bool bChecked){qDebug() << "State : " << bChecked;if(bChecked){label2->setText("ON");label2->setStyleSheet("color:red");}else{label2->setText("OFF");label2->setStyleSheet("color:black");}}void MainWindow::onToggled3(bool bChecked){qDebug() << "State : " << bChecked;if(bChecked){label3->setText("ON");label3->setStyleSheet("color:red");}else{label3->setText("OFF");label3->setStyleSheet("color:black");}}

main.cpp默认

以上两个程序都有些小bug,总体上不影响使用,可以在此基础上修改

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。