Qt绘制指南针(仪表盘绘制封装使用)

        指南针是一种用来确定方向的工具。它由一个磁针制成,其一端被磁化,可以自由旋转。当放置在水平面上时,磁针会指向地球的磁北极。通过观察磁针的指向,我们可以确定地理北方的方向。本示例是在Qt中绘制一个指南针,通过继承QWidget类,并重写其paintEvent函数来实现。并对仪表盘绘制进行封装。

一、简述

         这个示例创建了一个名为CompassWidget的自定义小部件,它继承自QWidget类。在paintEvent()函数中,我们使用QPainter类进行绘图操作。

二、 设计思路    
  1. 创建一个QWidget子类CompassWidget用于绘制指南针。
  2. 在CompassWidget的构造函数中,设置指南针的背景色、大小等属性。
  3. 定义QcGaugeWidget类,绘制指南针的各个组成部分,重写相关部件的paintEvent()函数。
  4. 使用QPainter在paintEvent()函数中绘制指南针的主体部分,包括圆形背景、指针和刻度。
  5. 根据指南针的当前角度,计算并绘制指针的位置和角度。
  6. 添加一个public的setCurrentValue()函数,用于设置指南针的角度,并在其中调用update()函数刷新界面。
三、效果 

 

四、核心代码  
1、头文件

        compasswidget.h 指南针表盘控件

#ifndef COMPASSWIDGET_H
#define COMPASSWIDGET_H#include <QWidget>class QcGaugeWidget;
class QcNeedleItem;
class QVBoxLayout;class CompassWidget : public QWidget
{Q_OBJECT
public:explicit CompassWidget(QWidget *parent = 0);~CompassWidget();public slots:void setCurrentValue(int value);private:void init();private:QcGaugeWidget   *m_pCompassGauge; //表盘QcNeedleItem    *m_pCompassNeedle; //指针QVBoxLayout     *m_pMainLayout;
};#endif // COMPASSWIDGET_H

qcgaugewidget.h 仪表盘绘制封装(此处只有绘制指南针所需代码,全部代码请下载) 

