最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于QT實(shí)現(xiàn)自定義溫度計(jì)的示例代碼

 更新時(shí)間:2023年11月07日 14:00:41   作者:瘋狂的挖掘機(jī)  
QT原生控件沒(méi)有實(shí)現(xiàn)如儀表盤或者溫度計(jì)的控件,只好自己實(shí)現(xiàn),所以本文為大家介紹了如何利用qt實(shí)現(xiàn)自定義溫度/濕度控件,感興趣的小伙伴可以了解下

0 引入

QT原生控件沒(méi)有實(shí)現(xiàn)如儀表盤或者溫度計(jì)的控件,只好自己實(shí)現(xiàn),文章代碼部分參考引用的文章。直接上圖

圖一 帶有標(biāo)尺的溫度計(jì)、濕度

圖二 溫度計(jì)、濕度

控件最核心的部分:在函數(shù)paintEvent繪制部分,如果需要?jiǎng)赢嬓Ч€需要加一個(gè)QPropertyAnimation ,這是最主要的,剩下的細(xì)節(jié)根據(jù)需求增加減少即可。

1、帶有標(biāo)尺的溫度/濕度計(jì)控件

因?yàn)橹蛔鰯?shù)據(jù)顯示用,所以只需要向控件傳數(shù)據(jù)即可。

主要功能:

1、可設(shè)置顯示范圍;

2、顯示過(guò)程中加了動(dòng)畫效果;

3、背景色和前景色以及刻度尺顏色可變;

4、刻度尺間距可變,控件大小隨著QWidget適應(yīng);

1.頭文件

代碼如下(示例):

protected:
    void paintEvent(QPaintEvent *);
    void drawBg(QPainter *painter);
    void drawProgress(QPainter *painter);
    void drawRulerTop(QPainter *painter);
    void drawRulerBottom(QPainter *painter);

private:
    QPropertyAnimation *m_valueAnimation;
    double minValue;                //最小值
    double maxValue;                //最大值
    qreal value;                    //當(dāng)前值
    int longStep;                   //長(zhǎng)線條等分步長(zhǎng)
    int shortStep;                  //短線條等分步長(zhǎng)
    bool rulerTop;                  //刻度線在上面
    bool isAdd;                     //是否為增加,默認(rèn)為的增加

    QColor bgColor;                 //背景顏色
    QColor lineColor;               //線條顏色
    QColor progressColor;           //進(jìn)度顏色

public:
    qreal getValue()               const;
    void setrulerTop(bool istop);   //設(shè)定刻度線再上還是在下,默認(rèn)是在上
    void setValue(qreal v);
    void setRange(int minValue, int maxValue);
    void startAnimation();
    void updateValue(double value);
    void setBgColor(const QColor &bgColor);               //設(shè)置背景顏色
    void setLineColor(const QColor &lineColor);           //設(shè)置線條顏色
    void setProgressColor(const QColor &progressColor);   //設(shè)置進(jìn)度顏色

2.核心代碼

繪制部分參考引用2代碼,感謝劉典武老師的無(wú)私開源,有需要的可去做定制。

代碼如下:

void HumidityProgress::startAnimation()
{
    qreal startValue =  value;
    if(isAdd)
    {
        m_valueAnimation->setKeyValueAt(0.5, value+0.5);
        m_valueAnimation->setKeyValueAt(1, value);
        m_valueAnimation->setStartValue(startValue-0.5);
        m_valueAnimation->start();
    }
    else{
        m_valueAnimation->setKeyValueAt(0.5, value-0.5);
        m_valueAnimation->setKeyValueAt(1, value);
        m_valueAnimation->setStartValue(startValue+0.5);
        m_valueAnimation->start();
    }

}

void HumidityProgress::paintEvent(QPaintEvent *)
{
    //繪制準(zhǔn)備工作,啟用反鋸齒
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //按照繪制順序
    drawBg(&painter);
    drawProgress(&painter);
    if (rulerTop) {
        drawRulerTop(&painter);
    } else {
        drawRulerBottom(&painter);
    }
}

