QFlightInstruments示例代码及航空仪表的使用(3)

WidgetNAV控件

经过(1)对航空仪表的了解及界面的介绍,(2)对WidgetPFD控件的介绍

本节继续了解下图控件的具体操作:

 WidgetNAV.h

#ifndef WIDGETNAV_H
#define WIDGETNAV_H



#include <QWidget>

#include <qfi_NAV.h>

#include "LayoutSquare.h"



namespace Ui
{
    class WidgetNAV;
}



class WidgetNAV : public QWidget
{
    Q_OBJECT

public:

    explicit WidgetNAV( QWidget *parent = 0 );

    virtual ~WidgetNAV();

    inline void update()
    {
        m_nav->update();
    }

    inline void setHeading( float heading )
    {
        m_nav->setHeading( heading );
    }

    inline void setHeadingBug( float headingBug )
    {
        m_nav->setHeadingBug( headingBug );
    }

    inline void setCourse( float course )
    {
        m_nav->setCourse( course );
    }

    inline void setBearing( float bearing, bool visible = false )
    {
        m_nav->setBearing( bearing, visible );
    }

    inline void setDeviation( float deviation, bool visible = false )
    {
        m_nav->setDeviation( deviation, visible );
    }

    inline void setDistance( float distance, bool visible = false )
    {
        m_nav->setDistance( distance, visible );
    }

private:

    Ui::WidgetNAV *m_ui;
    qfi_NAV       *m_nav;
    LayoutSquare  *m_layoutSq;

    void setupUi();
};



#endif // WIDGETNAV_H

WidgetNAV.cpp

#ifndef WIDGETNAV_CPP
#define WIDGETNAV_CPP
#endif

#include "WidgetNAV.h"
#include "ui_WidgetNAV.h"



WidgetNAV::WidgetNAV( QWidget *parent ) :
    QWidget( parent ),
    m_ui( new Ui::WidgetNAV ),
    m_nav ( 0 ),
    m_layoutSq ( 0 )
{
    m_ui->setupUi( this );

    setupUi();

    m_nav = m_ui->graphicsNAV;
}



WidgetNAV::~WidgetNAV()
{
    if ( m_layoutSq ) delete m_layoutSq; m_layoutSq = 0;

    if ( m_ui ) delete m_ui; m_ui = 0;
}



void WidgetNAV::setupUi()
{
    m_layoutSq = new LayoutSquare( this );

    m_layoutSq->setContentsMargins( 0, 0, 0, 0 );
    m_layoutSq->addWidget( m_ui->frameNAV );

    setLayout( m_layoutSq );
}

qfi_NAV.h

#ifndef QFI_NAV_H
#define QFI_NAV_H



#include <QGraphicsView>
#include <QGraphicsSvgItem>



/** This class provides Navigation Display widget. */
class qfi_NAV : public QGraphicsView
{
    Q_OBJECT

public:

    /** Constructor. */
    explicit qfi_NAV( QWidget *parent = 0 );

    /** Destructor. */
    virtual ~qfi_NAV();

    /** Reinitiates widget. */
    void reinit();

    /** Refreshes (redraws) widget. */
    void update();

    /** @param heading [deg] */
    void setHeading( float heading );

    /** @param heading bug [deg] */
    void setHeadingBug( float headingBug );

    /** @param course [deg] */
    void setCourse( float course );

    /** @param bearing [deg] */
    void setBearing( float bearing, bool visible = false );

    /** @param deviation [-] */
    void setDeviation( float deviation, bool visible = false );

    /** @param distance [nm] */
    void setDistance( float distance, bool visible = false );

protected:

    /** */
    void resizeEvent( QResizeEvent *event );

private:

    QGraphicsScene *m_scene;            ///< graphics scene

    QGraphicsSvgItem *m_itemBack;       ///< NAV background
    QGraphicsSvgItem *m_itemMask;       ///< NAV mask
    QGraphicsSvgItem *m_itemMark;

    QGraphicsSvgItem *m_itemBrgArrow;
    QGraphicsSvgItem *m_itemCrsArrow;
    QGraphicsSvgItem *m_itemDevBar;
    QGraphicsSvgItem *m_itemDevScale;
    QGraphicsSvgItem *m_itemHdgBug;
    QGraphicsSvgItem *m_itemHdgScale;

    QGraphicsTextItem *m_itemCrsText;
    QGraphicsTextItem *m_itemHdgText;
    QGraphicsTextItem *m_itemDmeText;

