EDYCJA: To, co zaproponował Kuba Ober, jest nieskończenie prostsze i bardziej niezawodne. Wciąż pozostawiam tutaj odpowiedź, ponieważ uznałem ją za dość interesującą (a podejście komponentu niestandardowego C++ można zmodyfikować, aby filtrować zdarzenia okna zgodnie z sugestią).
Wybacz ale ja napisałem szybki i brzydki hack, aby zobaczyć, czy to możliwe, że obejmuje tylko drugą część pytania (nie aktualizowanie zawartości). Moje rozwiązanie blokuje ponowne malowanie elementu, ale także ukrywa je, gdy tylko zażąda aktualizacji (co może nie być dla ciebie problemem).
Po zapoznaniu się z dokumentacją QQuickItem::updatePaintNode a zwłaszcza tę frazę
funkcja jest wywoływana w wyniku QQuickItem :: update(), jeśli użytkownik ustawił flagę QQuickItem :: ItemHasContents na przedmiocie.
Stworzyłem klasę C++ do włączony/wyłączony tę flagę na 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
Następnym krokiem jest zarejestrowanie tej klasy tak, że może on być stosowany w QML:
qmlRegisterType<ItemUpdateBlocker>("com.mycompany.qmlcomponents", 1, 0, "ItemUpdateBlocker");
I można go używać w QML tak:
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
}
}
}
}
Możesz oczywiście dodać blokerowi właściwość active
, aby uprościć jego użycie (ładniejsza niż użycie wartości zerowej target
, aby ją wyłączyć), ale zostawię to jako ćwiczenie.
Może można z tego skorzystać, gdy licznik czasu zostanie uruchomiony, gdy zmieni się szerokość lub wysokość Window
, jeszcze nie znalazłem bezpośredniego sposobu na sprawdzenie, czy rozmiar okna został zmieniony.
Filtruj odpowiednie zdarzenia, dopóki przycisk myszy nie zostanie zwolniony. W szczególności "zjedz" zdarzenie zmiany rozmiaru, gdy przycisk myszy jest wciśnięty, a następnie syntezuje końcowe zdarzenie zmiany rozmiaru po zwolnieniu myszy. Możesz zrobić to wszystko w filtrze zdarzeń dołączonym do obiektu okna/widgetu, który wyświetla twój interfejs QML. –
Próbowałem tego i działa, ale problem polega na tym, że nie masz naciśnięcia przycisku myszy lub wydania wydania podczas zmiany rozmiaru okna, a 'QGuiApplication :: mouseButtons' zwraca, że nie są naciskane żadne przyciski. – GrecKo