EDIT : What Kuba Ober suggested is infinitely simpler and more robust, I'll still leave my answer here as I found it somewhat interesting (and the C++ custom component approach can be modified to filter the window events as suggested).
Pardon me but I have written a quick and ugly hack to see if it was possible, it only covers the second part of your question (not updating the content).
My solution blocks the repainting of an Item, but also hide it as soon as an update is requested on it (which may not be a problem for you).
After reading the QQuickItem::updatePaintNode documentation and especially this phrase
The function is called as a result of QQuickItem::update(), if the user has set the QQuickItem::ItemHasContents flag on the item.
I created a C++ class to set/unset this flag on an abitrary QQuickItem :
#ifndef ITEMUPDATEBLOCKER_H
#define ITEMUPDATEBLOCKER_H
#include <QObject>
#include <QQuickItem>
class ItemUpdateBlocker : public QObject
{
Q_OBJECT
Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
QQuickItem* m_target;
public:
explicit ItemUpdateBlocker(QObject *parent = 0) : QObject(parent), m_target(nullptr) { }
QQuickItem* target() const { return m_target; }
signals:
void targetChanged();
private:
static void blockUpdate(QQuickItem* target)
{
if (target)
target->setFlag(QQuickItem::ItemHasContents, false);
}
static void unblockUpdate(QQuickItem* target)
{
if (target)
{
target->setFlag(QQuickItem::ItemHasContents, true);
target->update();
}
}
public slots:
void setTarget(QQuickItem* target)
{
if (m_target == target)
return;
unblockUpdate(m_target);
blockUpdate(target);
m_target = target;
emit targetChanged();
}
};
#endif // ITEMUPDATEBLOCKER_H
next step is to register this class so that it can be used in QML :
qmlRegisterType<ItemUpdateBlocker>("com.mycompany.qmlcomponents", 1, 0, "ItemUpdateBlocker");
And you can use it in QML like this :
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import com.mycompany.qmlcomponents 1.0
ApplicationWindow {
width: 640
height: 480
visible: true
Rectangle {
color: "red"
id: root
anchors.fill: parent
Text {
text: blocker.target ? "Blocked" : "Not Blocked"
}
Rectangle {
color: "white"
anchors.centerIn: parent
width: parent.width/2
height: parent.height/2
ItemUpdateBlocker {
id: blocker;
}
MouseArea {
anchors.fill: parent
onClicked: blocker.target = blocker.target ? null : parent
}
}
}
}
You can of course add an active
property to the blocker to simplify it's use (prettier than using a null target
to disable it), but I'll leave that as an exercise.
Maybe you can use that with a timer started whenever the width or the height of your Window
is changed, I have not yet found a direct way to find if a window is resized.