Ich portiere derzeit eine Open-Source-Lösung (Albatross ATM Lösung http://www.albatross.aero/) von Qt3 zu Qt5. Albatross ist ein Luftverkehrszuschauer, der sehr gute Leistungen verlangt. Es gibt verschiedene Probleme, die ich habe verwalten können, aber nicht den Anzeigeteil.Qt: Alternative zu BitBlt in Qt5 Windows
Die Anzeigearchitektur basiert auf einem Befehl bitblt
, der zuerst eine Pixmap in eine andere kopiert und schließlich die Pixmap auf den Bildschirm kopiert.
Hier ist der Qt3 Anzeigecode (Arbeits- und performant):
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);
}
ich versucht habe bitblt
durch drawPixmap
ersetzen, aber die Leistung ist sehr schlecht, da ich sehr oft den Bildschirm anzuzeigen habe.
Hier ist der neue QT5-Code ist:
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();
}
Für die Schichten gibt es 3 Schichten. Die Schicht 0 ist der tiefste (Hintergrund), die Schicht 2 ist die höchste. Diese Konfiguration wird verwendet, um sicherzustellen, dass der Flugverkehr immer oben auf dem Bildschirm angezeigt wird.
Die OnDraw-Methode zeichnet, die auf der Schicht abhängig, die Elemente, die
Q seit dem letzten paintEventO geändert haben: Haben Sie eine Idee, wie ich dieses paintEvent
Verfahren zu verbessern, könnte Gutes Verhalten zurückbekommen und wieder gute Leistungen mit Qt5?
Warum war der Zwischenbitmap-Schritt erforderlich? Um Transparenz zu schaffen? – UmNyobe
@UmNyobe Dies speichert immer die Pixmap der letzten Ebene, um den gesamten Bildschirminhalt im Speicher zu haben. Dies vermeidet die Lösung, nur das Element des Bildschirms zu behalten, das sich geändert hat. Wenn diese Lösung verwendet würde, könnte es einige Anzeige- und Aktualisierungsprobleme zwischen den Schichten geben (z. B. die Schicht 1 nach der Schicht 2 anzeigen und wertvolle Information verlieren). Indem wir immer die gesamte Ebene beibehalten, können wir sicher sein, dass das, was gezeichnet wird, korrekt ist. –