Qt编写自定义控件5 您所在的位置:网站首页 制作精美的温度计表 Qt编写自定义控件5

Qt编写自定义控件5

2024-04-23 10:21| 来源: 网络整理| 查看: 265

一、前言

柱状温度计控件,可能是很多人练手控件之一,基本上都是垂直方向展示,底部一个水银柱,中间刻度尺,刻度尺可以在左侧右侧或者两侧都有,自适应分辨率改动,有时候为了美观效果,可能还会整个定时器来实现动画效果,开启动画效果的缺点就是CPU占用会比较高,前阵子有个好友(贾文涛-涛哥)向我推荐了一个opengl绘制的开源东西,QNanoPainter,东西是个好东西,我个人的理解是直接封装了opengl绘制的qpainter,可以使得绘制全部走GPU,这样就可以大大减轻CPU的负担,非常方便,我自己试了下,方法和绘制逻辑和qpainter有点不一样,暂时没有将所有控件改成QNanoPainter版本,以后看情况吧。

二、实现的功能1:可设置精确度(小数点后几位)和间距2:可设置背景色/柱状颜色/线条颜色3:可设置长线条步长及短线条步长4:可启用动画及动画步长5:可设置范围值6:支持负数刻度值7:支持任意窗体大小缩放8:可设置柱状条位置 左侧 居中 右侧9:可设置刻度尺位置 无 左侧 右侧 两侧10:可设置用户设定目标值三、效果图在这里插入图片描述在这里插入图片描述四、头文件代码#ifndef RULERTEMP_H #define RULERTEMP_H /** * 柱状温度计控件 作者:feiyangqingyun(QQ:517216493) 2016-11-4 * 1:可设置精确度(小数点后几位)和间距 * 2:可设置背景色/柱状颜色/线条颜色 * 3:可设置长线条步长及短线条步长 * 4:可启用动画及动画步长 * 5:可设置范围值 * 6:支持负数刻度值 * 7:支持任意窗体大小缩放 * 8:可设置柱状条位置 左侧 居中 右侧 * 9:可设置刻度尺位置 无 左侧 右侧 两侧 * 10:可设置用户设定目标值 */ #include #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include #else #include #endif class QDESIGNER_WIDGET_EXPORT RulerTemp : public QWidget #else class RulerTemp : public QWidget #endif { Q_OBJECT Q_ENUMS(BarPosition) Q_ENUMS(TickPosition) Q_PROPERTY(double minValue READ getMinValue WRITE setMinValue) Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue) Q_PROPERTY(double value READ getValue WRITE setValue) Q_PROPERTY(int precision READ getPrecision WRITE setPrecision) Q_PROPERTY(int longStep READ getLongStep WRITE setLongStep) Q_PROPERTY(int shortStep READ getShortStep WRITE setShortStep) Q_PROPERTY(int space READ getSpace WRITE setSpace) Q_PROPERTY(bool animation READ getAnimation WRITE setAnimation) Q_PROPERTY(double animationStep READ getAnimationStep WRITE setAnimationStep) Q_PROPERTY(bool showUserValue READ getShowUserValue WRITE setShowUserValue) Q_PROPERTY(double userValue READ getUserValue WRITE setUserValue) Q_PROPERTY(QColor userValueColor READ getUserValueColor WRITE setUserValueColor) Q_PROPERTY(QColor bgColorStart READ getBgColorStart WRITE setBgColorStart) Q_PROPERTY(QColor bgColorEnd READ getBgColorEnd WRITE setBgColorEnd) Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor) Q_PROPERTY(QColor barBgColor READ getBarBgColor WRITE setBarBgColor) Q_PROPERTY(QColor barColor READ getBarColor WRITE setBarColor) Q_PROPERTY(BarPosition barPosition READ getBarPosition WRITE setBarPosition) Q_PROPERTY(TickPosition tickPosition READ getTickPosition WRITE setTickPosition) public: enum BarPosition { BarPosition_Left = 0, //左侧显示 BarPosition_Right = 1, //右侧显示 BarPosition_Center = 2 //居中显示 }; enum TickPosition { TickPosition_Null = 0, //不显示 TickPosition_Left = 1, //左侧显示 TickPosition_Right = 2, //右侧显示 TickPosition_Both = 3 //两侧显示 }; explicit RulerTemp(QWidget *parent = 0); ~RulerTemp(); protected: void resizeEvent(QResizeEvent *); void paintEvent(QPaintEvent *); void drawBg(QPainter *painter); void drawBarBg(QPainter *painter); void drawRuler(QPainter *painter, int type); void drawBar(QPainter *painter); void drawValue(QPainter *painter); private: double minValue; //最小值 double maxValue; //最大值 double value; //目标值 int precision; //精确度,小数点后几位 int longStep; //长线条等分步长 int shortStep; //短线条等分步长 int space; //间距 bool animation; //是否启用动画显示 double animationStep; //动画显示时步长 bool showUserValue; //显示用户设定值 double userValue; //用户设定值 QColor userValueColor; //用户设定值颜色 QColor bgColorStart; //背景渐变开始颜色 QColor bgColorEnd; //背景渐变结束颜色 QColor lineColor; //线条颜色 QColor barBgColor; //柱状背景色 QColor barColor; //柱状颜色 BarPosition barPosition; //柱状条位置 TickPosition tickPosition; //刻度尺位置 int barWidth; //水银柱宽度 int barHeight; //水银柱高度 int radius; //水银柱底部圆半径 int targetX; //目标X坐标 QRectF barRect; //柱状区域 QRectF circleRect; //底部圆区域 bool reverse; //是否倒退 double currentValue; //当前值 QTimer *timer; //定时器绘制动画 private slots: void updateValue(); public: double getMinValue() const; double getMaxValue() const; double getValue() const; int getPrecision() const; int getLongStep() const; int getShortStep() const; int getSpace() const; bool getAnimation() const; double getAnimationStep() const; bool getShowUserValue() const; double getUserValue() const; QColor getUserValueColor() const; QColor getBgColorStart() const; QColor getBgColorEnd() const; QColor getLineColor() const; QColor getBarBgColor() const; QColor getBarColor() const; BarPosition getBarPosition() const; TickPosition getTickPosition() const; QSize sizeHint() const; QSize minimumSizeHint() const; public Q_SLOTS: //设置最大最小值-范围值 void setRange(double minValue, double maxValue); void setRange(int minValue, int maxValue); //设置最大最小值 void setMinValue(double minValue); void setMaxValue(double maxValue); //设置目标值 void setValue(double value); void setValue(int value); //设置精确度 void setPrecision(int precision); //设置线条等分步长 void setLongStep(int longStep); void setShortStep(int shortStep); //设置间距 void setSpace(int space); //设置是否启用动画显示 void setAnimation(bool animation); //设置动画显示的步长 void setAnimationStep(double animationStep); //设置是否显示用户设定值 void setShowUserValue(bool showUserValue); //设置用户值 void setUserValue(double userValue); void setUserValue(int userValue); //设置用户设定值颜色 void setUserValueColor(const QColor &userValueColor); //设置背景颜色 void setBgColorStart(const QColor &bgColorStart); void setBgColorEnd(const QColor &bgColorEnd); //设置线条颜色 void setLineColor(const QColor &lineColor); //设置柱状颜色 void setBarBgColor(const QColor &barBgColor); void setBarColor(const QColor &barColor); //设置柱状条位置 void setBarPosition(const BarPosition &barPosition); //设置刻度尺位置 void setTickPosition(const TickPosition &tickPosition); Q_SIGNALS: void valueChanged(double value); }; #endif // RULERTEMP_H五、核心代码void RulerTemp::paintEvent(QPaintEvent *) { //绘制准备工作,启用反锯齿 QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); //绘制背景 drawBg(&painter); //绘制标尺及刻度尺 if (tickPosition == TickPosition_Left) { drawRuler(&painter, 0); } else if (tickPosition == TickPosition_Right) { drawRuler(&painter, 1); } else if (tickPosition == TickPosition_Both) { drawRuler(&painter, 0); drawRuler(&painter, 1); } //绘制水银柱背景,包含水银柱底部圆 drawBarBg(&painter); //绘制当前水银柱,包含水银柱底部圆 drawBar(&painter); //绘制当前值 drawValue(&painter); } void RulerTemp::drawBg(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); QLinearGradient bgGradient(QPointF(0, 0), QPointF(0, height())); bgGradient.setColorAt(0.0, bgColorStart); bgGradient.setColorAt(1.0, bgColorEnd); painter->setBrush(bgGradient); painter->drawRect(rect()); painter->restore(); } void RulerTemp::drawBarBg(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(barBgColor); int barX = targetX - barWidth / 2; int barY = space; QRectF barRect(barX, barY, barWidth, barHeight); int circleX = targetX - radius; //偏移 2 个像素,使得看起来边缘完整 int circleY = height() - radius * 2 - 2; int circleWidth = radius * 2; QRectF circleRect(circleX, circleY, circleWidth, circleWidth); QPainterPath path; path.addRect(barRect); path.addEllipse(circleRect); path.setFillRule(Qt::WindingFill); painter->drawPath(path); painter->restore(); } void RulerTemp::drawRuler(QPainter *painter, int type) { painter->save(); painter->setPen(lineColor); int barPercent = barWidth / 8; if (barPercent < 2) { barPercent = 2; } //绘制纵向标尺刻度 double length = height() - 2 * space - 2 * radius; //计算每一格移动多少 double increment = length / (maxValue - minValue); //长线条短线条长度 int longLineLen = 10; int shortLineLen = 7; //绘制纵向标尺线 偏移 5 像素 int offset = barWidth / 2 + 5; //左侧刻度尺需要重新计算 if (type == 0) { offset = -offset; longLineLen = -longLineLen; shortLineLen = -shortLineLen; } double initX = targetX + offset; double initY = space + barPercent; QPointF topPot(initX, initY); QPointF bottomPot(initX, height() - 2 * radius - 5); painter->drawLine(topPot, bottomPot); //根据范围值绘制刻度值及刻度值 for (int i = maxValue; i >= minValue; i = i - shortStep) { if (i % longStep == 0) { //绘制长线条 QPointF leftPot(initX + longLineLen, initY); QPointF rightPot(initX, initY); painter->drawLine(leftPot, rightPot); //绘制文字 QString strValue = QString("%1").arg((double)i, 0, 'f', precision); double fontHeight = painter->fontMetrics().height(); if (type == 0) { QRect textRect(initX - 45, initY - fontHeight / 3, 30, 15); painter->drawText(textRect, Qt::AlignRight, strValue); } else if (type == 1) { QRect textRect(initX + longLineLen + 5, initY - fontHeight / 3, 30, 15); painter->drawText(textRect, Qt::AlignLeft, strValue); } } else { //绘制短线条 QPointF leftPot(initX + shortLineLen, initY); QPointF rightPot(initX, initY); painter->drawLine(leftPot, rightPot); } initY += increment * shortStep; } painter->restore(); } void RulerTemp::drawBar(QPainter *painter) { painter->save(); painter->setPen(Qt::NoPen); painter->setBrush(barColor); //计算在背景宽度的基础上缩小的百分比, 至少为 2 int barPercent = barWidth / 8; int circlePercent = radius / 6; if (barPercent < 2) { barPercent = 2; } if (circlePercent < 2) { circlePercent = 2; } //标尺刻度高度 double length = height() - 2 * space - 2 * radius; //计算每一格移动多少 double increment = length / (maxValue - minValue); //计算标尺的高度 int rulerHeight = height() - 1 * space - 2 * radius; int barX = targetX - barWidth / 2; int barY = rulerHeight - (currentValue - minValue) * increment; barRect = QRectF(barX + barPercent, barY + barPercent, barWidth - barPercent * 2, barHeight + radius - barY); int circleX = targetX - radius; //偏移 2 个像素,使得看起来边缘完整 int circleY = height() - radius * 2 - 2; int circleWidth = radius * 2 - circlePercent * 2; circleRect = QRectF(circleX + circlePercent, circleY + circlePercent, circleWidth, circleWidth); QPainterPath path; path.addRect(barRect); path.addEllipse(circleRect); path.setFillRule(Qt::WindingFill); painter->drawPath(path); //绘制用户设定值三角号 if (showUserValue) { if (tickPosition == TickPosition_Left || tickPosition == TickPosition_Both) { QPolygon pts; int offset = 15; double initX = targetX - (barWidth / 2 + 5); double initY = rulerHeight - (userValue - minValue) * increment; pts.append(QPoint(initX, initY)); pts.append(QPoint(initX - offset, initY - offset / 2)); pts.append(QPoint(initX - offset, initY + offset / 2)); painter->setBrush(userValueColor); painter->drawPolygon(pts); } if (tickPosition == TickPosition_Right || tickPosition == TickPosition_Both) { QPolygon pts; int offset = 15; double initX = targetX + (barWidth / 2 + 5); double initY = rulerHeight - (userValue - minValue) * increment; pts.append(QPoint(initX, initY)); pts.append(QPoint(initX + offset, initY - offset / 2)); pts.append(QPoint(initX + offset, initY + offset / 2)); painter->setBrush(userValueColor); painter->drawPolygon(pts); } } painter->restore(); } void RulerTemp::drawValue(QPainter *painter) { painter->save(); QFont font; font.setPixelSize(circleRect.width() * 0.55); painter->setFont(font); painter->setPen(Qt::white); painter->drawText(circleRect, Qt::AlignCenter, QString("%1").arg(currentValue)); painter->restore(); }六、控件介绍超过150个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。每个控件默认配色和demo对应的配色都非常精美。超过130个可见控件,6个不可见控件。部分控件提供多种样式风格选择,多种指示器样式选择。所有控件自适应窗体拉伸变化。集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。自带activex控件demo,所有控件可以直接运行在ie浏览器中。集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。七、SDK下载SDK下载链接:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取码:877p下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo,自定义控件+属性设计器。自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。 目前已提供26个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有