В настоящее время я переношу решение с открытым исходным кодом (решение ATM Albatross http://www.albatross.aero/) от Qt3 до Qt5. Albatross - просмотрщик воздушного движения, который требует очень хороших характеристик. Существуют различные проблемы, с которыми мне удалось управлять, но не часть дисплея.Qt: Альтернатива BitBlt в Qt5 Windows
Архитектура дисплея опирается на команду bitblt
, которая сначала копирует одну карту pixmap в другую и, наконец, копирует pixmap на экран.
Вот код отображения 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
метод для того, чтобы geta хорошее поведение назад и хорошие результаты снова с Qt5?
Почему для промежуточного растрового шага необходим промежуточный шаг? Обеспечить прозрачность? – UmNyobe
@UmNyobe Это всегда сохраняет Pixmap последнего слоя, чтобы иметь в памяти весь экранный контент. Это позволяет избежать изменения только того, что изменился элемент экрана. Если это решение было использовано, могут возникать проблемы с отображением и обновлением между слоями (например, отображать слой 1 после слоя 2 и потерять ценную информацию). Сохранение всегда всего слоя позволяет нам быть уверенным, что то, что рисуется, является правильным. –