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


    一:提升Qt设计师界面类

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

    第二步:选择界面模板

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

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

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

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

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

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

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

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

    操作完可得到

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

    ImageSwitch.h

    1. #ifndef IMAGESWITCH_H
    2. #define IMAGESWITCH_H
    3. #include
    4. #include
    5. namespace Ui {
    6. class ImageSwitch;
    7. }
    8. class ImageSwitch : public QWidget
    9. {
    10. Q_OBJECT
    11. public:
    12. explicit ImageSwitch(QWidget *parent = nullptr);
    13. ~ImageSwitch();
    14. void mousePressEvent(QMouseEvent* event) override;
    15. private:
    16. Ui::ImageSwitch *ui;
    17. bool m_switchIsOpen;
    18. };
    19. #endif // IMAGESWITCH_H

    ImageSwitch.cpp

    1. #include "imageswitch.h"
    2. #include "ui_imageswitch.h"
    3. ImageSwitch::ImageSwitch(QWidget *parent) :
    4. QWidget(parent),
    5. ui(new Ui::ImageSwitch)
    6. {
    7. ui->setupUi(this);
    8. //初始按钮没有被选中
    9. m_switchIsOpen = false;
    10. }
    11. ImageSwitch::~ImageSwitch()
    12. {
    13. delete ui;
    14. }
    15. void ImageSwitch::mousePressEvent(QMouseEvent *event)
    16. {
    17. if(m_switchIsOpen)
    18. {
    19. m_switchIsOpen = !m_switchIsOpen;
    20. ui->lbSwitch->setStyleSheet("image: url(:/openSwitch.png);");
    21. }
    22. else
    23. {
    24. m_switchIsOpen = !m_switchIsOpen;
    25. ui->lbSwitch->setStyleSheet("image: url(:/closeSwitch.png);");
    26. }
    27. }

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

    右键选择提升到

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

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

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

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

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

    第一步:新建C++类

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

    第二步:编写控件代码

    Loading.h

    1. #ifndef LOADING_H
    2. #define LOADING_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. struct Location
    8. {
    9. public:
    10. explicit Location(float _x,float _y){x=_x;y=_y;}
    11. float x;
    12. float y;
    13. };
    14. class Loading : public QWidget
    15. {
    16. Q_OBJECT
    17. public:
    18. explicit Loading(QWidget *parent = nullptr);
    19. //设置圆点个数
    20. void setDotCount(int);
    21. //设置点颜色
    22. void setDotColor(const QColor&);
    23. //开始
    24. void start();
    25. //设置圆点最大直径
    26. void setMaxDiameter(float);
    27. //设置圆点最小直径
    28. void setMinDiameter(float);
    29. //计算
    30. void caculate();
    31. protected:
    32. void paintEvent(QPaintEvent *event);
    33. void resizeEvent(QResizeEvent *event);
    34. signals:
    35. private slots:
    36. void refresh();
    37. private:
    38. //刷新计数
    39. int _index;
    40. //点的颜色
    41. QColor _dotColor;
    42. //点的个数
    43. int _count;
    44. //圆点最小直径
    45. float _minDiameter;
    46. //圆点最大直径
    47. float _maxDiameter;
    48. //绘制圆点
    49. void paintDot(QPainter &);
    50. //计数
    51. int _i;
    52. //时间间隔 单位:毫秒(ms)
    53. int _interval;
    54. //定时器
    55. QTimer* timer;
    56. //绘制区域边长
    57. float _squareWidth;
    58. //圆的直径
    59. float _centerDistance;
    60. //直径列表
    61. QList<float> radiiList;
    62. //圆点坐标列表
    63. QList locationList;
    64. };
    65. #endif // LOADING_H

    Loading.cpp

    1. #include "Loading.h"
    2. #include
    3. #include
    4. Loading::Loading(QWidget *parent) : QWidget(parent),_i(0),_interval(50),_index(0)
    5. {
    6. //设置背景透明
    7. //this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
    8. //this->setAttribute(Qt::WA_TranslucentBackground, true);
    9. setDotColor(QColor(49, 177, 190));
    10. setDotCount(20);
    11. timer = new QTimer(this);
    12. connect(timer,&QTimer::timeout,this,&Loading::refresh);
    13. setMaxDiameter(30);
    14. setMinDiameter(5);
    15. }
    16. //********************************************** 设置部分 *************************************
    17. //设置点的个数
    18. void Loading::setDotCount(int count)
    19. {
    20. _count=count;
    21. }
    22. //设置点的颜色
    23. void Loading::setDotColor(const QColor & color)
    24. {
    25. _dotColor=color;
    26. }
    27. //开始动画
    28. void Loading::start()
    29. {
    30. timer->setInterval(_interval);
    31. timer->start();
    32. }
    33. //设置最大直径
    34. void Loading::setMaxDiameter(float max)
    35. {
    36. _maxDiameter=max;
    37. }
    38. //设置最小直径
    39. void Loading::setMinDiameter(float min)
    40. {
    41. _minDiameter=min;
    42. }
    43. //********************************************** 绘制部分 *************************************
    44. //刷新界面
    45. void Loading::refresh()
    46. {
    47. repaint();
    48. }
    49. void Loading::resizeEvent(QResizeEvent *event)
    50. {
    51. Q_UNUSED(event)
    52. caculate();
    53. }
    54. void Loading::paintEvent(QPaintEvent *event)
    55. {
    56. Q_UNUSED(event)
    57. QPainter painter(this);
    58. painter.setRenderHint(QPainter::Antialiasing);
    59. painter.setPen(_dotColor);
    60. painter.setBrush(_dotColor);
    61. //绘制点
    62. paintDot(painter);
    63. }
    64. //计算绘制正方形区域
    65. void Loading::caculate()
    66. {
    67. _squareWidth=qMin(this->width(),this->height());
    68. float half=_squareWidth/2;
    69. _centerDistance=half-_maxDiameter/2-1;
    70. float gap=(_maxDiameter-_minDiameter)/(_count-1)/2;
    71. float angleGap=(float)360/_count;
    72. locationList.clear();
    73. radiiList.clear();
    74. for(int i=0;i<_count;i++)
    75. {
    76. radiiList<<_maxDiameter/2-i*gap;
    77. float radian=qDegreesToRadians(-angleGap*i);
    78. locationList.append(Location(half+_centerDistance*qCos(radian),half-_centerDistance*qSin(radian)));
    79. }
    80. }
    81. //绘制圆点
    82. void Loading::paintDot(QPainter& painter)
    83. {
    84. for(int i=0;i<_count;i++)
    85. {
    86. painter.setPen(_dotColor);
    87. //半径
    88. float radii=radiiList.at((_index+_count-i)%_count);
    89. //绘制圆点
    90. painter.drawEllipse(QPointF(locationList.at(i).x,locationList.at(i).y),radii,radii);
    91. //绘制正方形
    92. //painter.drawRect(locationList.at(i).x,locationList.at(i).y,radii,radii);
    93. }
    94. _index++;
    95. }

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

    右键选择提升到

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

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

    参考

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

  • 相关阅读:
    FSC商标门户网站重置密码操作指南
    力扣-448.找到所有数组中消失的数字
    Spring框架对redis的封装
    Python数据分析与机器学习20- 逻辑回归项目实战4-模型评估方法:混淆矩阵
    你有对象类,我有结构体,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang结构体(struct)的使用EP06
    开年!5 款令人惊艳的开源项目「GitHub 热点速览」
    Fastnet,三步完成高性能的网络开发
    vue3 - Vue 项目处理GitHub Pages 部署后 _plugin-vue_export-helper.js 404
    Apache Dubbo 多语言体系再添新员:首个 Rust 语言版本正式发布
    基于java网上书城系统的设计与实现
  • 原文地址:https://blog.csdn.net/m0_71489826/article/details/141001793