找回密码
 立即注册
收起左侧

Qt编写自定义控件11-设备防区按钮控件

0
回复
443
查看
[复制链接]
累计签到:7 天
连续签到:1 天
来源: 2019-4-28 23:31:22 显示全部楼层 |阅读模式
前言
在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指示,例如布防、撤防、旁路、报警、离线、在线等状态,可以作为一个通用的设备按钮对象使用。

实现的功能
* 1:可设置防区样式  圆形、JC、气泡、气泡2、消息、消息2
* 2:可设置防区状态  布防、撤防、报警、旁路、故障
* 3:可设置报警切换
* 4:可设置显示的防区号
* 5:可设置是否可鼠标拖动

效果图



头文件代码
  1. #ifndef BUTTONDEFENCE_H
  2. #define BUTTONDEFENCE_H

  3. /**
  4. * 防区按钮控件 作者:feiyangqingyun(QQ:517216493) 2018-7-2
  5. * 1:可设置防区样式  圆形、JC、气泡、气泡2、消息、消息2
  6. * 2:可设置防区状态  布防、撤防、报警、旁路、故障
  7. * 3:可设置报警切换
  8. * 4:可设置显示的防区号
  9. * 5:可设置是否可鼠标拖动
  10. */

  11. #include <QWidget>

  12. #ifdef quc
  13. #if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
  14. #include <QtDesigner/QDesignerExportWidget>
  15. #else
  16. #include <QtUiPlugin/QDesignerExportWidget>
  17. #endif

  18. class QDESIGNER_WIDGET_EXPORT ButtonDefence : public QWidget
  19. #else
  20. class ButtonDefence : public QWidget
  21. #endif

  22. {
  23.     Q_OBJECT
  24.     Q_ENUMS(ButtonStyle)
  25.     Q_ENUMS(ButtonStatus)

  26.     Q_PROPERTY(bool canMove READ getCanMove WRITE setCanMove)
  27.     Q_PROPERTY(QString text READ getText WRITE setText)

  28.     Q_PROPERTY(ButtonStyle buttonStyle READ getButtonStyle WRITE setButtonStyle)
  29.     Q_PROPERTY(ButtonStatus buttonStatus READ getButtonStatus WRITE setButtonStatus)

  30. public:
  31.     //防区样式  圆形、JC、气泡、气泡2、消息、消息2
  32.     enum ButtonStyle {
  33.         ButtonStyle_Circle = 0,
  34.         ButtonStyle_Police = 1,
  35.         ButtonStyle_Bubble = 2,
  36.         ButtonStyle_Bubble2 = 3,
  37.         ButtonStyle_Msg = 4,
  38.         ButtonStyle_Msg2 = 5
  39.     };

  40.     //防区状态  布防、撤防、报警、旁路、故障
  41.     enum ButtonStatus {
  42.         ButtonStatus_Arming = 0,
  43.         ButtonStatus_Disarming = 1,
  44.         ButtonStatus_Alarm = 2,
  45.         ButtonStatus_Bypass = 3,
  46.         ButtonStatus_Error = 4
  47.     };

  48.     explicit ButtonDefence(QWidget *parent = 0);
  49.     ~ButtonDefence();

  50. protected:
  51.     void paintEvent(QPaintEvent *);
  52.     bool eventFilter(QObject *watched, QEvent *event);

  53. private:
  54.     bool canMove;                   //是否可移动
  55.     QString text;                   //显示文字
  56.     ButtonStyle buttonStyle;        //防区样式
  57.     ButtonStatus buttonStatus;      //防区状态

  58.     QString type;                   //图片末尾类型
  59.     QString imgName;                //背景图片名称
  60.     bool isDark;                    //是否加深报警
  61.     QTimer *timer;                  //报警闪烁定时器

  62. private slots:
  63.     void checkAlarm();

  64. public:
  65.     bool getCanMove()               const;
  66.     QString getText()               const;

  67.     ButtonStyle getButtonStyle()    const;
  68.     ButtonStatus getButtonStatus()  const;

  69.     QSize sizeHint()                const;
  70.     QSize minimumSizeHint()         const;

  71. public slots:
  72.     //设置可移动
  73.     void setCanMove(bool canMove);
  74.     //设置显示文字
  75.     void setText(const QString &text);
  76.     //设置防区样式
  77.     void setButtonStyle(const ButtonStyle &buttonStyle);
  78.     //设置防区状态
  79.     void setButtonStatus(const ButtonStatus &buttonStatus);

  80. };

  81. #endif //BUTTONDEFENCE_H