#ifndef QCGAUGEWIDGET_H
#define QCGAUGEWIDGET_H#include <QWidget>
#include <QPainter>
#include <QObject>
#include <QRectF>
#include <QtMath>class QcGaugeWidget;
class QcItem;
class QcBackgroundItem;
class QcDegreesItem;
class QcNeedleItem;
class QcLabelItem;
class QcGlassItem;///
class QcGaugeWidget : public QWidget
{Q_OBJECT
public:explicit QcGaugeWidget(QWidget *parent = 0);    QcBackgroundItem* addBackground(float position);QcDegreesItem* addDegrees(float position);QcNeedleItem* addNeedle(float position);QcLabelItem* addLabel(float position);QcGlassItem* addGlass(float position);void addItem(QcItem* item, float position);int removeItem(QcItem* item);QList <QcItem*> items();QList <QcItem*> mItems;private:void paintEvent(QPaintEvent *);};///
class QcItem : public QObject
{Q_OBJECT
public:explicit QcItem(QObject *parent = 0);virtual void draw(QPainter *) = 0;virtual int type();void setPosition(float percentage);float position();QRectF rect();enum Error{InvalidValueRange,InvalidDegreeRange,InvalidStep};protected:QRectF adjustRect(float percentage);float getRadius(const QRectF &);float getAngle(const QPointF&, const QRectF &tmpRect);QPointF getPoint(float deg, const QRectF &tmpRect);QRectF resetRect();void update();private:QRectF mRect;QWidget *parentWidget;float mPosition;
};///
class QcScaleItem : public QcItem
{Q_OBJECT
public:explicit QcScaleItem(QObject *parent = 0);void setValueRange(float minValue,float maxValue);void setDgereeRange(float minDegree,float maxDegree);void setMinValue(float minValue);void setMaxValue(float maxValue);void setMinDegree(float minDegree);void setMaxDegree(float maxDegree);protected:float getDegFromValue(float);float mMinValue;float mMaxValue;float mMinDegree;float mMaxDegree;
};///
class QcBackgroundItem : public QcItem
{Q_OBJECT
public:explicit QcBackgroundItem(QObject *parent = 0);void draw(QPainter*);void addColor(float position, const QColor& color);void clearrColors();private:QPen mPen;QList<QPair<float,QColor> > mColors;QLinearGradient mLinearGrad;
};///
class QcGlassItem : public QcItem
{Q_OBJECT
public:explicit QcGlassItem(QObject *parent = 0);void draw(QPainter*);
};///
class QcLabelItem : public QcItem
{Q_OBJECT
public:explicit QcLabelItem(QObject *parent = 0);virtual void draw(QPainter *);void setAngle(float);float angle();void setText(const QString &text, bool repaint = true);QString text();void setColor(const QColor& color);QColor color();private:float mAngle;QString mText;QColor mColor;
};///
class  QcDegreesItem : public QcScaleItem
{Q_OBJECT
public:explicit QcDegreesItem(QObject *parent = 0);void draw(QPainter *painter);void setStep(float step);void setColor(const QColor& color);void setSubDegree(bool );
private:float mStep;QColor mColor;bool mSubDegree;
};///
class QcNeedleItem : public QcScaleItem
{Q_OBJECT
public:explicit QcNeedleItem(QObject *parent = 0);void draw(QPainter*);void setCurrentValue(float value);float currentValue();void setValueFormat(QString format);QString currentValueFormat();void setColor(const QColor & color);QColor color();void setLabel(QcLabelItem*);QcLabelItem * label();enum NeedleType{DiamonNeedle,TriangleNeedle,//三角指针FeatherNeedle,AttitudeMeterNeedle,CompassNeedle   //指南针};void setNeedle(QcNeedleItem::NeedleType needleType);
private:QPolygonF mNeedlePoly;float mCurrentValue;QColor mColor;void createDiamonNeedle(float r);void createTriangleNeedle(float r);void createFeatherNeedle(float r);void createAttitudeNeedle(float r);void createCompassNeedle(float r);NeedleType mNeedleType;QcLabelItem *mLabel;QString mFormat;
};#endif // QCGAUGEWIDGET_H
2、实现代码

compasswidget.cpp 

#include "compasswidget.h"
#include <QVBoxLayout>
#include "qcgaugewidget.h"CompassWidget::CompassWidget(QWidget *parent): QWidget(parent)
{init();
}CompassWidget::~CompassWidget()
{
}void CompassWidget::setCurrentValue(int value)
{m_pCompassNeedle->setCurrentValue(value);
}void CompassWidget::init()
{m_pCompassGauge = new QcGaugeWidget;m_pCompassGauge->addBackground(99);QcBackgroundItem *bkg1 = m_pCompassGauge->addBackground(92);bkg1->clearrColors();bkg1->addColor(0.1,Qt::black);bkg1->addColor(1.0,Qt::white);QcBackgroundItem *bkg2 = m_pCompassGauge->addBackground(88);bkg2->clearrColors();bkg2->addColor(0.1,Qt::white);bkg2->addColor(1.0,Qt::black);QcLabelItem *w = m_pCompassGauge->addLabel(80);//标签w->setText("W");w->setAngle(0);w->setColor(Qt::white);QcLabelItem *n = m_pCompassGauge->addLabel(80);n->setText("N");n->setAngle(90);n->setColor(Qt::white);QcLabelItem *e = m_pCompassGauge->addLabel(80);e->setText("E");e->setAngle(180);e->setColor(Qt::white);QcLabelItem *s = m_pCompassGauge->addLabel(80);s->setText("S");s->setAngle(270);s->setColor(Qt::white);QcDegreesItem *deg = m_pCompassGauge->addDegrees(70);//刻度deg->setStep(5);deg->setMaxDegree(270);deg->setMinDegree(-75);deg->setColor(Qt::white);m_pCompassNeedle = m_pCompassGauge->addNeedle(60);//指针m_pCompassNeedle->setNeedle(QcNeedleItem::CompassNeedle);m_pCompassNeedle->setValueRange(0,360);m_pCompassNeedle->setMaxDegree(360);m_pCompassNeedle->setMinDegree(0);m_pCompassGauge->addBackground(7);m_pCompassGauge->addGlass(88);//毛玻璃m_pMainLayout = new QVBoxLayout(this);m_pMainLayout->addWidget(m_pCompassGauge);
}

qcgaugewidget.cpp  仪表盘绘制封装(此处只有绘制指南针所需代码,全部代码请下载) 

#include "qcgaugewidget.h"QcGaugeWidget::QcGaugeWidget(QWidget *parent) :QWidget(parent)
{setMinimumSize(250,250);
}QcBackgroundItem *QcGaugeWidget::addBackground(float position)
{QcBackgroundItem * item = new QcBackgroundItem(this);item->setPosition(position);mItems.append(item);return item;
}QcDegreesItem *QcGaugeWidget::addDegrees(float position)
{QcDegreesItem * item = new QcDegreesItem(this);item->setPosition(position);mItems.append(item);return item;
}QcNeedleItem *QcGaugeWidget::addNeedle(float position)
{QcNeedleItem * item = new QcNeedleItem(this);item->setPosition(position);mItems.append(item);return item;
}QcLabelItem *QcGaugeWidget::addLabel(float position)
{QcLabelItem * item = new QcLabelItem(this);item->setPosition(position);mItems.append(item);return item;
}QcGlassItem *QcGaugeWidget::addGlass(float position)
{QcGlassItem * item = new QcGlassItem(this);item->setPosition(position);mItems.append(item);return item;
}void QcGaugeWidget::addItem(QcItem *item,float position)
{item->setParent(this);item->setPosition(position);mItems.append(item);
}int QcGaugeWidget::removeItem(QcItem *item)
{return mItems.removeAll(item);
}QList<QcItem *> QcGaugeWidget::items()
{return mItems;
}void QcGaugeWidget::paintEvent(QPaintEvent */*paintEvt*/)
{QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);foreach (QcItem * item, mItems) {item->draw(&painter);}
}///
QcItem::QcItem(QObject *parent) :QObject(parent)
{parentWidget = qobject_cast<QWidget*>(parent);mPosition = 50;
}int QcItem::type()
{return 50;
}void QcItem::update()
{parentWidget->update();
}float QcItem::position()
{return mPosition;
}QRectF QcItem::rect()
{return mRect;
}void QcItem::setPosition(float position)
{if(position>100)mPosition = 100;else if(position<0)mPosition = 0;elsemPosition = position;update();
}QRectF QcItem::adjustRect(float percentage)
{float r = getRadius(mRect);float offset =   r-(percentage*r)/100.0;QRectF tmpRect = mRect.adjusted(offset,offset,-offset,-offset);return tmpRect;
}float QcItem::getRadius(const QRectF &tmpRect)
{float r = 0;if(tmpRect.width()<tmpRect.height())r = tmpRect.width()/2.0;elser = tmpRect.height()/2.0;return r;
}QRectF QcItem::resetRect()
{mRect = parentWidget->rect();float r = getRadius(mRect);mRect.setWidth(2.0*r);mRect.setHeight(2.0*r);mRect.moveCenter(parentWidget->rect().center());return mRect;
}QPointF QcItem::getPoint(float deg,const QRectF &tmpRect)
{float r = getRadius(tmpRect);float xx=cos(qDegreesToRadians(deg))*r;float yy=sin(qDegreesToRadians(deg))*r;QPointF pt;xx=tmpRect.center().x()-xx;yy=tmpRect.center().y()-yy;pt.setX(xx);pt.setY(yy);return pt;
}float QcItem::getAngle(const QPointF&pt, const QRectF &tmpRect)
{float xx=tmpRect.center().x()-pt.x();float yy=tmpRect.center().y()-pt.y();return qRadiansToDegrees( atan2(yy,xx));
}///
QcScaleItem::QcScaleItem(QObject *parent) :QcItem(parent)
{mMinDegree = -45;mMaxDegree = 225;mMinValue = 0;mMaxValue = 100;
}void QcScaleItem::setValueRange(float minValue, float maxValue)
{if(!(minValue<maxValue))throw( InvalidValueRange);mMinValue = minValue;mMaxValue = maxValue;}void QcScaleItem::setDgereeRange(float minDegree, float maxDegree)
{if(!(minDegree<maxDegree))throw( InvalidValueRange);mMinDegree = minDegree;mMaxDegree = maxDegree;
}float QcScaleItem::getDegFromValue(float v)
{float a = (mMaxDegree-mMinDegree)/(mMaxValue-mMinValue);float b = -a*mMinValue+mMinDegree;return a*v+b;
}void QcScaleItem::setMinValue(float minValue)
{if(minValue>mMaxValue)throw (InvalidValueRange);mMinValue = minValue;update();
}void QcScaleItem::setMaxValue(float maxValue)
{if(maxValue<mMinValue )throw (InvalidValueRange);mMaxValue = maxValue;update();
}void QcScaleItem::setMinDegree(float minDegree)
{if(minDegree>mMaxDegree)throw (InvalidDegreeRange);mMinDegree = minDegree;update();
}
void QcScaleItem::setMaxDegree(float maxDegree)
{if(maxDegree<mMinDegree)throw (InvalidDegreeRange);mMaxDegree = maxDegree;update();
}///
QcBackgroundItem::QcBackgroundItem(QObject *parent) :QcItem(parent)
{setPosition(88);mPen = Qt::NoPen;setPosition(88);addColor(0.4,Qt::darkGray);addColor(0.8,Qt::black);}void QcBackgroundItem::draw(QPainter* painter)
{QRectF tmpRect = resetRect();painter->setBrush(Qt::NoBrush);QLinearGradient linearGrad(tmpRect.topLeft(), tmpRect.bottomRight());for(int i = 0;i<mColors.size();i++){linearGrad.setColorAt(mColors[i].first,mColors[i].second);}painter->setPen(mPen);painter->setBrush(linearGrad);painter->drawEllipse(adjustRect(position()));
}void QcBackgroundItem::addColor(float position, const QColor &color)
{if(position<0||position>1)return;QPair<float,QColor> pair;pair.first = position;pair.second = color;mColors.append(pair);update();
}void QcBackgroundItem::clearrColors()
{mColors.clear();
}///
QcGlassItem::QcGlassItem(QObject *parent) :QcItem(parent)
{setPosition(88);
}void QcGlassItem::draw(QPainter *painter)
{resetRect();QRectF tmpRect1 = adjustRect(position());QRectF tmpRect2 = tmpRect1;float r = getRadius(tmpRect1);tmpRect2.setHeight(r/2.0);painter->setPen(Qt::NoPen);QColor clr1 = Qt::gray ;QColor clr2 = Qt::white;clr1.setAlphaF(0.2);clr2.setAlphaF(0.4);QLinearGradient linearGrad1(tmpRect1.topLeft(), tmpRect1.bottomRight());linearGrad1.setColorAt(0.1, clr1);linearGrad1.setColorAt(0.5, clr2);painter->setBrush(linearGrad1);painter->drawPie(tmpRect1,0,16*180);tmpRect2.moveCenter(rect().center());painter->drawPie(tmpRect2,0,-16*180);
}///
QcLabelItem::QcLabelItem(QObject *parent) :QcItem(parent)
{setPosition(50);mAngle = 270;mText = "%";mColor = Qt::black;
}void QcLabelItem::draw(QPainter *painter)
{resetRect();QRectF tmpRect = adjustRect(position());float r = getRadius(rect());QFont font("Meiryo UI", r/10.0, QFont::Bold);painter->setFont(font);painter->setPen(QPen(mColor));QPointF txtCenter = getPoint(mAngle,tmpRect);QFontMetrics fMetrics = painter->fontMetrics();QSize sz = fMetrics.size( Qt::TextSingleLine, mText );QRectF txtRect(QPointF(0,0), sz );txtRect.moveCenter(txtCenter);painter->drawText( txtRect, Qt::TextSingleLine,mText );
}void QcLabelItem::setAngle(float a)
{mAngle = a;update();
}float QcLabelItem::angle()
{return mAngle;
}void QcLabelItem::setText(const QString &text, bool repaint)
{mText = text;if(repaint)update();
}QString QcLabelItem::text()
{return mText;
}void QcLabelItem::setColor(const QColor &color)
{mColor = color;update();
}QColor QcLabelItem::color()
{return mColor;
}///
QcDegreesItem::QcDegreesItem(QObject *parent) :QcScaleItem(parent)
{mStep = 10;mColor = Qt::black;mSubDegree = false;setPosition(90);
}void QcDegreesItem::draw(QPainter *painter)
{resetRect();QRectF tmpRect = adjustRect(position());painter->setPen(mColor);float r = getRadius(tmpRect);for(float val = mMinValue;val<=mMaxValue;val+=mStep){float deg = getDegFromValue(val);QPointF pt = getPoint(deg,tmpRect);QPainterPath path;path.moveTo(pt);path.lineTo(tmpRect.center());pt = path.pointAtPercent(0.03);QPointF newPt = path.pointAtPercent(0.13);QPen pen;pen.setColor(mColor);if(!mSubDegree)pen.setWidthF(r/25.0);painter->setPen(pen);painter->drawLine(pt,newPt);}
}void QcDegreesItem::setStep(float step)
{mStep = step;update();
}void QcDegreesItem::setColor(const QColor& color)
{mColor = color;update();
}void QcDegreesItem::setSubDegree(bool b)
{mSubDegree = b;update();
}///
QcNeedleItem::QcNeedleItem(QObject *parent) :QcScaleItem(parent)
{mCurrentValue = 0;mColor = Qt::black;mLabel = NULL;mNeedleType = FeatherNeedle;
}void QcNeedleItem::draw(QPainter *painter)
{resetRect();QRectF tmpRect = adjustRect(position());painter->save();painter->translate(tmpRect.center());float deg = getDegFromValue( mCurrentValue);painter->rotate(deg+90.0);painter->setBrush(QBrush(mColor));painter->setPen(Qt::NoPen);QLinearGradient grad;switch (mNeedleType) {case QcNeedleItem::FeatherNeedle:createFeatherNeedle(getRadius(tmpRect));break;case QcNeedleItem::DiamonNeedle:createDiamonNeedle(getRadius(tmpRect));break;case QcNeedleItem::TriangleNeedle:createTriangleNeedle(getRadius(tmpRect));break;case QcNeedleItem::AttitudeMeterNeedle:createAttitudeNeedle(getRadius(tmpRect));break;case QcNeedleItem::CompassNeedle:createCompassNeedle(getRadius(tmpRect));grad.setStart(mNeedlePoly[0]);grad.setFinalStop(mNeedlePoly[1]);grad.setColorAt(0.9,Qt::red);grad.setColorAt(1,Qt::blue);painter->setBrush(grad);break;default:break;}painter->drawConvexPolygon(mNeedlePoly);painter->restore();
}void QcNeedleItem::setCurrentValue(float value)
{if(value<mMinValue)mCurrentValue = mMinValue;else if(value>mMaxValue)mCurrentValue = mMaxValue;elsemCurrentValue = value;if(mLabel!=0)mLabel->setText(QString::number(mCurrentValue),false);update();
}float QcNeedleItem::currentValue()
{return mCurrentValue;
}void QcNeedleItem::setValueFormat(QString format){mFormat = format;update();
}QString QcNeedleItem::currentValueFormat(){return mFormat;
}void QcNeedleItem::setColor(const QColor &color)
{mColor = color;update();
}QColor QcNeedleItem::color()
{return mColor;
}void QcNeedleItem::setLabel(QcLabelItem *label)
{mLabel = label;update();
}QcLabelItem *QcNeedleItem::label()
{return mLabel;
}void QcNeedleItem::setNeedle(QcNeedleItem::NeedleType needleType)
{mNeedleType = needleType;update();
}void QcNeedleItem::createDiamonNeedle(float r)
{QVector<QPointF> tmpPoints;tmpPoints.append(QPointF(0.0, 0.0));tmpPoints.append(QPointF(-r/20.0,r/20.0));tmpPoints.append(QPointF(0.0, r));tmpPoints.append(QPointF(r/20.0,r/20.0));mNeedlePoly = tmpPoints;
}void QcNeedleItem::createTriangleNeedle(float r)
{QVector<QPointF> tmpPoints;tmpPoints.append(QPointF(0.0, r));tmpPoints.append(QPointF(-r/40.0, 0.0));tmpPoints.append(QPointF(r/40.0,0.0));mNeedlePoly = tmpPoints;
}void QcNeedleItem::createFeatherNeedle(float r)
{QVector<QPointF> tmpPoints;tmpPoints.append(QPointF(0.0, r));tmpPoints.append(QPointF(-r/40.0, 0.0));tmpPoints.append(QPointF(-r/15.0, -r/5.0));tmpPoints.append(QPointF(r/15.0,-r/5));tmpPoints.append(QPointF(r/40.0,0.0));mNeedlePoly = tmpPoints;
}void QcNeedleItem::createAttitudeNeedle(float r)
{QVector<QPointF> tmpPoints;tmpPoints.append(QPointF(0.0, r));tmpPoints.append(QPointF(-r/20.0, 0.85*r));tmpPoints.append(QPointF(r/20.0,0.85*r));mNeedlePoly = tmpPoints;
}void QcNeedleItem::createCompassNeedle(float r)
{QVector<QPointF> tmpPoints;tmpPoints.append(QPointF(0.0, r));tmpPoints.append(QPointF(-r/15.0, 0.0));tmpPoints.append(QPointF(0.0, -r));tmpPoints.append(QPointF(r/15.0,0.0));mNeedlePoly = tmpPoints;
}

