QPixmap绘制性能问题

时间:2017-12-04 10:19:30

标签: c++ qt qml qpainter qpixmap

我需要重新创建Windows 7主题,其中应用程序窗口标题是透明的,并显示模糊的屏幕内容。我的想法是捕获屏幕内容并在标题中显示模糊。因此我扩展了QQuickPaintedItem。

以下是标题:

class DesktopImage : public QQuickPaintedItem
{
    Q_OBJECT

    Q_PROPERTY(int desktopX READ desktopX WRITE setDesktopX NOTIFY desktopXChanged)
    Q_PROPERTY(int desktopY READ desktopY WRITE setDesktopY NOTIFY desktopYChanged)

public:
    explicit DesktopImage(QQuickItem *parent = nullptr);

    void paint(QPainter *painter) override;

    int desktopX() const;
    void setDesktopX(int desktopX);

    int desktopY() const;
    void setDesktopY(int desktopY);

signals:
    void desktopXChanged();
    void desktopYChanged();

private:
    void grabScreensContent();

private:
    QPixmap mScreensContent;
    int mDesktopX;
    int mDesktopY;

};

grabScreensContent()方法如名称所示。 paint()方法实现如下:

void DesktopImage::paint(QPainter *painter)
{
    QRectF target(0, 0, width(), height());
    QRectF source(mDesktopX, mDesktopY, width(), height());
    painter->drawPixmap(target, mScreensContent, source);
}
在QML方面,我使用如下类型:

DesktopContent {
    id: desktop
    desktopX: window.x
    desktopY: window.y
    width: parent.width
    height: parent.height    
}

如您所见,desktopX(desktopY)属性绑定到窗口x(窗口y)属性,以便当用户移动窗口时,正确获取需要绘制的背景部分。然而,绘图并不像人们预期的那样流畅。结果如下:

Slow pixmap paint

有人可以建议提高绩效吗?

1 个答案:

答案 0 :(得分:2)

renderTarget设置为FramebufferObject来照顾{{3}}。这基本上应该使它像普通QML渲染一样高效,但你可以使用有时候很方便的QPainter

DesktopImage::DesktopImage(QQuickItem *parent)
{
    // this setting is not default
    this->setRenderTarget(QQuickPaintedItem::FramebufferObject);
}

此外,如果您不需要整个屏幕,则只能在有限的屏幕区域内操作。这可能有所帮助,也可能没有帮助,具体取决于平台/实现,但我始终首先限制目标的范围,然后将源定位在其中。低级绘画不一定非常聪明,可能期望整个区域有很多变化。所以我们应该指定最小目标区域并改变它(这种情况就是这样)。

void DesktopImage::paint(QPainter *painter)
{
    QRectF target(mDesktopX, mDesktopY, width(), height()); // now limited
    QRectF source(0, 0, width(), height());                 // now within smaller target
    painter->drawPixmap(target, mScreensContent, source);
}