Qt实现自定义控件的两种方式之提升法

一:提升Qt设计师界面类

第一步:添加新文件选择Qt设计师界面类

第二步:选择界面模板

看自己需求,一般不需要怎么更改

第三步:为设计师界面类起一个类名

类名不能全是小写,要不然后面会出错

此时可以添加一些图片资源到项目中,即添加Qt资源文件(图片名字起反了,不改了)

第四步:在设计师界面类ImageSwitch添加一个label

设置label大小,删除label的内容,并更改控件名

第五步:右键label,添加样式表,添加图片资源

点击<resouce root>,选择openSwitch.png(图片名字起反了,不改了),点击ok

操作完可得到

第六步:重写ImageSwitch类的mousePressEvent事件,实现鼠标点击显示动态开关的效果

ImageSwitch.h

#ifndef IMAGESWITCH_H
#define IMAGESWITCH_H

#include <QWidget>
#include <QMouseEvent>
namespace Ui {
class ImageSwitch;
}

class ImageSwitch : public QWidget
{
    Q_OBJECT

public:
    explicit ImageSwitch(QWidget *parent = nullptr);
    ~ImageSwitch();
    void mousePressEvent(QMouseEvent* event) override;

private:
    Ui::ImageSwitch *ui;
    bool m_switchIsOpen;
};

#endif // IMAGESWITCH_H

ImageSwitch.cpp

#include "imageswitch.h"
#include "ui_imageswitch.h"

ImageSwitch::ImageSwitch(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ImageSwitch)
{
    ui->setupUi(this);
    //初始按钮没有被选中
    m_switchIsOpen = false;
}

ImageSwitch::~ImageSwitch()
{
    delete ui;
}

void ImageSwitch::mousePressEvent(QMouseEvent *event)
{

    if(m_switchIsOpen)
    {
        m_switchIsOpen = !m_switchIsOpen;
        ui->lbSwitch->setStyleSheet("image: url(:/openSwitch.png);");
    }
    else
    {
        m_switchIsOpen = !m_switchIsOpen;
        ui->lbSwitch->setStyleSheet("image: url(:/closeSwitch.png);");
    }

}

第七步:在项目的ui界面中添加widget控件

右键选择提升到

填写类名时,注意大小写是有区别的,点击添加

选择添加的提升类,点击提升

第八步:编译项目,然后运行

二:提升C++类(没有界面)

这种就是纯在.h和.cpp文件中来创建控件,一般就是重写paintEvent,在paintEvent中使用QPainter和图片资源来进行控件的创建

第一步:新建C++类

名字啥的还是一样不能全小写,继承啥的看自己需求,这里我选的widget

第二步:编写控件代码

Loading.h

#ifndef LOADING_H
#define LOADING_H

#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QMap>

struct Location
{
public:
    explicit Location(float _x,float _y){x=_x;y=_y;}
    float x;
    float y;
};

class Loading : public QWidget
{
    Q_OBJECT
public:
    explicit Loading(QWidget *parent = nullptr);
    //设置圆点个数
    void setDotCount(int);
    //设置点颜色
    void setDotColor(const QColor&);
    //开始
    void start();
    //设置圆点最大直径
    void setMaxDiameter(float);
    //设置圆点最小直径
    void setMinDiameter(float);
    //计算
    void caculate();
protected:
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
signals:

private slots:
    void refresh();

private:
    //刷新计数
    int _index;
    //点的颜色
    QColor _dotColor;
    //点的个数
    int _count;
    //圆点最小直径
    float _minDiameter;
    //圆点最大直径
    float _maxDiameter;
    //绘制圆点
    void paintDot(QPainter &);
    //计数
    int _i;
    //时间间隔 单位:毫秒(ms)
    int _interval;
    //定时器
    QTimer* timer;
    //绘制区域边长
    float _squareWidth;
    //圆的直径
    float _centerDistance;
    //直径列表
    QList<float> radiiList;
    //圆点坐标列表
    QList<Location> locationList;

};

#endif // LOADING_H

Loading.cpp

#include "Loading.h"
#include <QDebug>
#include <qmath.h>
Loading::Loading(QWidget *parent) : QWidget(parent),_i(0),_interval(50),_index(0)
{
    //设置背景透明
    //this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
    //this->setAttribute(Qt::WA_TranslucentBackground, true);

    setDotColor(QColor(49, 177, 190));
    setDotCount(20);
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&Loading::refresh);
    setMaxDiameter(30);
    setMinDiameter(5);
}