复制代码


完整源码
  1. #pragma execution_character_set("utf-8")

  2. #include "buttondefence.h"
  3. #include "qpainter.h"
  4. #include "qevent.h"
  5. #include "qtimer.h"
  6. #include "qdebug.h"

  7. ButtonDefence::ButtonDefence(QWidget *parent) : QWidget(parent)
  8. {
  9.     canMove = false;
  10.     text = "1";
  11.     buttonStyle = ButtonStyle_Police;
  12.     buttonStatus = ButtonStatus_Arming;

  13.     type = "police";
  14.     imgName = QString(":/image/btn_defence_disarming_%1.png").arg(type);
  15.     isDark = false;

  16.     timer = new QTimer(this);
  17.     timer->setInterval(500);
  18.     connect(timer, SIGNAL(timeout()), this, SLOT(checkAlarm()));

  19.     this->installEventFilter(this);
  20. }

  21. ButtonDefence::~ButtonDefence()
  22. {
  23.     if (timer->isActive()) {
  24.         timer->stop();
  25.     }
  26. }

  27. void ButtonDefence::paintEvent(QPaintEvent *)
  28. {
  29.     double width = this->width();
  30.     double height = this->height();
  31.     double side = qMin(width, height);

  32.     QPainter painter(this);
  33.     painter.setRenderHint(QPainter::Antialiasing);

  34.     //绘制背景图
  35.     QImage img(imgName);
  36.     if (!img.isNull()) {
  37.         img = img.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);

  38.         //按照比例自动居中绘制
  39.         int pixX = rect().center().x() - img.width() / 2;
  40.         int pixY = rect().center().y() - img.height() / 2;
  41.         QPoint point(pixX, pixY);
  42.         painter.drawImage(point, img);
  43.     }

  44.     //计算字体
  45.     QFont font;
  46.     font.setPixelSize(side * 0.37);
  47.     font.setBold(true);

  48.     //自动计算文字绘制区域,绘制防区号
  49.     QRectF rect = this->rect();
  50.     if (buttonStyle == ButtonStyle_Police) {
  51.         double y = (30 * height / 60);
  52.         rect = QRectF(0, y, width, height - y);
  53.     } else if (buttonStyle == ButtonStyle_Bubble) {
  54.         double y = (8 * height / 60);
  55.         rect = QRectF(0, 0, width, height - y);
  56.     } else if (buttonStyle == ButtonStyle_Bubble2) {
  57.         double y = (13 * height / 60);
  58.         rect = QRectF(0, 0, width, height - y);
  59.         font.setPixelSize(width * 0.33);
  60.     } else if (buttonStyle == ButtonStyle_Msg) {
  61.         double y = (17 * height / 60);
  62.         rect = QRectF(0, 0, width, height - y);
  63.     } else if (buttonStyle == ButtonStyle_Msg2) {
  64.         double y = (17 * height / 60);
  65.         rect = QRectF(0, 0, width, height - y);
  66.     }

  67.     //绘制文字标识
  68.     painter.setFont(font);
  69.     painter.setPen(Qt::white);
  70.     painter.drawText(rect, Qt::AlignCenter, text);
  71. }

  72. bool ButtonDefence::eventFilter(QObject *watched, QEvent *event)
  73. {
  74.     if (canMove) {
  75.         static QPoint lastPoint;
  76.         static bool isPressed = false;

  77.         if (event->type() == QEvent::MouseButtonPress) {
  78.             QMouseEvent *e = static_cast<QMouseEvent *>(event);
  79.             if (this->rect().contains(e->pos()) && (e->button() == Qt::LeftButton)) {
  80.                 lastPoint = e->pos();
  81.                 isPressed = true;
  82.             }
  83.         } else if (event->type() == QEvent::MouseMove && isPressed) {
  84.             QMouseEvent *e = static_cast<QMouseEvent *>(event);
  85.             int dx = e->pos().x() - lastPoint.x();
  86.             int dy = e->pos().y() - lastPoint.y();
  87.             this->move(this->x() + dx, this->y() + dy);
  88.             return true;
  89.         } else if (event->type() == QEvent::MouseButtonRelease && isPressed) {
  90.             isPressed = false;
  91.         }
  92.     }

  93.     return QWidget::eventFilter(watched, event);
  94. }

  95. bool ButtonDefence::getCanMove() const
  96. {
  97.     return this->canMove;
  98. }

  99. QString ButtonDefence::getText() const
  100. {
  101.     return this->text;
  102. }

  103. ButtonDefence::ButtonStyle ButtonDefence::getButtonStyle() const
  104. {
  105.     return this->buttonStyle;
  106. }

  107. ButtonDefence::ButtonStatus ButtonDefence::getButtonStatus() const
  108. {
  109.     return this->buttonStatus;
  110. }

  111. QSize ButtonDefence::sizeHint() const
  112. {
  113.     return QSize(50, 50);
  114. }

  115. QSize ButtonDefence::minimumSizeHint() const
  116. {
  117.     return QSize(10, 10);
  118. }

  119. void ButtonDefence::checkAlarm()
  120. {
  121.     if (isDark) {
  122.         imgName = QString(":/image/btn_defence_error_%1.png").arg(type);
  123.     } else {
  124.         imgName = QString(":/image/btn_defence_alarm_%1.png").arg(type);
  125.     }

  126.     isDark = !isDark;
  127.     update();
  128. }

  129. void ButtonDefence::setCanMove(bool canMove)
  130. {
  131.     this->canMove = canMove;
  132. }

  133. void ButtonDefence::setText(const QString &text)
  134. {
  135.     if (this->text != text) {
  136.         this->text = text;
  137.         update();
  138.     }
  139. }

  140. void ButtonDefence::setButtonStyle(const ButtonDefence::ButtonStyle &buttonStyle)
  141. {
  142.     this->buttonStyle = buttonStyle;
  143.     if (buttonStyle == ButtonStyle_Circle) {
  144.         type = "circle";
  145.     } else if (buttonStyle == ButtonStyle_Police) {
  146.         type = "police";
  147.     } else if (buttonStyle == ButtonStyle_Bubble) {
  148.         type = "bubble";
  149.     } else if (buttonStyle == ButtonStyle_Bubble2) {
  150.         type = "bubble2";
  151.     } else if (buttonStyle == ButtonStyle_Msg) {
  152.         type = "msg";
  153.     } else if (buttonStyle == ButtonStyle_Msg2) {
  154.         type = "msg2";
  155.     } else {
  156.         type = "circle";
  157.     }

  158.     setButtonStatus(buttonStatus);
  159. }

  160. void ButtonDefence::setButtonStatus(const ButtonDefence::ButtonStatus &buttonStatus)
  161. {
  162.     this->buttonStatus = buttonStatus;
  163.     isDark = false;
  164.     if (timer->isActive()) {
  165.         timer->stop();
  166.     }

  167.     if (buttonStatus == ButtonStatus_Arming) {
  168.         imgName = QString(":/image/btn_defence_arming_%1.png").arg(type);
  169.     } else if (buttonStatus == ButtonStatus_Disarming) {
  170.         imgName = QString(":/image/btn_defence_disarming_%1.png").arg(type);
  171.     } else if (buttonStatus == ButtonStatus_Bypass) {
  172.         imgName = QString(":/image/btn_defence_bypass_%1.png").arg(type);
  173.     } else if (buttonStatus == ButtonStatus_Error) {
  174.         imgName = QString(":/image/btn_defence_error_%1.png").arg(type);
  175.     } else if (buttonStatus == ButtonStatus_Alarm) {
  176.         checkAlarm();
  177.         if (!timer->isActive()) {
  178.             timer->start();
  179.         }
  180.     }

  181.     update();
  182. }
复制代码


控件介绍


1. 超过140个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,不乱码,可直接集成到Qt  Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
6. 每个控件默认配色和demo对应的配色都非常精美。
7. 超过120个可见控件,6个不可见控件。
8. 部分控件提供多种样式风格选择,多种指示器样式选择。
9. 所有控件自适应窗体拉伸变化。
10.  集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
13. 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。
SDK下载
- SDK下载链接:https://pan.baidu.com/s/1tD9v1YPfE2fgYoK6lqUr1Q 提取码:lyhk
- 自定义控件+属性设计器欣赏:https://pan.baidu.com/s/1l6L3rKSiLu_uYi7lnL3ibQ 提取码:tmvl
- 下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo。
- 自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。
- 目前已提供22个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
- 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
- widget版本(QQ:517216493)qml版本(QQ:373955953)三峰驼(QQ:278969898)。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册