当前位置: 首页 > news >正文

Qt指南针

        Qt写的指南针demo.

      运行结果

        滑动调整指针角度

 实现代码

        h文件

#ifndef COMPASS_H
#define COMPASS_H#include <QWidget>
#include <QColor>class Compass : public QWidget
{Q_OBJECT// 可自定义属性Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor)Q_PROPERTY(QColor needleColor READ needleColor WRITE setNeedleColor)Q_PROPERTY(QColor directionColor READ directionColor WRITE setDirectionColor)Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)Q_PROPERTY(double angle READ angle WRITE setAngle)Q_PROPERTY(int borderWidth READ borderWidth WRITE setBorderWidth)public:explicit Compass(QWidget *parent = nullptr);// 获取和设置属性QColor backgroundColor() const;void setBackgroundColor(const QColor &color);QColor borderColor() const;void setBorderColor(const QColor &color);QColor needleColor() const;void setNeedleColor(const QColor &color);QColor directionColor() const;void setDirectionColor(const QColor &color);QColor textColor() const;void setTextColor(const QColor &color);double angle() const;void setAngle(double angle);int borderWidth() const;void setBorderWidth(int width);QSize sizeHint() const override;QSize minimumSizeHint() const override;protected:void paintEvent(QPaintEvent *event) override;private:void drawCompassCircle(QPainter &painter);void drawDirectionMarkers(QPainter &painter);void drawNeedle(QPainter &painter);void drawTechRing(QPainter &painter);QColor m_backgroundColor;QColor m_borderColor;QColor m_needleColor;QColor m_directionColor;QColor m_textColor;double m_angle;int m_borderWidth;
};#endif // COMPASS_H

        c文件

