Qt implement a custom slide button

  Next record today, using Qt existing components, to achieve the effect with a sliding button. I think it was done before a similar, but in the event there paintEvent strokes with a painting, I do, lazy, on the use of ready-made components to implement it, look at the following effects:

  

  This is the use of custom classes inherit QWidget, which together with a QLabel, to achieve the above effect. By the way, you can save yourself doing after assembly down to facilitate future projects in use.

Ado, directly on the core code, never played, to come and experience it in the manual.

  Here is the header file:

#ifndef CUSTOMBUTTON_H
#define CUSTOMBUTTON_H

#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QMouseEvent>
#include <QStyleOption>
#include <QPainter>

class CustomButton : public QWidget
{
    Q_OBJECT
public:
    explicit CustomButton(QWidget *parent = nullptr,int width=50, int height=20);

private:
    QLabel* myLabel;
    QTimer timer;
    int m_width;
     int m_height;
     int dir;
     int position;
     int max;
     int min;
     int length;
 protected :
     void paintEvent (QPaintEvent * Event ) the override ; // this must be rewritten, otherwise, the style sheet loaded invalid. 
    void mousePressEvent (QMouseEvent * Event ) the override ;
 public slots:
     void move_slot (); // timer timeout grooves function to achieve the effect of the sliding button 
public :
     void the init (); 
};

#endif // CUSTOMBUTTON_H

 

  Here is the cpp file:

#include "CustomButton.h"

/*** 我的是MSVC的编译器,必须要这段代码,不然中文就是乱码。如果Mingw编译器可以忽略。
#if _MSC_VER >=1800
#pragma execution_character_set("utf-8")
#endif
********/
CustomButton::CustomButton(QWidget *parent,int width, int height) : QWidget(parent),m_width(width),m_height(height),position(0)
{
    max = qMax(m_width,m_height);
    min = m_width>m_height?m_height:m_width;
    length = max - min;
    dir = m_width>=m_height? Qt::AlignLeft : Qt::AlignTop;
    connect(&timer,SIGNAL(timeout()),this,SLOT(move_slot()));
    init();
}

void CustomButton::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QStyleOption opt;
    opt.init(this);
    QPainter painter(this);
    style()->drawPrimitive(QStyle::PE_Widget,&opt,&painter,this);

}

void CustomButton::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        switch (dir)
        {
        case Qt::AlignLeft: case Qt::AlignRight:
            position = myLabel->pos().x();
            timer.start(5);
            break;

        case Qt::AlignTop: case Qt::AlignBottom:
            position = myLabel->pos().y();
            timer.start(5);
            break;
        }
    }
    QWidget::mousePressEvent(event);
}

void CustomButton::move_slot()
{
    switch(dir)
    {
    case Qt::AlignLeft:
        if(position>length)
        {
            timer.stop();
            this->setStyleSheet(QString("CustomButton{background-color:red;border-radius:%1px;}").arg(min/2));
            myLabel->setText("");
            myLabel->setStyleSheet(QString("#myLabel{background-color: /*lightgrey*/rgb(144,236,144);border-radius:%1px}").arg(min/2));
            dir = Qt::AlignRight;
            return;
        }
        ++position;
        myLabel->move(position,0);
        break;

    case Qt::AlignRight:
        if(position<=0)
        {
            timer.stop();
            this->setStyleSheet(QString("CustomButton{background-color:rgb(144,236,144);border-radius:%1px;}").arg(min/2));
            myLabel->setStyleSheet(QString("#myLabel{background-color:red;border-radius:%1px;}").arg(min/2));
            myLabel->setText("");
            dir = Qt::AlignLeft;
            return;
        }
        --position;
        myLabel->move(position,0);
        break;

    case Qt::AlignTop:
        if(position>length)
        {
            timer.stop();
            this->setStyleSheet(QString("CustomButton{background-color:red;border-radius:%1px;}").arg(min/2));
            myLabel->setText("");
            myLabel->setStyleSheet(QString("#myLabel{background-color: /*lightgrey*/rgb(144,236,144);border-radius:%1px}").arg(min/2));
            dir = Qt::AlignBottom;
            return;
        }
        ++position;
        myLabel->move(0,position);
        break;

    case Qt::AlignBottom:
        if(position<=0)
        {
            timer.stop();
            this->setStyleSheet(QString("CustomButton{background-color:rgb(144,236,144);border-radius:%1px;}").arg(min/2));
            myLabel->setStyleSheet(QString("#myLabel{background-color:red;border-radius:%1px;}").arg(min/2));
            myLabel->setText("");
            dir = Qt::AlignTop;
            return;
        }
        --position;
        myLabel->move(0,position);
        break;
    }

}

void CustomButton::init()
{
    this->resize(m_width,m_height);
    QString leftBtn_style = QString("CustomButton{background-color:rgb(144,236,144);border-radius:%1px;}").arg(min/2);
    this->setStyleSheet(leftBtn_style);
    myLabel = new QLabel(this);
    myLabel->setObjectName("myLabel");
    myLabel->resize(min,min);
    myLabel->setText("");
    myLabel->setAlignment(Qt::AlignCenter);
    QString lab_style = QString("#myLabel{background-color: red;border-radius:%1px}").arg(min/2);
    myLabel->setStyleSheet(lab_style);
    this->setFixedSize(m_width,m_height);
}

 

最后呢,在主函数调用下,并new一个我们写好的类的实例,来展示效果吧。

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
   btn1 = new CustomButton(this,58,22);
   btn2 = new CustomButton(this,60,20);
   btn3 = new CustomButton(this,18,50);
   btn4 = new CustomButton(this,50,22);
   label1 = new QLabel("客厅开关:");
   label2 = new QLabel("卧室开关:");
   label3 = new QLabel("水泵开关:");
   label4 = new QLabel("总闸开关:");
   form = new QFormLayout(this); //这里是表单布局
   form->addRow(label1,btn1);
   form->addRow(label2,btn2);
   form->addRow(label3,btn3);
   form->addRow(label4,btn4);
   setStyleSheet("QWidget{background-color:rgb(124,134,146);}.QLabel{background-color:lightgrey;border-radius:3px;}");
   resize(sizeHint());
}

  上面的代码,实现的功能如下:

  1. 可以自定义组件的大小,实例化时可以不指定大小,因为有默认的参数。

  2. 如果宽度小于高度,就会实现上下滑动,否则就是左右滑动。

  目前就是这些功能,当然还可以添加自定义颜色呀之类的,那么只要在源码里添加相关的接口供外部调用就行了。

 

Guess you like

Origin www.cnblogs.com/dz-study/p/12466969.html