以上是Qt绘制指南针实现代码,在实际使用中,可以根据需要自定义动画文件和样式。

该自定义控件主要特点有:

1、纯QPaint绘制,不包括图片等文件;

2、多种自定义控制,非常灵活;

3、能够自适应大小,不需要手动调整;

        需要注意的是,在使用QPainter时,需要灵活运用QPainter的绘图函数和提供给用户的交互函数,并注意处理用户的交互操作和组件的尺寸调整等问题。

五、使用示例

以下是一个简单的示例代码,演示了如何在Qt中使用此控件:

#include "mainwindow.h"
#include "compasswidget.h"
#include <QSlider>
#include <QHBoxLayout>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{CompassWidget *pCompassWidget = new CompassWidget(this);QSlider *slider = new QSlider(this);slider->setRange(0, 360);connect(slider, &QSlider::valueChanged, pCompassWidget, &CompassWidget::setCurrentValue);QWidget *widget = new QWidget(this);QHBoxLayout *layout = new QHBoxLayout(widget);layout->addWidget(pCompassWidget);layout->addWidget(slider);setCentralWidget(widget);resize(400, 400);
}MainWindow::~MainWindow()
{
}

总结一下,指南针的设计方法和流程如下:

1、绘制指南针的背景。可以使用QPainter的drawEllipse方法来绘制一个圆形背景,然后填充颜色。