void HumidityProgress::drawBg(QPainter *painter)
{
    painter->save();
    painter->setPen(lineColor);
    painter->setBrush(bgColor);
    painter->drawRect(rect());
    painter->restore();
}

void HumidityProgress::drawProgress(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(progressColor);

    double length = width();
    double increment = length / (maxValue - minValue);
    double initX = (value - minValue) * increment;

    QRect rect(0, 0, initX, height());
    painter->drawRect(rect);
    painter->restore();
}

void HumidityProgress::drawRulerTop(QPainter *painter)
{
    painter->save();
    painter->setPen(lineColor);

    double initX = 0;

    //繪制橫向標(biāo)尺上部分底部線
    double initTopY = 0;
    QPointF lineTopLeftPot = QPointF(initX, initTopY);
    QPointF lineTopRightPot = QPointF(width() - initX, initTopY);
    painter->drawLine(lineTopLeftPot, lineTopRightPot);

    //繪制上部分及下部分橫向標(biāo)尺刻度
    double length = width();
    //計(jì)算每一格移動(dòng)多少
    double increment = length / (maxValue - minValue);
    //長(zhǎng)線條短線條長(zhǎng)度
    int longLineLen = 15;
    int shortLineLen = 10;

    //根據(jù)范圍值繪制刻度值及刻度值 長(zhǎng)線條需要移動(dòng)10像素 短線條需要移動(dòng)5像素
    for (int i = minValue; i <= maxValue; i = i + shortStep) {
        if (i % longStep == 0) {
            QPointF topPot = QPointF(initX, initTopY);
            QPointF bottomPot = QPointF(initX, initTopY + longLineLen);
            painter->drawLine(topPot, bottomPot);

            //第一個(gè)值和最后一個(gè)值不要繪制
            if (i == minValue || i == maxValue) {
                initX += increment * shortStep;
                continue;
            }

            QString strValue = QString("%1").arg((double)i, 0, 'f', 0);
            double textWidth = fontMetrics().width(strValue);
            double textHeight = fontMetrics().height();

            QPointF textPot = QPointF(initX - textWidth / 2, initTopY + textHeight + longLineLen);
            painter->drawText(textPot, strValue);
        } else {
            if (i % (longStep / 2) == 0) {
                shortLineLen = 10;
            } else {
                shortLineLen = 6;
            }

            QPointF topPot = QPointF(initX, initTopY);
            QPointF bottomPot = QPointF(initX, initTopY + shortLineLen);
            painter->drawLine(topPot, bottomPot);
        }

        initX += increment * shortStep;
    }

    painter->restore();
}

該處使用的url網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)。

2、豎起來(lái)的溫度/濕度計(jì)控件

因?yàn)橹蛔鰯?shù)據(jù)顯示用,所以只需要向控件傳數(shù)據(jù)即可。

控件是好看,但是大小不能改變,所以這里需要自己實(shí)現(xiàn)了,源碼作者已經(jīng)放上。

1.頭文件

代碼如下(示例):

#ifndef THERMOMETREDLG_H
#define THERMOMETREDLG_H
#include <QWidget>
#include <QPropertyAnimation>
#include <QPainter>
#include <QTimer>
class thermometreDlg : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(qreal value READ getValue WRITE setValue)  //聲明屬性
public:
    explicit thermometreDlg(QWidget *parent = nullptr);
    qreal getValue();
    void setValue(qreal value);
    void changeValue(qreal value);
protected:
    void paintEvent(QPaintEvent *e);
public slots:
    void startAnimation();
signals:
private:
    qreal m_value;
    qreal curValue;
    int m_width;
    QRectF m_rect;
    int maxValue, minValue;
    qreal m_radius;
    QPropertyAnimation *m_valueAnimation;
    void updateRect();
};
#endif // THERMOMETREDLG_H

2.實(shí)現(xiàn)

代碼如下(示例):