    QColor m_crsTextColor;
    QColor m_hdgTextColor;
    QColor m_dmeTextColor;

    QFont  m_crsTextFont;
    QFont  m_hdgTextFont;
    QFont  m_dmeTextFont;

    float m_heading;                    ///< [deg]
    float m_headingBug;                 ///< [deg]
    float m_course;
    float m_bearing;
    float m_deviation;
    float m_distance;

    bool m_bearingVisible;
    bool m_deviationVisible;
    bool m_distanceVisible;

    float m_devBarDeltaX_new;
    float m_devBarDeltaX_old;
    float m_devBarDeltaY_new;
    float m_devBarDeltaY_old;

    float m_scaleX; ///<
    float m_scaleY; ///<

    float m_originalPixPerDev;

    QPointF m_originalNavCtr;

    QPointF m_originalCrsTextCtr;
    QPointF m_originalHdgTextCtr;
    QPointF m_originalDmeTextCtr;

    const int m_originalHeight;         ///< [px]
    const int m_originalWidth;          ///< [px]

    const int m_backZ;
    const int m_maskZ;
    const int m_markZ;

    const int m_brgArrowZ;
    const int m_crsArrowZ;
    const int m_crsTextZ;
    const int m_devBarZ;
    const int m_devScaleZ;
    const int m_hdgBugZ;
    const int m_hdgScaleZ;
    const int m_hdgTextZ;
    const int m_dmeTextZ;

    /** */
    void init();

    /** */
    void reset();

    /** */
    void updateView();
};



#endif // QFI_NAV_H

qfi_NAV.cpp

#ifndef QFI_NAV_CPP
#define QFI_NAV_CPP
#endif



#include <iostream>

#ifdef WIN32
#   include <float.h>
#endif

#include <math.h>
#include <stdio.h>

#include "qfi_NAV.h"



qfi_NAV::qfi_NAV( QWidget *parent ) :
    QGraphicsView ( parent ),

    m_scene ( 0 ),

    m_itemBack ( 0 ),
    m_itemMask ( 0 ),
    m_itemMark ( 0 ),

    m_itemBrgArrow ( 0 ),
    m_itemCrsArrow ( 0 ),
    m_itemDevBar   ( 0 ),
    m_itemDevScale ( 0 ),
    m_itemHdgBug   ( 0 ),
    m_itemHdgScale ( 0 ),

    m_itemCrsText ( 0 ),
    m_itemHdgText ( 0 ),
    m_itemDmeText ( 0 ),

    m_crsTextColor (   0, 255,   0 ),
    m_hdgTextColor ( 255,   0, 255 ),
    m_dmeTextColor ( 255, 255, 255 ),

    m_heading    ( 0.0f ),
    m_headingBug ( 0.0f ),
    m_course     ( 0.0f ),
    m_bearing    ( 0.0f ),
    m_deviation  ( 0.0f ),
    m_distance   ( 0.0f ),

    m_bearingVisible   ( true ),
    m_deviationVisible ( true ),
    m_distanceVisible  ( true ),

    m_devBarDeltaX_new ( 0.0f ),
    m_devBarDeltaX_old ( 0.0f ),
    m_devBarDeltaY_new ( 0.0f ),
    m_devBarDeltaY_old ( 0.0f ),

    m_scaleX ( 1.0f ),
    m_scaleY ( 1.0f ),

    m_originalPixPerDev ( 52.5f ),

    m_originalNavCtr ( 150.0f, 150.0f ),

    m_originalCrsTextCtr (  50.0f,  25.0f ),
    m_originalHdgTextCtr ( 250.0f,  25.0f ),
    m_originalDmeTextCtr ( 250.0f, 275.0f ),

    m_originalHeight ( 300 ),
    m_originalWidth  ( 300 ),

    m_backZ (   0 ),
    m_maskZ ( 100 ),
    m_markZ ( 200 ),

    m_brgArrowZ (  60 ),
    m_crsArrowZ (  70 ),
    m_crsTextZ  ( 130 ),
    m_devBarZ   (  50 ),
    m_devScaleZ (  10 ),
    m_hdgBugZ   ( 120 ),
    m_hdgScaleZ ( 110 ),
    m_hdgTextZ  ( 130 ),
    m_dmeTextZ  ( 130 )
{
#   ifdef WIN32
    m_crsTextFont.setFamily( "Courier" );
    m_crsTextFont.setPointSizeF( 12.0f );
    m_crsTextFont.setStretch( QFont::Condensed );
    m_crsTextFont.setWeight( QFont::Bold );

    m_hdgTextFont.setFamily( "Courier" );
    m_hdgTextFont.setPointSizeF( 12.0f );
    m_hdgTextFont.setStretch( QFont::Condensed );
    m_hdgTextFont.setWeight( QFont::Bold );

    m_dmeTextFont.setFamily( "Courier" );
    m_dmeTextFont.setPointSizeF( 10.0f );
    m_dmeTextFont.setStretch( QFont::Condensed );
    m_dmeTextFont.setWeight( QFont::Bold );
#   else
    m_crsTextFont.setFamily( "courier" );
    m_crsTextFont.setPointSizeF( 12.0f );
    m_crsTextFont.setStretch( QFont::Condensed );
    m_crsTextFont.setWeight( QFont::Bold );

    m_hdgTextFont.setFamily( "courier" );
    m_hdgTextFont.setPointSizeF( 12.0f );
    m_hdgTextFont.setStretch( QFont::Condensed );
    m_hdgTextFont.setWeight( QFont::Bold );

    m_dmeTextFont.setFamily( "courier" );
    m_dmeTextFont.setPointSizeF( 10.0f );
    m_dmeTextFont.setStretch( QFont::Condensed );
    m_dmeTextFont.setWeight( QFont::Bold );
#   endif

    reset();

    m_scene = new QGraphicsScene( this );
    setScene( m_scene );

    m_scene->clear();

    init();
}