2、绘制指南针的刻度。可以使用QPainter的drawLine方法绘制指南针的刻度线,通过循环来绘制所有的刻度。

3、绘制指南针的指针。可以使用QPainter的drawLine方法绘制指南针的指针线,通过计算指针的角度来确定其位置。

4、绘制指南针的文字标签。可以使用QPainter的drawText方法绘制文字,并根据指南针的角度来确定文字标签的位置。

六、绘制一个速度表盘 

        我们利用QcGaugeWidget 将CompassWidget内init稍作修改即可实现一个速度仪表盘,代码如下(表盘和指针对象名称已修改):  

    m_pSpeedGauge = new QcGaugeWidget(this);m_pSpeedGauge->addBackground(99);QcBackgroundItem *bkg1 = m_pSpeedGauge->addBackground(92);bkg1->clearrColors();bkg1->addColor(0.1,Qt::black);bkg1->addColor(1.0,Qt::white);QcBackgroundItem *bkg2 = m_pSpeedGauge->addBackground(88);bkg2->clearrColors();bkg2->addColor(0.1,Qt::gray);bkg2->addColor(1.0,Qt::darkGray);m_pSpeedGauge->addArc(55);m_pSpeedGauge->addDegrees(65)->setValueRange(0,80);m_pSpeedGauge->addColorBand(50);m_pSpeedGauge->addValues(80)->setValueRange(0,80);m_pSpeedGauge->addLabel(70)->setText("Km/h");QcLabelItem *lab = m_pSpeedGauge->addLabel(40);lab->setText("0");m_pSpeedNeedle = m_pSpeedGauge->addNeedle(60);m_pSpeedNeedle->setLabel(lab);m_pSpeedNeedle->setColor(Qt::white);m_pSpeedNeedle->setValueRange(0,80);m_pSpeedGauge->addBackground(7);m_pSpeedGauge->addGlass(88);m_pMainLayout = new QVBoxLayout(this);m_pMainLayout->addWidget(m_pSpeedGauge);setLayout(m_pMainLayout);

