【发布时间】:2015-09-13 02:32:14
【问题描述】:
我目前正在将一个开源解决方案(Albatross ATM 解决方案http://www.albatross.aero/)从 Qt3 移植到 Qt5。 Albatross 是一个空中交通查看器,需要非常好的性能。 我已经能够处理各种问题,但不是显示部分。
显示架构依赖于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);
}
我尝试用drawPixmap 替换bitblt,但性能很差,因为我必须经常显示屏幕。
这是新的 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 以来发生变化的元素
问:你有什么想法可以改进这个paintEvent 方法,以便在 Qt5 中恢复良好的行为并再次获得良好的性能?
【问题讨论】:
-
为什么需要中间位图 blit 步骤?提供透明度?
-
@UmNyobe 这总是存储最后一层的像素图,以便将整个屏幕内容保存在内存中。这避免了仅保留已更改的屏幕元素的解决方案。如果使用此解决方案,图层之间可能会出现一些显示和刷新问题(例如,在图层 2 之后显示图层 1 并丢失宝贵的信息)。始终保持整个图层可以让我们确保绘制的内容是正确的。