My QML application (Qt 5.4) is based on a Window
item. The application can be resized by the user. When the application is resized the content of the application is being resized respectively (with onWidthChanged
and onHeightChanged
).
This is all fine.
But to avoid flickering I don't want to update the content of the application while the applicaiton is beeing resized. Is there a possibility in QML to detect when the user is actually resizing the window (holding the mouse button down over the border of the window) and don't recalculate the content before the resize is finished (the mouse button is released)?
to change the height, size or width of (an image, window, etc)
Solution 1. this->SetWindowPos(NULL,0,0,newWidth,newHeight,SWP_NOMOVE | SWP_NOZORDER); This will change the size of the dialog, but you will need to move and resize the control inside the dialog using the same function but with the CWnd of the control.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With