效果如下:

 

        谢谢您的关注和阅读。如果您还有其他问题或需要进一步的帮助,请随时联系我。祝您一切顺利!

七、源代码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/49111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android WebViewClient 的 `shouldOverrideUrlLoading` 方法

简介 在Android开发中&#xff0c;WebView是一个强大的工具&#xff0c;可以在你的应用中显示网页内容。了解 WebViewClient 中的 shouldOverrideUrlLoading 方法是至关重要的&#xff0c;因为这个方法允许你控制 URL 在 WebView 中的处理方式。 在本文中&#xff0c;我们将详…

S71200 - 笔记

1 S71200 0 ProfiNet - 2 PLC编程 01.如何零基础快速上手S7-1200_哔哩哔哩_bilibili 西门子S7-1200PLC编程设计学习视频&#xff0c;从入门开始讲解_哔哩哔哩_bilibili

Linux:进程信号(一.认识信号、信号的产生及深层理解、Term与Core)

上次结束了进程间通信的知识介绍&#xff1a;Linux&#xff1a;进程间通信&#xff08;二.共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量 文章目录 1.认识信号进程看待信号方式 2.信号的产生2.1信号的处理的方式 --- signal()函数2.2kill指令产生信号2.3键盘产生…

最新快乐二级域名分发系统重置版v1.7源码-最新美化版+源码+可对接支付

