模拟扫描卫星/雷达控件开发

最近需要用Qt开发一个带有雷达扫描功能的组件,最后总结一下实现的过程。先贴个图,大神看了请无视。(●'◡'●)

 


                                                                                                                   satellite1                     satellite  

testskywidget.cpp关键代码如下:

void TestSkyWidget::paintEvent(QPaintEvent *)

{
     QPainter painter(this);
     float          topMargin ;
     float          leftMargin;
     float          size;
     float          satelliteSize;
     float          fontSize;

     float          availableWidth    = widgetSize.width ();
     float          availableHeight   = widgetSize.height();

     qreal x = widgetSize.center().x() + (qreal) availableWidth /2 * cos(-m_pieRotate*3.14159/180);
     qreal y = widgetSize.center().y() + (qreal) availableWidth /2 * sin(-m_pieRotate*3.14159/180);
     painter.setPen(QPen(Qt::white));
     painter.drawLine(widgetSize.center(),QPointF(x,y));

      //----//扇形
     QConicalGradient gradient;
     gradient.setCenter(widgetSize.center());
     gradient.setAngle(m_pieRotate + 180); //渐变与旋转方向恰好相反,以扇形相反的边作为渐变角度。
     gradient.setColorAt(0.8,QColor(255,255,255,100)); //从渐变角度开始0.5 - 0.75为扇形区域,由于Int类型计算不精确,将范围扩大到0.4-0.8
     //gradient.setColorAt(0.8,QColor(255,255,255,0));
     gradient.setColorAt(0.4,QColor(255,0,105,100));
     painter.setBrush(QBrush(gradient));
    // painter.setBrush(QBrush(QColor(255,10,100,100)));
     painter.setPen(Qt::NoPen);
     painter.drawPie(widgetSize,m_pieRotate*16,90*16);//添加扫描功能


     //装饰-随机点
     for(int i = 0; i < m_points.count(); ++i)
     {
         int colorAlaph = m_pointsAlapha.at(i);
         painter.setPen(QPen(QColor(255,255,255,colorAlaph),3));
         painter.drawPoint(m_points.at(i));
     }


     if( availableHeight/*height()*/ > availableWidth/*width()*/ )
     {
        size = widgetSize.width() * p_marginScale;
        topMargin   = ( widgetSize.width() - widgetSize.width() * p_marginScale +
              widgetSize.height() - widgetSize.width() ) / 2.0;
        leftMargin  = ( widgetSize.width() - widgetSize.width() * p_marginScale ) / 2.0;

//          widgetSize = QRect(0,(height() - width())/2 ,width(),width());
     }

     else
     {
        size = widgetSize.height() * p_marginScale;
        leftMargin = ( widgetSize.height() - widgetSize.height() * p_marginScale +
              widgetSize.width() - widgetSize.height()) / 2.0;
        topMargin  = ( widgetSize.height() - widgetSize.height() * p_marginScale ) / 2.0;


         //widgetSize = QRect((width() - height())/2 ,0,height(),height());

     }

      satelliteSize = size * p_satScale;
     //satelliteSize = widgetSize/*size*/ * p_satScale;

     painter.setRenderHint(QPainter::Antialiasing, p_antialiased);
     painter.translate( leftMargin, topMargin );
     fontSize = size * p_fontScale;


     painter.setFont(
           QFont( "Arial",
           static_cast< int >( fontSize ) ) );

     // paint the circles
     for( int i=0; i < p_ellipses; i++ )
     {
        float radius = size / 2.0 - i * ( size / ( 2.0  * p_ellipses )  );
        painter.setPen( QPen( p_gridColor, p_gridWidth ) );
        painter.drawEllipse(
              QPoint( size/2.0, size/2.0 ),
              static_cast< int >( radius ),
              static_cast< int >( radius ) );
        if( p_withGridLabels )
        {
           painter.setPen( QPen( p_gridTextColor, p_gridWidth ) );
           painter.drawText( QPoint( size/2.0 + p_textMargin, size/2.0 - ( radius + p_textMargin ) ),
                              QString("%1").arg( i * (90 / p_ellipses ) ) );
        }
     }

     // paint the crosses
     for( int i=0; i < p_crosses; i ++ )
     {
        QLineF line1;
        QLineF line2;
        float angle = static_cast<float>(i) * 90.0 / static_cast<float>(p_crosses);
        line1.setP1( QPoint( size/2.0, size/2.0 ) );
        line1.setLength( size/2.0 );

        QRectF textRect( 0, 0, 4.0 * fontSize, fontSize + 2.0 );

        for( int c = 0; c < 4; c++ )
        {
           line1.setAngle( angle + c*90.0 + 90.0 );
           painter.setPen( QPen( p_gridColor, p_gridWidth ) );
           painter.drawLine( line1 );
           if( p_withGridLabels  )
           {
              painter.setPen( QPen( p_gridTextColor, p_gridWidth ) );
              line2 = QLineF( line1 );
              line2.setLength( size/2.0 + 2.0 * fontSize );
              textRect.moveCenter( line2.p2() );
              if( i > 0 )
                 painter.drawText( textRect, Qt::AlignCenter, QString( "%1").arg( 360.0 - (c*90.0 ) - angle ) );
              else
                 painter.drawText( textRect, Qt::AlignCenter, QString( "N") );
           }
        }
     }

     QBrush innerBrush = QBrush( Qt::SolidPattern );
     //QBrush outerBrush = QBrush( );

     foreach( auto s, satellites )
     {

        // skip invisible satellites
        if(     s.state & SatelliteState::Invisible       ||  // the invisible flag is set

           ( !( s.state & SatelliteState::Visible ) &         // neither visible nor half-visible
             !( s.state & SatelliteState::HalfVisible ) ) ||

           (  s.state & (SatelliteState::Flashing/*|SatelliteState::Flashing1|SatelliteState::Flashing2*/) && flash )    // flashing flag is set and flash is active
           )
           continue;


        float el_s = ( 90 - s.el ) * size / ( 2 * 90.0 );
        QRectF labelRect( 0, 0, s.label.length() * satelliteSize, satelliteSize+2 );

        QPoint satPos( size/2   + sin( s.az * 2 * MY_PI / 360.0 ) * el_s,
                       size/2   - cos( s.az * 2 * MY_PI / 360.0 ) * el_s );

        // define the color's alpha value (0.3 or 1.0)
        QColor innerColor = s.innerColor;
        QColor outerColor = s.outerColor;
        QColor fontColor  = s.fontColor;
        if( s.state & SatelliteState::Visible )
        {
           innerColor.setAlphaF( 1.0 );
           outerColor.setAlphaF( 1.0 );
           fontColor.setAlphaF( 1.0 );
        }
        else
        {
           innerColor.setAlphaF( 0.3 );
           outerColor.setAlphaF( 0.3 );
           fontColor.setAlphaF( 0.3 );
        }

        // paint the inner circle
        innerBrush.setColor( innerColor );
        painter.setBrush( innerBrush );
        if( s.state & SatelliteState::Marked )
           painter.setPen( QPen( outerColor, satelliteSize/4 ) );
        else
           painter.setPen( QPen( p_gridColor, 0 ) );
        painter.drawEllipse(
              satPos,
              static_cast< int >( satelliteSize ),
              static_cast< int >( satelliteSize ) );


        // write the text
        painter.setPen( QPen( fontColor, 1 ) );
        painter.setFont(
              QFont( "Arial",
              static_cast< int >( satelliteSize ),
              QFont::Bold ) );
        labelRect.moveCenter( satPos );
        painter.drawText( labelRect, Qt::AlignCenter, s.label );

     }

}