qfi_NAV::~qfi_NAV()
{
    if ( m_scene )
    {
        m_scene->clear();
        delete m_scene;
        m_scene = 0;
    }

    reset();
}



void qfi_NAV::reinit()
{
    if ( m_scene )
    {
        m_scene->clear();

        init();
    }
}



void qfi_NAV::update()
{
    updateView();

    m_devBarDeltaX_old = m_devBarDeltaX_new;
    m_devBarDeltaY_old = m_devBarDeltaY_new;
}



void qfi_NAV::setHeading( float heading )
{
    m_heading = heading;

    while ( m_heading <   0.0f ) m_heading += 360.0f;
    while ( m_heading > 360.0f ) m_heading -= 360.0f;
}



void qfi_NAV::setHeadingBug( float headingBug )
{
    m_headingBug = headingBug;

    while ( m_headingBug <   0.0f ) m_headingBug += 360.0f;
    while ( m_headingBug > 360.0f ) m_headingBug -= 360.0f;
}



void qfi_NAV::setCourse( float course )
{
    m_course = course;

    while ( m_course <   0.0f ) m_course += 360.0f;
    while ( m_course > 360.0f ) m_course -= 360.0f;
}



void qfi_NAV::setBearing( float bearing, bool visible )
{
    m_bearing        = bearing;
    m_bearingVisible = visible;

    while ( m_bearing <   0.0f ) m_bearing += 360.0f;
    while ( m_bearing > 360.0f ) m_bearing -= 360.0f;
}



void qfi_NAV::setDeviation( float deviation, bool visible )
{
    m_deviation        = deviation;
    m_deviationVisible = visible;

    if ( m_deviation < -1.0f ) m_deviation = -1.0f;
    if ( m_deviation >  1.0f ) m_deviation =  1.0f;
}



void qfi_NAV::setDistance( float distance, bool visible )
{
    m_distance        = fabs( distance );
    m_distanceVisible = visible;
}



void qfi_NAV::resizeEvent( QResizeEvent *event )
{
    
    QGraphicsView::resizeEvent( event );
    

    reinit();
}