源码简介&#xff1a; 最新快乐二级域名分发系统重置版v1.7源码&#xff0c;它是最新美化版源码可对接支付。 快乐二级域名分发系统重置版v1.7源码&#xff0c;简单快捷、功能强大的控制面板。系统稳定长久&#xff0c;控制面板没任何广告&#xff0c;让网站更实用方便。 最…

现货白银交易中spring形态的应用

在现货白银市场中交易想取得成功并从市场中获利&#xff0c;掌握一些工具是必不可少的&#xff0c;而今天我们要介绍的现货白银的交易工具就是spring形态。 对于spring这个英文&#xff0c;我们都很熟悉&#xff0c;它有春天的意思&#xff0c;但这里所说的spring形态并不是指春…

ComfyUI进阶:Comfyroll节点 (最终篇)+应用实例

前言&#xff1a; 学习ComfyUI是一场持久战&#xff0c;而Comfyroll 是一款功能强大的自定义节点集合&#xff0c;专为 ComfyUI 用户打造&#xff0c;旨在提供更加丰富和专业的图像生成与编辑工具。借助这些节点&#xff0c;用户可以在静态图像的精细调整和动态动画的复杂构建…

【LabVIEW作业篇 - 5】:水仙花数、数组与for循环的连接

文章目录 水仙花数数组与for循环的连接 水仙花数 水仙花数&#xff0c;是指一个3位数&#xff0c;它的每个位上的数字的3次幂之和等于它本身。如371 3^3 7^3 1^3&#xff0c;则371是一个水仙花数。 思路&#xff1a;水仙花数是一个三位数&#xff0c;通过使用for循环&#xf…

