2015-03-20 29 views
6

Moja aplikacja QML (Qt 5.4) oparta jest na pozycji Window. Aplikacja może zmieniać rozmiar przez użytkownika. Gdy rozmiar aplikacji jest zmieniany, zawartość aplikacji zmienia się odpowiednio (z onWidthChanged i onHeightChanged).Nie odświeżaj okna podczas zmiany rozmiaru

To wszystko w porządku.

Aby uniknąć migotania, nie chcę aktualizować zawartości aplikacji podczas zmiany rozmiaru aplikacji. Czy w QML istnieje możliwość wykrycia, kiedy użytkownik zmienia rozmiar okna (przytrzymanie przycisku myszy nad krawędzią okna) i nie dokonuje ponownego obliczenia zawartości przed zakończeniem zmiany rozmiaru (przycisk myszy jest zwolniony)?

+5

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. –

+0

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

Odpowiedz

1

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.