2010-10-24 28 views
1

J'ai un QGraphicsItem (en fait, un QDeclarativeItem) et je veux qu'il occupe tout l'espace visible du QGraphicsView (encore une fois, c'est en fait le classe QDeclarativeView dérivée) à laquelle il a été ajouté. Normalement, vous pouvez utiliser QDeclarativeView::setResizeMode(QDeclarativeView::SizeRootObjectToView) et QDeclarativeView redimensionnera automatiquement l'objet racine pour qu'il corresponde à la vue.Redimensionnement d'un QGraphicsItem pour prendre tout l'espace dans un QGraphicsView, problèmes lorsque la fenêtre est redimensionnée

Le problème que je vais avoir est que je suis en train de créer manuellement le widget racine à l'aide

QDeclarativeComponent component(declarativeView->engine(), QUrl(qml)); 
QDeclarativeItem* object = qobject_cast<QDeclarativeItem*>(component.create()); 
if (object) 
{ 
    declarativeView->scene()->addItem(object); 
    ... 

au lieu de laisser QDeclarativeView le faire automatiquement en appelant setSource(). La raison pour laquelle je fais cela est parce que je veux échanger la scène QML lorsque certains événements se produisent, mais je ne veux pas détruire la scène précédente. L'appel setSource() supprime tous les éléments qui ont été ajoutés avant l'appel de setSource(). Donc, je crée moi-même l '"objet racine" et je l'ajoute manuellement à la scène.

J'utilise les fenêtres resizeEvent pour redimensionner mon QDeclarativeItem, comme ceci:

void AppWindow::resizeEvent (QResizeEvent* event) 
{ 
    QDeclarativeItem* object = sceneCache.value(sceneName, 0); 
    if (object) 
    { 
     object->setWidth(declarativeView->viewport()->width()); 
     object->setHeight(declarativeView->viewport()->height()); 
    } 
} 

Cela ne fonctionne! Mais, ce n'est pas très joli. Si vous redimensionnez rapidement la fenêtre, le QDeclarativeItem n'est pas redimensionné assez rapidement et vous voyez brièvement un arrière-plan gris avant de le rattraper et de le redimensionner. C'est aussi pas très lisse. Cela ne se produit que si un élément complexe est redimensionné (dans mon cas, il s'agit d'un widget QWebKit). Cela fonctionne bien pour les éléments plus simples. La chose est, cependant, que si je laisse QDeclarativeView le faire, je n'ai aucun de ces problèmes: son redimensionnement correctement et en douceur. J'imagine que ce n'est pas spécifique au QtDeclarative, mais plutôt QGraphicsView, même si je me trompe peut-être là-bas.

Quelqu'un a-t-il des idées?

Répondre

3

J'ai résolu mes problèmes.

Le problème semble provenir de l'élément WebView de QML. Je l'ai changé pour un QGraphicsProxyWidget enregistré à partir de C++, avec le widget défini sur un QWebView normal et tous les problèmes disparaissent. Il se comporte maintenant exactement comment je m'attendais à ce que le WebView se comporte. L'inconvénient est que j'ai besoin d'exposer manuellement les signaux/slots/propriétés QWebView à QML. (EDIT: J'ai résolu ceci en ayant une propriété en lecture seule appelée object, qui retourne le widget set.Quand les QObjects sont automagiquement convertis en objets javascript accessibles, je peux accéder à la vue web, par exemple, comme ceci: object.url = 'http://google.com'. commodité, j'appelle également une fonction init javascript sur l'objet QML, si elle existe, donc je mets simplement la vue web là-haut - fonctionne super!)

Un autre changement que j'ai fait depuis que j'ai posé la question est de déplacer le " objet racine "passage de C++ dans QML lui-même, en créant un Rectangle en plein écran avec une fonction javascript compatible C++ qui utilise Qt.createComponent() pour charger le fichier QML" réel "et l'ancrer avec anchors.fill.De cette façon la logique (et la mise en cache des objets) est faite en QML, au lieu de C++, donc je peux simplement définir SetSource(), laisser Qt gérer le redimensionnement et autres et je travaille uniquement en QML (pour cette partie de l'application).

3

Je ne sais pas si cela va se débarrasser de la vacillante, mais vous pouvez utiliser fitInView dans votre resizeEvent():

declarativeView->fitInView(object, Qt::IgnoreAspectRatio); 
+0

Merci pour cela, il semble que j'ai raté cette fonction. – Dan

+0

Cela a fonctionné, bien que je ne sais pas pourquoi le contenu est centré dans la vue montrant une partie minimale de la couleur d'arrière-plan (blanc) semblable à une bordure blanche. Des indices? – emanuelcds