redis的使用场景和持久化方式

redis的使用场景 热点数据的缓存。热点&#xff1a;频繁读取的数据。限时任务的操作&#xff1a;短信验证码。完成session共享的问题完成分布式锁。 redis的持久化方式 什么是持久化&#xff1a;把内存中的数据存储到磁盘的过程&#xff0c;同时也可以把磁盘中的数据加载到内存…

FPGA实现二选一数据选择器

在FPGA开发当中&#xff0c;我们最早开始接触的就是关于二选一选择器的设计。 1、原理 通过一个sel选择位判断输出out为a还是b&#xff0c;这里我们规定&#xff1a; sel0时&#xff0c;outa sel1时&#xff0c;outb 2、工程代码 多路选择器的缩写为MUX&#xff0c;这里我们见…

Git报错fatal: detected dubious ownership in repository

报错信息 fatal: detected dubious ownership in repository at 解决办法 一行代码解决 git config --global --add safe.directory "*";如何使用git工具初始胡项目并且和远程仓库建立联系 git init–建立一个本地仓库 git add README.md–将README.md文件加入…

【Day1415】Bean管理、SpringBoot 原理、总结、Maven 高级

0 SpringBoot 配置优先级 从上到下 虽然 springboot 支持多种格式配置文件&#xff0c;但是在项目开发时&#xff0c;推荐统一使用一种格式的配置 &#xff08;yml是主流&#xff09; 1 Bean管理 1.1 从 IOC 容器中获取 Bean 1.2 Bean 作品域 可以通过注解 Scope("proto…

