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?
perché era necessario il passaggio di bitmap intermedio? Per fornire trasparenza? – UmNyobe
@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. –