void TestSkyWidget::insert(
                        int id,
                        float az,
                        float el,
                        const QString & label,
                        const QColor & outerColor,
                        const QColor & innerColor,
                        const QColor & fontColor,
                        SatelliteState  state )
{
   Satellite   sat;
   sat.label      = label;
   sat.az         = az;
   sat.el         = el;
   sat.state      = state;
   sat.innerColor = innerColor;
   sat.outerColor = outerColor;
   sat.fontColor  = fontColor;

   this->update();

   satellites.insert( id, sat );
}

//
void TestSkyWidget::remove( int id )
{
   satellites.remove( id );
}

//
bool TestSkyWidget::contains( int id ) const
{
    return satellites.contains( id );
}

//
QColor TestSkyWidget::innerColor( int id ) const
{
   return satellites[ id ].innerColor;
}
//
QColor TestSkyWidget::outerColor( int id ) const
{
   return satellites[ id ].outerColor;
}

QColor TestSkyWidget::fontColor( int id ) const
{
   return satellites[ id ].fontColor;
}
//
void  TestSkyWidget::setInnerColor( int id, const QColor & c )
{
   satellites[ id ].innerColor = c;
   this->update();
}
//
void TestSkyWidget::setOuterColor( int id, const QColor & c )
{
   satellites[ id ].outerColor = c;
}
//
void TestSkyWidget::setFontColor( int id, const QColor & c )
{
   satellites[ id ].fontColor = c;
}
//
TestSkyWidget::SatelliteState TestSkyWidget::state( int id ) const
{
   return satellites[ id ].state;
}
//
void  TestSkyWidget::setState( int id, SatelliteState state )
{
   satellites[ id ].state = state;
   this->update();
}