//********************************************** 设置部分 *************************************
//设置点的个数
void Loading::setDotCount(int count)
{
    _count=count;
}

//设置点的颜色
void Loading::setDotColor(const QColor & color)
{
    _dotColor=color;
}

//开始动画
void Loading::start()
{
    timer->setInterval(_interval);
    timer->start();
}

//设置最大直径
void Loading::setMaxDiameter(float max)
{
    _maxDiameter=max;
}

//设置最小直径
void Loading::setMinDiameter(float min)
{
    _minDiameter=min;
}
//********************************************** 绘制部分 *************************************
//刷新界面
void Loading::refresh()
{
    repaint();
}

void Loading::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)
    caculate();
}

void Loading::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    painter.setPen(_dotColor);
    painter.setBrush(_dotColor);

    //绘制点
    paintDot(painter);
}

//计算绘制正方形区域
void Loading::caculate()
{
    _squareWidth=qMin(this->width(),this->height());
    float half=_squareWidth/2;
    _centerDistance=half-_maxDiameter/2-1;

    float gap=(_maxDiameter-_minDiameter)/(_count-1)/2;
    float angleGap=(float)360/_count;

    locationList.clear();
    radiiList.clear();

    for(int i=0;i<_count;i++)
    {
        radiiList<<_maxDiameter/2-i*gap;
        float radian=qDegreesToRadians(-angleGap*i);
        locationList.append(Location(half+_centerDistance*qCos(radian),half-_centerDistance*qSin(radian)));
    }
}

//绘制圆点
void Loading::paintDot(QPainter& painter)
{
    for(int i=0;i<_count;i++)
    {
        painter.setPen(_dotColor);
        //半径
        float radii=radiiList.at((_index+_count-i)%_count);

        //绘制圆点
        painter.drawEllipse(QPointF(locationList.at(i).x,locationList.at(i).y),radii,radii);
        //绘制正方形
        //painter.drawRect(locationList.at(i).x,locationList.at(i).y,radii,radii);
    }
    _index++;
}

第三步:在项目的ui界面中添加widget控件

右键选择提升到

选择添加的提升类(这里我已经添加过),点击提升

第四步:编译项目,然后运行

参考

(一)Qt实现自定义控件的两种方式---提升法_qt自定义控件-CSDN博客

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中,如果你想在自定义类中操作主界面的控件和属性,可以使用以下两种方式: 1. 通过指针访问主界面控件和属性 在主界面类中,你可以将需要在自定义类中操作的控件或属性设置为公共的,然后在自定义类中通过指向主界面对象的指针来访问它们。 例如,假设你有一个主界面类`MyMainWindow`,其中有一个名为`lineEdit`的文本框,你可以将其设置为公共的: ```cpp class MyMainWindow : public QMainWindow { public: QLineEdit *lineEdit; // ... }; ``` 然后,在自定义类中,你可以通过指向主界面对象的指针来访问`lineEdit`控件和它的属性: ```cpp class MyCustomClass { public: void doSomething(MyMainWindow *mainWindow) { QString text = mainWindow->lineEdit->text(); // ... } }; ``` 2. 通过信号和槽机制访问主界面控件和属性 在主界面类中,你可以定义一个信号,当需要在自定义类中操作控件或属性时,发射这个信号,并将需要操作的控件或属性传递给自定义类。在自定义类中,你可以连接这个信号到一个槽函数,以便在收到信号时进行相应的操作。 例如,在主界面类中,你可以定义一个名为`doSomethingSignal`的信号和一个名为`doSomething`的槽函数: ```cpp class MyMainWindow : public QMainWindow { Q_OBJECT signals: void doSomethingSignal(QLineEdit *lineEdit); public slots: void doSomething(QLineEdit *lineEdit) { QString text = lineEdit->text(); // ... } // ... }; ``` 然后,在自定义类中,你可以连接`doSomethingSignal`信号到`doSomething`槽函数,并在需要操作`lineEdit`控件时,发射这个信号并传递`lineEdit`控件: ```cpp class MyCustomClass { public: void doSomething(MyMainWindow *mainWindow) { connect(mainWindow, &MyMainWindow::doSomethingSignal, this, &MyCustomClass::handleDoSomething); emit mainWindow->doSomethingSignal(mainWindow->lineEdit); } public slots: void handleDoSomething(QLineEdit *lineEdit) { QString text = lineEdit->text(); // ... } }; ``` 这样,在自定义类中,当发射`doSomethingSignal`信号时,`handleDoSomething`槽函数就会被调用,并传递`lineEdit`控件,以完成相应的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值