#include "thermometredlg.h"
#include <QDebug>
thermometreDlg::thermometreDlg(QWidget *parent) : QWidget(parent)
{
    m_width = 20;
    maxValue = 100;
    minValue = 0;
    m_radius = 1.05;
    m_value = 0;
    curValue = m_value;
    QTimer *at = new QTimer(this);
    at->start(1000);
    m_valueAnimation = new QPropertyAnimation(this, "value");
    m_valueAnimation->setDuration(1000);
    m_valueAnimation->setEasingCurve(QEasingCurve::OutCubic);
    m_valueAnimation->setLoopCount(1);
    connect(at, SIGNAL(timeout()), this, SLOT(startAnimation()));
}
void thermometreDlg::updateRect()
{
    m_rect.setX(0);
    m_rect.setY(20 - height()/2);
    m_rect.setWidth(m_width);
    m_rect.setHeight(height() - 40 - m_width* m_radius);
}
void thermometreDlg::setValue(qreal value)
{
    m_value = value;
    update();
}
void thermometreDlg::changeValue(qreal value)
{
    if(value > maxValue)
        value = maxValue;
    if(value < minValue)
        value = minValue;
    curValue = value;
}
qreal thermometreDlg::getValue()
{
    return m_value;
}
void thermometreDlg::paintEvent(QPaintEvent *e)
{
    updateRect();
    QPainter painter(this);
    QPen pen(Qt::black);
    painter.translate(this->width()/2, this->height()/2);  //坐標(biāo)軸移動(dòng)到中心點(diǎn)
    painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing);  // 啟用反鋸齒
    painter.save();
    //繪制上方的柱狀
    painter.fillRect(m_rect, QColor(168,200, 225));
    //繪制底部的圓
    QRectF tmpRect = QRectF(m_rect.bottomLeft(), QPointF(m_width, height()/2- m_width*m_radius));
    painter.fillRect(tmpRect, QColor(255, 0, 0));
    painter.setPen(Qt::NoPen);
    painter.setBrush(QColor(255, 0, 0));
    painter.drawEllipse(tmpRect.bottomLeft()+QPointF(tmpRect.width()/2, 0),m_width*m_radius, m_width*m_radius);
    painter.restore();
    //繪制刻度以及刻度值
    painter.save();
    painter.setPen(QColor(Qt::black));
    int nYCount = (maxValue - minValue)/10+1;
    qreal perHeight = (m_rect.height())/nYCount;
    for (int i=0; i<nYCount; ++i) {
        QPointF basePoint = m_rect.bottomLeft() - QPointF(0, perHeight/2) - QPointF(0, perHeight*i);
        //左側(cè)大刻度
        painter.drawLine(basePoint, basePoint+QPointF(-10, 0));
        for (int j=1; j<10; ++j) {
            if(i == nYCount -1)
                continue;
            painter.drawLine(basePoint-QPointF(0, perHeight/10*j),basePoint-QPointF(5, perHeight/10*j));
        }
        painter.drawText(basePoint+QPointF(-28, 4), QString("%1").arg(minValue+i*10));
        //右側(cè)大刻度
        basePoint = m_rect.bottomRight() - QPointF(0, perHeight/2) - QPointF(0, perHeight*i);
        painter.drawLine(basePoint, basePoint+QPointF(10, 0));
        for (int j=1; j<10; ++j) {
            if(i == nYCount -1)
                continue;
            painter.drawLine(basePoint-QPointF(0, perHeight/10*j),basePoint-QPointF(-5, perHeight/10*j));
        }
    }
    painter.restore();
    //根據(jù)值填充m_rect
    qreal h = (m_value-minValue)/(maxValue-minValue)*(m_rect.height()-perHeight);
    if(h<0)
        h = 0;
    if(h > m_rect.height())
        h = m_rect.height();
    painter.fillRect(m_rect.adjusted(0, m_rect.height()-h-perHeight/2-1 , 0, 0), QColor(255, 0, 0));
    QWidget::paintEvent(e);
}
void thermometreDlg::startAnimation()
{
    qreal startValue = getValue();
    m_valueAnimation->setKeyValueAt(0, startValue-1);
    m_valueAnimation->setKeyValueAt(0.5, curValue+1);
    m_valueAnimation->setKeyValueAt(1, curValue);
    m_valueAnimation->setStartValue(startValue-2);
    m_valueAnimation->start();
}