//
QString TestSkyWidget::label( int id ) const
{
   return satellites[ id ].label;
}
//
void TestSkyWidget::setLabel( int id, const QString & label )
{
   satellites[ id ].label = label;
   this->update();
}


float TestSkyWidget::azimuth( int id ) const
{
   return satellites[ id ].az;
}

float TestSkyWidget::elevation( int id ) const
{
   return satellites[ id ].el;
}

void TestSkyWidget::setAzimuth( int id, float az )
{
   satellites[ id ].az = az;
   this->update();
}

void TestSkyWidget::setElevation( int id, float el )
{
   satellites[ id ].el = el;
   this->update();
}

QList<int> TestSkyWidget::ids( void ) const
{
   return satellites.keys();
}


TestSkyWidget::SatelliteState operator|
(
      TestSkyWidget::SatelliteState lhs,
      TestSkyWidget::SatelliteState rhs
)
{
   return static_cast< TestSkyWidget::SatelliteState >
           (
               static_cast< quint8 >( lhs ) | static_cast< quint8 >( rhs )
           );
}
//定时器事件
void TestSkyWidget::timerEvent(QTimerEvent *event)
{
    if(m_timerId == event->timerId())
    {
        m_pieRotate -= 10;
        update();
    }
    else if(m_pointTimerId == event->timerId())
    {
        //随机更换装饰的点
        for(int i = 0; i < m_points.count(); ++i)
        {
            int offsetX = rand()%widgetSize.width();
            int offsetY = rand()%widgetSize.width();
            int alapha = rand()%255;
            m_points.replace(i,QPoint(offsetX,offsetY) + widgetSize.topLeft());
            m_pointsAlapha.replace(i,alapha);
        }

        update();
    }
}
//尺寸
void TestSkyWidget::resizeEvent(QResizeEvent *)
{
    if(width() > height())
    {
        widgetSize = QRect((width() - height())/1000 ,0,height(),height());
    }
    else
    {
        widgetSize = QRect(0,(height() - width())/1000 ,width(),width());
    }

    //widgetSize.adjust(10,10,-10,-10);
    //widgetSize.adjust(5,5,-10,-10);

}
posted @ 2017-11-24 21:21  云很淡,风很清  阅读(1758)  评论(0编辑  收藏  举报