#include "widget.h"
#include <QPainter>
#include <QPainterPath>
#include <QtMath>
#include <QLinearGradient>Compass::Compass(QWidget *parent) : QWidget(parent),m_backgroundColor(QColor(30, 30, 40)),m_borderColor(QColor(80, 160, 255)),m_needleColor(QColor(255, 80, 80)),m_directionColor(QColor(80, 255, 160)),m_textColor(QColor(220, 220, 220)),m_angle(0),m_borderWidth(3)
{setMinimumSize(100, 100);
}QColor Compass::backgroundColor() const { return m_backgroundColor; }
void Compass::setBackgroundColor(const QColor &color) { m_backgroundColor = color; update(); }QColor Compass::borderColor() const { return m_borderColor; }
void Compass::setBorderColor(const QColor &color) { m_borderColor = color; update(); }QColor Compass::needleColor() const { return m_needleColor; }
void Compass::setNeedleColor(const QColor &color) { m_needleColor = color; update(); }QColor Compass::directionColor() const { return m_directionColor; }
void Compass::setDirectionColor(const QColor &color) { m_directionColor = color; update(); }QColor Compass::textColor() const { return m_textColor; }
void Compass::setTextColor(const QColor &color) { m_textColor = color; update(); }double Compass::angle() const { return m_angle; }
void Compass::setAngle(double angle) { m_angle = angle; update(); }int Compass::borderWidth() const { return m_borderWidth; }
void Compass::setBorderWidth(int width) { m_borderWidth = width; update(); }QSize Compass::sizeHint() const { return QSize(200, 200); }
QSize Compass::minimumSizeHint() const { return QSize(100, 100); }void Compass::paintEvent(QPaintEvent *event)
{Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true);// 绘制指南针背景drawCompassCircle(painter);// 绘制方向标记drawDirectionMarkers(painter);// 绘制科技感圆环drawTechRing(painter);// 绘制指针drawNeedle(painter);
}void Compass::drawCompassCircle(QPainter &painter)
{int side = qMin(width(), height());QRectF outerRect(0, 0, side, side);outerRect.moveCenter(rect().center());// 绘制背景painter.setPen(Qt::NoPen);painter.setBrush(m_backgroundColor);painter.drawEllipse(outerRect);// 绘制边框QPen borderPen(m_borderColor);borderPen.setWidth(m_borderWidth);painter.setPen(borderPen);painter.setBrush(Qt::NoBrush);painter.drawEllipse(outerRect);// 绘制内圆QRectF innerRect = outerRect.adjusted(side*0.1, side*0.1, -side*0.1, -side*0.1);QRadialGradient gradient(innerRect.center(), innerRect.width()/2);gradient.setColorAt(0, QColor(50, 50, 60));gradient.setColorAt(1, QColor(20, 20, 30));painter.setPen(Qt::NoPen);painter.setBrush(gradient);painter.drawEllipse(innerRect);
}void Compass::drawDirectionMarkers(QPainter &painter)
{int side = qMin(width(), height());QRectF outerRect(0, 0, side, side);outerRect.moveCenter(rect().center());painter.save();painter.translate(outerRect.center());QFont font = painter.font();font.setPixelSize(side * 0.08);font.setBold(true);painter.setFont(font);painter.setPen(m_textColor);QStringList directions = {"N", "E", "S", "W"};QStringList subDirections = {"NE", "SE", "SW", "NW"};// 绘制主要方向标记for (int i = 0; i < 4; ++i) {painter.save();painter.rotate(i * 90);// 绘制刻度线QPen pen(m_directionColor);pen.setWidth(side * 0.01);painter.setPen(pen);painter.drawLine(0, -outerRect.height()*0.45, 0, -outerRect.height()*0.35);// 绘制方向文字painter.translate(0, -outerRect.height()*0.3);painter.rotate(-i * 90);painter.drawText(QRect(-side*0.1, -side*0.1, side*0.2, side*0.2),Qt::AlignCenter, directions[i]);painter.restore();}// 绘制次要方向标记for (int i = 0; i < 4; ++i) {painter.save();painter.rotate(45 + i * 90);// 绘制刻度线QPen pen(m_directionColor);pen.setWidth(side * 0.005);painter.setPen(pen);painter.drawLine(0, -outerRect.height()*0.45, 0, -outerRect.height()*0.38);// 绘制方向文字painter.translate(0, -outerRect.height()*0.33);painter.rotate(-45 - i * 90);painter.drawText(QRect(-side*0.1, -side*0.1, side*0.2, side*0.2),Qt::AlignCenter, subDirections[i]);painter.restore();}// 绘制更小的刻度for (int i = 0; i < 36; ++i) {if (i % 9 == 0) continue; // 跳过主要方向painter.save();painter.rotate(i * 10);QPen pen(m_textColor);pen.setWidth(side * 0.003);painter.setPen(pen);if (i % 3 == 0) {// 中等刻度painter.drawLine(0, -outerRect.height()*0.45, 0, -outerRect.height()*0.4);} else {// 小刻度painter.drawLine(0, -outerRect.height()*0.45, 0, -outerRect.height()*0.42);}painter.restore();}painter.restore();
}void Compass::drawNeedle(QPainter &painter)
{int side = qMin(width(), height());QRectF outerRect(0, 0, side, side);outerRect.moveCenter(rect().center());painter.save();painter.translate(outerRect.center());painter.rotate(m_angle);// 创建科技感指针形状QPainterPath needlePath;// 主指针needlePath.moveTo(0, -outerRect.height()*0.35);needlePath.lineTo(-outerRect.width()*0.05, -outerRect.height()*0.05);needlePath.lineTo(0, 0);needlePath.lineTo(outerRect.width()*0.05, -outerRect.height()*0.05);needlePath.closeSubpath();// 尾翼needlePath.moveTo(0, outerRect.height()*0.1);needlePath.lineTo(-outerRect.width()*0.03, outerRect.height()*0.2);needlePath.lineTo(0, outerRect.height()*0.25);needlePath.lineTo(outerRect.width()*0.03, outerRect.height()*0.2);needlePath.closeSubpath();// 绘制指针QLinearGradient gradient(0, -outerRect.height()*0.35, 0, outerRect.height()*0.25);gradient.setColorAt(0, m_needleColor.lighter(150));gradient.setColorAt(1, m_needleColor.darker(150));painter.setPen(QPen(m_needleColor.darker(200), side*0.005));painter.setBrush(gradient);painter.drawPath(needlePath);// 绘制中心圆点QRadialGradient centerGradient(0, 0, side*0.05);centerGradient.setColorAt(0, Qt::white);centerGradient.setColorAt(1, m_needleColor);painter.setPen(Qt::NoPen);painter.setBrush(centerGradient);painter.drawEllipse(QRectF(-side*0.05, -side*0.05, side*0.1, side*0.1));painter.restore();
}void Compass::drawTechRing(QPainter &painter)
{int side = qMin(width(), height());QRectF outerRect(0, 0, side, side);outerRect.moveCenter(rect().center());painter.save();painter.translate(outerRect.center());// 绘制外环科技感装饰QPen techPen(m_borderColor);techPen.setWidth(side * 0.01);painter.setPen(techPen);// 绘制分段圆环for (int i = 0; i < 8; ++i) {painter.save();painter.rotate(i * 45);QRectF segmentRect(-side*0.5, -side*0.5, side, side);segmentRect.adjust(side*0.05, side*0.05, -side*0.05, -side*0.05);int startAngle = 10 * 16;int spanAngle = 25 * 16;painter.drawArc(segmentRect, startAngle, spanAngle);painter.restore();}// 绘制内环科技感装饰QRectF innerRingRect(-side*0.3, -side*0.3, side*0.6, side*0.6);techPen.setColor(m_directionColor);techPen.setWidth(side * 0.005);painter.setPen(techPen);painter.setBrush(Qt::NoBrush);painter.drawEllipse(innerRingRect);// 绘制内环点阵for (int i = 0; i < 36; ++i) {painter.save();painter.rotate(i * 10);QPointF point(0, -side*0.25);painter.setPen(Qt::NoPen);painter.setBrush(m_directionColor);painter.drawEllipse(point, side*0.005, side*0.005);painter.restore();}painter.restore();
}

        main.c

