我需要重新创建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)属性,以便当用户移动窗口时,正确获取需要绘制的背景部分。然而,绘图并不像人们预期的那样流畅。结果如下:
有人可以建议提高绩效吗?
答案 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);
}