void qfi_NAV::init()
{
    m_scaleX = (float)width()  / (float)m_originalWidth;
    m_scaleY = (float)height() / (float)m_originalHeight;

    m_itemBack = new QGraphicsSvgItem( ":/qfi/images/nav/nav_back.svg" );
    m_itemBack->setCacheMode( QGraphicsItem::NoCache );
    m_itemBack->setZValue( m_backZ );
    m_itemBack->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_scene->addItem( m_itemBack );

    m_itemMask = new QGraphicsSvgItem( ":/qfi/images/nav/nav_mask.svg" );
    m_itemMask->setCacheMode( QGraphicsItem::NoCache );
    m_itemMask->setZValue( m_maskZ );
    m_itemMask->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_scene->addItem( m_itemMask );

    m_itemMark = new QGraphicsSvgItem( ":/qfi/images/nav/nav_mark.svg" );
    m_itemMark->setCacheMode( QGraphicsItem::NoCache );
    m_itemMark->setZValue( m_markZ );
    m_itemMark->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_scene->addItem( m_itemMark );

    m_itemBrgArrow = new QGraphicsSvgItem( ":/qfi/images/nav/nav_brg_arrow.svg" );
    m_itemBrgArrow->setCacheMode( QGraphicsItem::NoCache );
    m_itemBrgArrow->setZValue( m_brgArrowZ );
    m_itemBrgArrow->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemBrgArrow->setTransformOriginPoint( m_originalNavCtr );
    m_scene->addItem( m_itemBrgArrow );

    m_itemCrsArrow = new QGraphicsSvgItem( ":/qfi/images/nav/nav_crs_arrow.svg" );
    m_itemCrsArrow->setCacheMode( QGraphicsItem::NoCache );
    m_itemCrsArrow->setZValue( m_crsArrowZ );
    m_itemCrsArrow->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemCrsArrow->setTransformOriginPoint( m_originalNavCtr );
    m_scene->addItem( m_itemCrsArrow );

    m_itemDevBar = new QGraphicsSvgItem( ":/qfi/images/nav/nav_dev_bar.svg" );
    m_itemDevBar->setCacheMode( QGraphicsItem::NoCache );
    m_itemDevBar->setZValue( m_devBarZ );
    m_itemDevBar->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemDevBar->setTransformOriginPoint( m_originalNavCtr );
    m_scene->addItem( m_itemDevBar );

    m_itemDevScale = new QGraphicsSvgItem( ":/qfi/images/nav/nav_dev_scale.svg" );
    m_itemDevScale->setCacheMode( QGraphicsItem::NoCache );
    m_itemDevScale->setZValue( m_devScaleZ );
    m_itemDevScale->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemDevScale->setTransformOriginPoint( m_originalNavCtr );
    m_scene->addItem( m_itemDevScale );

    m_itemHdgBug = new QGraphicsSvgItem( ":/qfi/images/nav/nav_hdg_bug.svg" );
    m_itemHdgBug->setCacheMode( QGraphicsItem::NoCache );
    m_itemHdgBug->setZValue( m_hdgBugZ );
    m_itemHdgBug->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemHdgBug->setTransformOriginPoint( m_originalNavCtr );
    m_scene->addItem( m_itemHdgBug );

    m_itemHdgScale = new QGraphicsSvgItem( ":/qfi/images/nav/nav_hdg_scale.svg" );
    m_itemHdgScale->setCacheMode( QGraphicsItem::NoCache );
    m_itemHdgScale->setZValue( m_hdgScaleZ );
    m_itemHdgScale->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemHdgScale->setTransformOriginPoint( m_originalNavCtr );
    m_scene->addItem( m_itemHdgScale );

    m_itemCrsText = 0;

    m_itemCrsText = new QGraphicsTextItem( QString( "CRS 999" ) );
    m_itemCrsText->setCacheMode( QGraphicsItem::NoCache );
    m_itemCrsText->setZValue( m_crsTextZ );
    m_itemCrsText->setDefaultTextColor( m_crsTextColor );
    m_itemCrsText->setFont( m_crsTextFont );
    m_itemCrsText->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemCrsText->moveBy( m_scaleX * ( m_originalCrsTextCtr.x() - m_itemCrsText->boundingRect().width()  / 2.0f ),
                           m_scaleY * ( m_originalCrsTextCtr.y() - m_itemCrsText->boundingRect().height() / 2.0f ) );
    m_scene->addItem( m_itemCrsText );

    m_itemHdgText = new QGraphicsTextItem( QString( "HDG 999" ) );
    m_itemHdgText->setCacheMode( QGraphicsItem::NoCache );
    m_itemHdgText->setZValue( m_hdgTextZ );
    m_itemHdgText->setDefaultTextColor( m_hdgTextColor );
    m_itemHdgText->setFont( m_hdgTextFont );
    m_itemHdgText->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemHdgText->moveBy( m_scaleX * ( m_originalHdgTextCtr.x() - m_itemHdgText->boundingRect().width()  / 2.0f ),
                           m_scaleY * ( m_originalHdgTextCtr.y() - m_itemHdgText->boundingRect().height() / 2.0f ) );
    m_scene->addItem( m_itemHdgText );

    m_itemDmeText = new QGraphicsTextItem( QString( "99.9 NM" ) );
    m_itemDmeText->setCacheMode( QGraphicsItem::NoCache );
    m_itemDmeText->setZValue( m_dmeTextZ );
    m_itemDmeText->setDefaultTextColor( m_dmeTextColor );
    m_itemDmeText->setFont( m_dmeTextFont );
    m_itemDmeText->setTransform( QTransform::fromScale( m_scaleX, m_scaleY ), true );
    m_itemDmeText->moveBy( m_scaleX * ( m_originalDmeTextCtr.x() - m_itemDmeText->boundingRect().width()  / 2.0f ),
                           m_scaleY * ( m_originalDmeTextCtr.y() - m_itemDmeText->boundingRect().height() / 2.0f ) );
    m_scene->addItem( m_itemDmeText );

    updateView();
}



