2015-03-20 20 views
6

La mia applicazione QML (Qt 5.4) si basa su un elemento Window. L'applicazione può essere ridimensionata dall'utente. Quando l'applicazione viene ridimensionata, il contenuto dell'applicazione viene ridimensionato rispettivamente (con onWidthChanged e onHeightChanged).Non ridisegnare la finestra durante il ridimensionamento

Questo va tutto bene.

Tuttavia, per evitare lo sfarfallio, non desidero aggiornare il contenuto dell'applicazione mentre viene ridimensionata l'applicazione. Esiste la possibilità in QML di rilevare quando l'utente sta effettivamente ridimensionando la finestra (tenendo premuto il pulsante del mouse sul bordo della finestra) e non ricalcolare il contenuto prima che il ridimensionamento sia terminato (il pulsante del mouse viene rilasciato)?

+5

Filtra gli eventi rilevanti fino a quando il pulsante del mouse non è stato rilasciato. In particolare, "mangia" l'evento di ridimensionamento mentre il pulsante del mouse viene tenuto premuto, quindi sintetizza l'evento di ridimensionamento finale una volta rilasciato il mouse. È possibile eseguire tutto in un filtro eventi collegato all'oggetto finestra/widget che visualizza l'interfaccia QML. –

+0

Ho provato questo e funziona, ma il problema è che non si preme mouse press o rilascio evento durante il ridimensionamento della finestra, e 'QGuiApplication :: mouseButtons' restituisce che non viene premuto alcun pulsante. – GrecKo

risposta

1

MODIFICA: Ciò che Kuba Ober ha suggerito è infinitamente più semplice e più robusto, lascerò comunque la mia risposta qui perché l'ho trovato piuttosto interessante (e l'approccio del componente personalizzato C++ può essere modificato per filtrare gli eventi della finestra come suggerito).


Mi perdoni, ma ho scritto un hack rapido e brutta per vedere se era possibile, copre solo la seconda parte della tua domanda (non aggiornare il contenuto). La mia soluzione blocca la ridipintura di un oggetto, ma lo nasconde non appena viene richiesto un aggiornamento (che potrebbe non essere un problema per te).

Dopo aver letto la documentazione QQuickItem::updatePaintNode e soprattutto questa frase

La funzione viene chiamata a seguito di QQuickItem :: update(), se l'utente ha impostato il flag QQuickItem :: ItemHasContents sulla voce.

Ho creato una classe C++ per attivare/disattivare questo flag su un QQuickItem abitrary:

#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 

passo successivo consiste nel registrare questa classe in modo che possa essere utilizzato in QML:

qmlRegisterType<ItemUpdateBlocker>("com.mycompany.qmlcomponents", 1, 0, "ItemUpdateBlocker"); 

E lo si può utilizzare in QML come questo:

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 
      } 
     } 
    } 
} 

Ovviamente è possibile aggiungere una proprietà active al blocco per semplificarne l'uso (più carina dell'utilizzo di un valore target nullo per disattivarla), ma la lascerò come esercizio.

Forse è possibile utilizzarlo con un timer avviato ogni volta che la larghezza o l'altezza del tuo Window viene modificata, non ho ancora trovato un modo diretto per trovare se una finestra viene ridimensionata.