计算机网络八股文(后续更新)

文章目录 一、计算机网络体系结构1、计算机网络的各层协议及作用&#xff1f; 二、物理层三、数据链路层四、网络层五、传输层1、TCP和UDP的区别&#xff1f;2、UDP 和 TCP 对应的应用场景是什么&#xff1f;3、详细介绍一下 TCP 的三次握手机制4、为什么需要三次握手&#xff…

测试管理工具、自动化测试工具、跨浏览器测试工具 推荐

测试管理工具 1&#xff09;Xray Xray 是排名第一的手动与自动化测试管理应用&#xff0c;专为质量保证而设计。它是一个功能齐全的工具&#xff0c;能够无缝集成于 Jira 中。其目的是通过有效和高效的测试帮助公司提高产品质量。 功能特点&#xff1a; 需求、测试、缺陷和执…

Java | Leetcode Java题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; class Solution {public int hIndex(int[] citations) {int n citations.length;int left 0, right n - 1;while (left < right) {int mid left (right - left) / 2;if (citations[mid] > n - mid) {right mid - 1;} else {lef…

深入浅出mediasoup—协议交互

本文主要分析 mediasoup 一对一 WebRTC 通信 demo 的协议交互&#xff0c;从协议层面了解 mediasoup 的设计与实现&#xff0c;这是深入阅读 mediasoup 源码的重要基础。 1. 时序图 下图是 mediasoup 客户端-服务器协议交互的总体架构&#xff0c;服务器是一个 Node.js 进程加…

【计算机毕业设计】877陪诊系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

使用nginx实现一个端口和ip访问多个vue前端

前言&#xff1a;由于安全组要求&#xff0c;前端页面只开放一个端口&#xff0c;但是项目有多个前端&#xff0c;此前一直使用的是一个前端使用单独一个端口进行访问&#xff0c;现在需要调整。 需要实现&#xff1a;这里以80端口为例&#xff0c;两个前端分别是&#xff1a;p…

AI 驱动下的一体化分布式数据库:滴滴、快手、中国恩菲、好未来、翼鸥教育共话创新应用实践|OceanBase Meetup 精彩回顾

7月6日&#xff0c;OceanBase Meetup 北京站——“AI 驱动下的一体化分布式数据库&#xff1a;跨行业多场景的创新应用与实战”举办。来自滴滴、快手、中国恩菲、好未来、翼鸥教育、蚂蚁集团及OceanBase等众多行业技术专家与资深用户&#xff0c;围绕众多用户关注的AI 与数据库…

物联网mqtt网关搭建背后的技术原理

前言 物联网是现在比较热门的软件领域&#xff0c;众多物联网厂商都有自己的物联网平台&#xff0c;而物联网平台其中一个核心的模块就是Mqtt网关。这篇文章的目的是手把手教大家写书写一个mqtt网关&#xff0c;后端存储支持Kafka/Pulsar&#xff0c;支持mqtt 连接、断链、发送…

Zabbix监控系统:zabbix服务部署+基于Proxy分布式部署+zabbix主动与被动监控模式

一、Zabbix概述 1.1 简介 zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff0c;提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。 zabbix…