2015-06-26 32 views
5

Aktualnie przesyłam rozwiązanie typu open-source (Albatross ATM solution http://www.albatross.aero/) z Qt3 na Qt5. Albatross to przeglądarka ruchu lotniczego, która wymaga bardzo dobrych osiągów. Są różne problemy, którymi mogłem zarządzać, ale nie część wyświetlana.Qt: Alternatywa dla BitBlt w Qt5 Windows

Architektura wyświetlania opiera się na poleceniu bitblt, które najpierw kopiuje jedną piksel na inną i ostatecznie kopiuje piksel na ekran.

Oto kod wyświetlacz Qt3 (pracę i wydajnych):

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

Próbowałem zastępując bitblt przez drawPixmap ale wydajność są bardzo złe, ponieważ mam bardzo często, aby wyświetlić ekran.

Oto nowy kod 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(); 
} 
  • dla warstw, istnieją 3 warstwy. Warstwa 0 jest najgłębsza (tło), warstwa 2 jest najwyższa. Ta konfiguracja jest używana w celu upewnienia się, że ruch lotniczy jest zawsze wyświetlany na górze ekranu.

  • Sposób OnDraw losowania, w zależności od warstwy, elementy, które uległy zmianie od czasu ostatniego paintEvent

Q: Czy masz jakiś pomysł, jak mogę poprawić tę metodę paintEvent w celu odzyskać dobre zachowanie i znów mieć dobre wyniki z Qt5?

+0

dlaczego potrzebny był pośredni etap bitmapy? Aby zapewnić przejrzystość? – UmNyobe

+0

@UmNyobe To zawsze przechowuje Pixmap z ostatniej warstwy, aby mieć w pamięci całą zawartość ekranu. W ten sposób unika się rozwiązania polegającego jedynie na zachowaniu elementu ekranu, który się zmienił. Jeśli to rozwiązanie zostało użyte, mogą wystąpić pewne problemy z wyświetlaniem i odświeżaniem między warstwami (np. Wyświetlanie warstwy 1 po warstwie 2 i utrata cennych informacji). Zachowanie zawsze całej warstwy pozwala nam upewnić się, że to, co jest rysowane, jest poprawne. –

Odpowiedz

2

Znalazłem problem tutaj.

drawPixmap/drawImage to najlepsza alternatywa dla bitblt w Qt4/Qt5. Niestety miałem pewne problemy ze skalowaną() metodą QPixmap (używaną w innym kodzie, którego nie pokazano tutaj ...), która zwróciła mi złe wyniki. Musiałem przejść od pixmap.resize() do pixmap.scaled() i tutaj popełniłem błąd.

Zmieniłem go i teraz mam całkiem niezły wynik. Tak więc dla osób takich jak ja, które wciąż się zastanawiają, najlepszą alternatywą w Qt dla Bitblt jest drawPixmap z QPainter.