12

我正在学习 QT,我对平移时 QLabel 和 QGraphics 视图的性能差异感到困惑。

我将一个巨大的 36Mpixels (D800) jpeg 文件读入 QLabel 或 QGraphics 对象,并尝试使用 QLabel/Graphics 拖动全尺寸图像。令人惊讶的是,QLabel 提供了非常平滑的移动,而 QGRaphicsView 平移是生涩的。

简化的 QGraphicsView 代码是:

QApplication::setGraphicsSystem("raster");    
...
QGraphicsView  view();
view.setDragMode(QGraphicsView::ScrollHandDrag);
view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
view.setFrameStyle(QFrame::NoFrame);
view.showFullScreen();

QGraphicsPixmapItem *pmItem = new QGraphicsPixmapItem(pixMap);
scene.addItem(pmItem); // only one item in the scene
//view.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); // no difference
view.show();

简化的基于 QLabel 的代码是:

void MyQLabel::mouseMoveEvent(QMouseEvent *event){
    if(_leftButtonPressed) {
            // calculate new {_x, _y} position
            repaint();
        }
    } else super::mouseMoveEvent(event);
}
void MyQLabel::paintEvent(QPaintEvent *aEvent){
    QPainter paint(this);
    paint.drawPixmap(_x, _y, pixMap);
}

... // Somewhere in the code:
MyQLabel _myLabel(NULL);
_myLabel.showFullScreen();
_myLabel.show();

感觉就像 QGraphicsView 跳过了一些位置(快速拖动),而 QLabel 在所有中间图像上绘制。

我想念什么?

谢谢亚历克斯

4

1 回答 1

1

update()很可能,当检测到滚动更改时会调用 QGraphicsView 。当您的标签调用repaint().

不同之处在于update()调度呼叫repaint()和多个快速呼叫update()可能会呼叫repaint()一次。

快速拖动时,您可能会在短时间内注册多个鼠标事件。QGraphicsView 将处理所有这些,并为它们中的每一个调用update(),并且只有在它们全部处理完毕后repaint()才会真正调用它们。repaint()您的标签将为每个鼠标事件强制执行一个。

您的标签可能比图形视图更平滑,但它会消耗更多资源,并且在有限的硬件上,标签将落后于鼠标光标,因为硬件正在尝试处理所有重绘。

于 2021-08-29T09:19:54.950 回答