#include "widget.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QSlider>
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget window;QVBoxLayout *layout = new QVBoxLayout(&window);// 创建指南针控件Compass *compass = new Compass();compass->setBackgroundColor(QColor(20, 25, 35));compass->setBorderColor(QColor(0, 200, 255));compass->setNeedleColor(QColor(255, 60, 60));compass->setDirectionColor(QColor(0, 255, 180));compass->setTextColor(Qt::white);compass->setBorderWidth(4);// 创建滑块控制方向QSlider *slider = new QSlider(Qt::Horizontal);slider->setRange(0, 360);slider->setValue(0);QObject::connect(slider, &QSlider::valueChanged, [compass](int value) {compass->setAngle(value);});layout->addWidget(compass, 1);layout->addWidget(slider);window.resize(400, 450);window.show();return a.exec();
}

相关文章:

  • 支持selenium的chrome driver更新到136.0.7103.49
  • 打包 Python 项目为 Windows 可执行文件:高效部署指南
  • 33、VS中提示“以下文件中的行尾不一致。是否将行尾标准化?“是什么意思?
  • 【C语言练习】014. 使用数组作为函数参数
  • Java关键字解析
  • Canvas特效实例:黑客帝国-字母矩阵(字母雨)
  • OpenAI最新发布的GPT-4.1系列模型,性能体验如何?
  • 设计模式简述(十四)组合模式
  • Unity SpriteMask(精灵遮罩)
  • Go 语言中一个功能强大且广泛使用的数据验证库github.com/go-playground/validator/v10
  • Js扩展DOM、BOM、AJAX、事件、定时器
  • 系统架构设计师:设计模式概述
  • 为 Unity 项目添加自定义 USB HID 设备支持 (适用于 PC 和 Android/VR)-任何手柄、无人机手柄、摇杆、方向盘
  • 补题( Convolution, 二维卷积求输出矩阵元素和最大值)
  • 华为云Astro大屏连接器创建操作实例:抽取物联网iotda影子设备数据的连接器创建
  • 【中间件】bthread_基础_TaskControl
  • Kotlin革新数据分析
  • linux 使用nginx部署next.js项目,并使用pm2守护进程
  • 信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(六)
  • 快速上手非关系型数据库-MongoDB
  • 长三角铁路今日预计发送旅客420万人次,有望创单日客发量新高
  • 首部关于民营经济发展的基础性法律,有何亮点?专家解读
  • 近七成科创板公司2024年营收增长,285家营收创历史新高
  • 国务院安委办、应急管理部进一步调度部署“五一”假期安全防范工作
  • 平安资管总经理罗水权因个人工作原因辞职
  • 范宇任上海宝山区副区长