2015-06-26 18 views
5

Attualmente sto eseguendo il porting di una soluzione open source (soluzione ATM Albatross http://www.albatross.aero/) da Qt3 a Qt5. Albatross è un visualizzatore del traffico aereo che richiede prestazioni molto buone. Ci sono vari problemi che sono stato in grado di gestire ma non la parte di visualizzazione.Qt: alternativa a BitBlt in Windows Qt5

L'architettura di visualizzazione si basa su un comando bitblt che copia innanzitutto una pixmap in un'altra e infine copia la pixmap sullo schermo.

Ecco il codice di visualizzazione Qt3 (lavoro e performante):

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); 
} 

Ho provato a sostituire bitblt dal drawPixmap ma le prestazioni sono molto male dal momento che ho per visualizzare molto spesso lo schermo.

Ecco il nuovo codice 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(); 
} 
  • per gli strati, ci sono 3 strati. Il livello 0 è il più profondo (sfondo), il livello 2 è il più alto. Questa configurazione viene utilizzata per garantire che il traffico aereo venga sempre visualizzato nella parte superiore dello schermo.

  • Il metodo OnDraw attinge, a seconda del livello, gli elementi che sono stati modificati dopo l'ultimo paintEvent

Q: Avete qualche idea su come potrei migliorare questo metodo paintEvent al fine di ottenere un buon comportamento indietro e avere buone prestazioni di nuovo con Qt5?

+0

perché era necessario il passaggio di bitmap intermedio? Per fornire trasparenza? – UmNyobe

+0

@UmNyobe Questo memorizza sempre la Pixmap dell'ultimo strato per avere in memoria l'intero contenuto dello schermo. Ciò evita che la soluzione mantenga solo l'elemento dello schermo modificato. Se questa soluzione è stata utilizzata, potrebbero esserci problemi di visualizzazione e di aggiornamento tra i livelli (ad esempio, visualizzare il livello 1 dopo il livello 2 e perdere informazioni preziose). Mantenere sempre l'intero livello ci consente di essere sicuri che ciò che viene disegnato è corretto. –

risposta

2

Ho trovato il problema qui.

drawPixmap/drawImage è la migliore alternativa al bitblt in Qt4/Qt5. Purtroppo ho avuto alcuni problemi con il metodo ridimensionato() di QPixmap (usato in un altro pezzo di codice non mostrato qui ...) che mi ha restituito risultati negativi. Dovevo andare da pixmap.resize() a pixmap.scaled() e ho fatto un errore qui.

L'ho modificato e ora ho chiaramente un buon risultato. Quindi per quelli come me che si stanno ancora chiedendo, la migliore alternativa in Qt per Bitblt è drawPixmap con un QPainter.