以上就是基于QT實(shí)現(xiàn)自定義溫度計(jì)的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于QT溫度計(jì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++ 排查內(nèi)存泄漏的妙招

    c++ 排查內(nèi)存泄漏的妙招

    這篇文章主要介紹了c++ 如何用輔助類排查內(nèi)存泄漏,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下
    2021-03-03
  • C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn)

    C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn)

    這篇文章主要介紹了C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C語(yǔ)言實(shí)現(xiàn)時(shí)間處理工具的示例代碼

    C語(yǔ)言實(shí)現(xiàn)時(shí)間處理工具的示例代碼

    這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)時(shí)間處理工具的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-09-09
  • c++之解決char轉(zhuǎn)string時(shí)出現(xiàn)的亂碼問(wèn)題

    c++之解決char轉(zhuǎn)string時(shí)出現(xiàn)的亂碼問(wèn)題

    這篇文章主要介紹了c++之解決char轉(zhuǎn)string時(shí)出現(xiàn)的亂碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 基于Qt實(shí)現(xiàn)視頻播放器功能

    基于Qt實(shí)現(xiàn)視頻播放器功能

    本文通過(guò)實(shí)例代碼給大家介紹了基于Qt實(shí)現(xiàn)視頻播放器功能,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-09-09
  • C++統(tǒng)一的自測(cè)接口實(shí)踐

    C++統(tǒng)一的自測(cè)接口實(shí)踐

    這篇文章主要介紹了C++統(tǒng)一的自測(cè)接口實(shí)踐,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2026-05-05
  • C++中的常對(duì)象與常對(duì)象成員詳解

    C++中的常對(duì)象與常對(duì)象成員詳解

    常成員函數(shù)可以訪問(wèn)常對(duì)象中的數(shù)據(jù)成員,但仍然不允許修改常對(duì)象中數(shù)據(jù)成員的值。有時(shí)在編程時(shí)有要求,一定要修改常對(duì)象成員中的某個(gè)數(shù)據(jù)成員的值(例如類中有一個(gè)用于計(jì)數(shù)的變量count,其值應(yīng)當(dāng)不能變化)
    2013-10-10
  • mfc文件操作CFile類之創(chuàng)建文件的方法

    mfc文件操作CFile類之創(chuàng)建文件的方法

    這篇文章主要介紹了mfc文件操作CFile類之創(chuàng)建文件的方法,需要的朋友可以參考下
    2019-04-04
  • C語(yǔ)言break和continue的語(yǔ)句用法

    C語(yǔ)言break和continue的語(yǔ)句用法

    這篇文章主要介紹了C語(yǔ)言break和continue的語(yǔ)句用法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • C++拷貝構(gòu)造函數(shù)(深拷貝與淺拷貝)詳解

    C++拷貝構(gòu)造函數(shù)(深拷貝與淺拷貝)詳解

    深拷貝和淺拷貝可以簡(jiǎn)單理解為:如果一個(gè)類擁有資源,當(dāng)這個(gè)類的對(duì)象發(fā)生復(fù)制過(guò)程的時(shí)候,資源重新分配,這個(gè)過(guò)程就是深拷貝,反之,沒(méi)有重新分配資源,就是淺拷貝
    2013-09-09

最新評(píng)論

天镇县| 呼玛县| 安化县| 乌鲁木齐市| 娱乐| 琼海市| 酒泉市| 改则县| 镇坪县| 台湾省| 皋兰县| 济南市| 板桥市| 大庆市| 清徐县| 慈利县| 东丽区| 南丹县| 芦山县| 棋牌| 彭泽县| 谢通门县| 苍梧县| 铜鼓县| 贵州省| 屯留县| 樟树市| 屏边| 哈密市| 四子王旗| 治县。| 黎城县| 瑞安市| 瓮安县| 剑河县| 金堂县| 娄烦县| 图片| 青河县| 林芝县| 青川县|