6

現在、オープンソース ソリューション (Albatross ATM ソリューションhttp://www.albatross.aero/ ) を Qt3 から Qt5 に移植しています。Albatross は、非常に優れたパフォーマンスを必要とする航空交通ビューアーです。私は管理できましたが、表示部分ではないさまざまな問題があります。

表示アーキテクチャは、bitblt最初にピックスマップを別のピックスマップにコピーし、最後にピックスマップを画面にコピーするコマンドに基づいています。

これがQt3ディスプレイコードです(動作およびパフォーマンス)

void CAsdView::paintEvent ( QPaintEvent * Event)
{
    QRect   rcBounds=Event->rect();

    QPainter tmp;

    for (int lay=0;lay<(int)m_RectTable.size();lay++) //For each drawing layer (there are 3) 
    {

        if (!m_RectTable[lay].isEmpty())
        {
            if (lay!=0)
                bitBlt(m_BitmapTable[lay],m_RectTable[lay].left(),m_RectTable[lay].top(),m_BitmapTable[lay-1],m_RectTable[lay].left(),m_RectTable[lay].top(),m_RectTable[lay].width(),m_RectTable[lay].height(),CopyROP); //m_BitmapTable is a QVector< QPixmap* >, m_RectTable is a QVector<QRect>

            tmp.begin(m_BitmapTable[lay]);

            if (lay==0)
                tmp.fillRect(m_RectTable[lay], *m_pBrush);

            OnDraw(&tmp,lay);
            tmp.end();
            m_RectTable[lay].setRect(0,0,-1,-1);
        }
    }
    bitBlt(this, rcBounds.left(), rcBounds.top(),m_BitmapTable[m_LayerNb-1],rcBounds.left(), rcBounds.top(),rcBounds.width(), rcBounds.height(), CopyROP);  
}

に置き換えてみましbitbltdrawPixmapが、画面を頻繁に表示する必要があるため、パフォーマンスが非常に悪いです。

新しい Qt5 コードは次のとおりです。

void CAsdView::paintEvent ( QPaintEvent * Event)
{
    QRect   rcBounds=Event->rect();
    QPainter tmp;

    for (int lay=0;lay<(int)m_RectTable.size();lay++)
    {
        if (!m_RectTable.at(lay).isEmpty())
        {       
            tmp2.begin(m_BitmapTable[lay]);

            if (lay != 0)
            {
                tmp.drawPixmap(m_RectTable[lay].left(), m_RectTable[lay].top(), *m_BitmapTable.at(lay - 1), m_RectTable[lay].left(), m_RectTable[lay].top(), m_RectTable[lay].width(), m_RectTable[lay].height());//TOCHECK
                m_BitmapTable[lay] = m_BitmapTable[lay - 1].copy(m_RectTable[lay]);
            }

            if (lay==0)
                tmp.fillRect(m_RectTable.at(lay), *m_pBrush);

            OnDraw(&tmp, lay);
            tmp.end();
            m_RectTable[lay].setRect(0, 0, -1, -1);
        }
    }
    tmp.begin(this);
    tmp.drawPixmap(rcBounds.left(), rcBounds.top(), m_BitmapTable.at(m_LayerNb - 1), rcBounds.left(), rcBounds.top(), rcBounds.width(), rcBounds.height()); 
    tmp.end();
}
  • レイヤーには、3 つのレイヤーがあります。レイヤ 0 が最も深く (背景)、レイヤ 2 が最も高くなります。この設定は、航空交通が常に画面の一番上に表示されるようにするために使用されます。

  • OnDraw メソッドは、レイヤに応じて、最後の paintEvent 以降に変更された要素を描画します

paintEventQ: Qt5 で良好な動作を取り戻し、再び良好なパフォーマンスを得るために、この方法を改善する方法について何か考えはありますか?

4

1 に答える 1

4

ここで問題を見つけました。

drawPixmap/drawImage は明らかに、Qt4/Qt5 の bitblt の最良の代替手段です。残念ながら、QPixmap の scaled() メソッド (ここには示されていない別のコードで使用されています...) に問題があり、悪い結果が返されました。pixmap.resize() から pixmap.scaled() に移動する必要があり、ここで間違いを犯しました。

私はそれを変更しましたが、今では明らかにかなり良い結果が得られています。私のようにまだ疑問に思っている人にとっては、Bitblt の Qt での最良の代替手段は、QPainter を使用した drawPixmap です。

于 2015-07-01T09:27:04.930 に答える