void qfi_NAV::reset()
{
    m_itemBrgArrow = 0;
    m_itemCrsArrow = 0;
    m_itemDevBar   = 0;
    m_itemDevScale = 0;
    m_itemHdgBug   = 0;
    m_itemHdgScale = 0;

    m_itemCrsText = 0;
    m_itemHdgText = 0;
    m_itemDmeText = 0;

    m_heading    = 0.0f;
    m_headingBug = 0.0f;
    m_course     = 0.0f;
    m_bearing    = 0.0f;
    m_deviation  = 0.0f;
    m_distance   = 0.0f;

    m_bearingVisible   = true;
    m_deviationVisible = true;
    m_distanceVisible  = true;

    m_devBarDeltaX_new = 0.0f;
    m_devBarDeltaX_old = 0.0f;
    m_devBarDeltaY_new = 0.0f;
    m_devBarDeltaY_old = 0.0f;
}



void qfi_NAV::updateView()
{
    m_scaleX = (float)width()  / (float)m_originalWidth;
    m_scaleY = (float)height() / (float)m_originalHeight;

    m_itemCrsArrow->setRotation( -m_heading + m_course );
    m_itemHdgBug->setRotation( -m_heading + m_headingBug );
    m_itemHdgScale->setRotation( -m_heading );

    if ( m_bearingVisible )
    {
        m_itemBrgArrow->setVisible( true );
        m_itemBrgArrow->setRotation( -m_heading + m_bearing );
    }
    else
    {
        m_itemBrgArrow->setVisible( false );
    }

    if ( m_deviationVisible )
    {
        m_itemDevBar->setVisible( true );
        m_itemDevScale->setVisible( true );

        float angle_deg = -m_heading + m_course;
#       ifndef M_PI
        float angle_rad = 3.14159265358979323846 * angle_deg / 180.0f;
#       else
        float angle_rad = M_PI * angle_deg / 180.0f;
#       endif


        float sinAngle = sin( angle_rad );
        float cosAngle = cos( angle_rad );

        m_itemDevBar->setRotation( angle_deg );
        m_itemDevScale->setRotation( angle_deg );

        float delta  = m_originalPixPerDev * m_deviation;

        m_devBarDeltaX_new = m_scaleX * delta * cosAngle;
        m_devBarDeltaY_new = m_scaleY * delta * sinAngle;

        m_itemDevBar->moveBy( m_devBarDeltaX_new - m_devBarDeltaX_old, m_devBarDeltaY_new - m_devBarDeltaY_old );
    }
    else
    {
        m_itemDevBar->setVisible( false );
        m_itemDevScale->setVisible( false );

        m_devBarDeltaX_new = m_devBarDeltaX_old;
        m_devBarDeltaY_new = m_devBarDeltaY_old;
    }

    m_itemCrsText->setPlainText( QString("CRS %1").arg( m_course     , 3, 'f', 0, QChar('0') ) );
    m_itemHdgText->setPlainText( QString("HDG %1").arg( m_headingBug , 3, 'f', 0, QChar('0') ) );

    if ( m_distanceVisible )
    {
        m_itemDmeText->setVisible( true );
        m_itemDmeText->setPlainText( QString("%1 NM").arg( m_distance, 5, 'f', 1, QChar(' ') ) );
    }
    else
    {
        m_itemDmeText->setVisible( false );
    }

    m_scene->update();

    centerOn( width() / 2.0f , height() / 2.0f );
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IIIIIII_II

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值