В настоящее время я портирую решение с открытым исходным кодом (решение Albatross ATM http://www.albatross.aero/) из Qt3 в Qt5.
Альбатрос — зритель воздушного движения, который требует очень хороших выступлений.
Существуют различные проблемы, которыми я смог управлять, но не в части отображения.
Архитектура дисплея опирается на 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);
}
Я пробовал заменить bitblt
от drawPixmap
но производительность очень плохая, так как мне приходится очень часто отображать экран.
Вот новый код 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
Q: Есть ли у вас идеи о том, как я мог бы улучшить это paintEvent
метод, чтобы получить хорошее поведение назад и снова иметь хорошие результаты с Qt5?
Я нашел проблему здесь.
drawPixmap / drawImage является лучшей альтернативой bitblt в Qt4 / Qt5.
К сожалению, у меня были некоторые проблемы с методом scaled () в QPixmap (использованном в другом фрагменте кода, не показанном здесь …), который дал мне плохие результаты. Мне пришлось перейти от pixmap.resize () к pixmap.scaled (), и я здесь сделал ошибку.
Я изменил это, и теперь у меня явно хороший результат. Поэтому для тех, кто, как я, все еще задается вопросом, лучшая альтернатива в Qt для Bitblt — это drawPixmap с QPainter.