IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

(Bug Qt ?) Bouton de la souris non détecté lors du redimensionnement d'une fenêtre


Sujet :

Qt

  1. #1
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut (Bug Qt ?) Bouton de la souris non détecté lors du redimensionnement d'une fenêtre


    Lors d'un redimensionnement d'une fenêtre par l'utilisateur aucun bouton de la souris n'est détectée.

    La fonction QApplication::mouseButtons() que appellée lors du resize d'un des widget retourne Qt::NoButton alors qu'elle devrait au moins retourner Qt::LeftButton.

    Ce n'est pas normal ??

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour TaZStars

    Un peu de code peu toujours aider à comprendre le problème...

    Je n'utilise pas cette fonction (on préfère en général gérer la souris avec des QMouseEvent : http://qt.developpez.com/doc/latest/qmouseevent.html) mais en lisant la doc, j'interprète de cette façon :
    - QApplication::mouseButtons() est mis à jour à chaque QEvent::MouseButtonPress and QEvent::MouseButtonRelease (http://qt.developpez.com/doc/latest/...l#mouseButtons)
    - Les QEvent::Mouse sont détectés par les widgets (comportement par défaut)
    - Le redimensionment de la fenêtre est pris en charge (par défaut) par l'OS et pas par un widget Qt

    donc pas de QEvent::Mouse émis et donc QApplication::mouseButtons() retourne Qt::NoButton

    Que souhaites-tu faire exactement ?

  3. #3
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Je me doutais bien qu'il y avait une explication rationnelle mais je trouve ça dommage de ne pas connaître l'état de la souris à tout moment.

    Dans mon cas, je souhaitais détecter la fin du resize de la fenêtre afin de mettre à jour le widget central dont je souhaite fixer la résolution.

    Ceci fait suite à cette discussion:
    http://www.developpez.net/forums/d92...ets-adjacents/

    J'ai désormais une fonction qui fixe la résolution du widget central tout en conservant la taille des dock widgets. C'est la MainWindow qui s'adapte à son widget central et non l'inverse (pour les raisons évoquées dans le thread) L'utilisateur choisit entre divers résolutions de la fenêtre de rendu. Cependant, lors qu'il retaille les fenêtres (MainWindow ou dock widgets), il perd la résolution qu'il a choisit. Donc j'ai ajouté une option "Lock resolution" et je voudrais détecter un événement OnEndResizing pour appeler la dite fonction.

    Pour ce faire j'ai installé un event filter sur le widget central dans le constructeur de la MainWindow
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ui->_Renderer->installEventFilter(this); // this = MainWindow
    Je filtre les événements
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bool MainWindow::eventFilter(QObject* obj, QEvent* e)
    {
      if ((obj == ui->_Renderer) && (e->type() == QEvent::Resize))
        return OnRendererResized(e);      
      return QMainWindow::eventFilter(obj, e);
    }
    Traitement de l'événement resize de la fenêtre de rendu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    bool MainWindow::OnRendererResized(QEvent* resizeEvent)
    {
      Qt::MouseButtons m = QApplication::mouseButtons();
      if (!ui->_aLockResolution->isChecked() || (QApplication::mouseButtons() & Qt::LeftButton))
      {
        _isRendererResized = true; // (*)
        return false;
      }
     
      ResizeRenderer(_resolution);
      return true;
    }
    (*) On passe jamais là, je cherche donc un moyen de passer ici.

    La fonction ResizeRenderer() doit être appelée uniquement à la fin d'un resize, lorsque le bouton gauche de la souris est relachée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void MainWindow::mouseReleaseEvent(QMouseEvent* e)
    {
      if (_isRendererResized && (e->button() && Qt::LeftButton))
      {
        ResizeRenderer(_resolution);
        _isRendererResized = false;
      }
     
      QMainWindow::mouseReleaseEvent(e);
    }

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut


    Une sensation de très compliqué pour pas grand chose...

    Déjà, d'un point de vue utilisateur, avoir une fenêtre principale qui se redimensionne toute seule, ça fait bizarre.

    Regarde l'exemple de Blender : tu as une fenêtre principale, redimensionnable (et avec des zones de rendu redimensionnable aussi) ; lors d'un resize, la nouvelle taille est envoyé au moteur 3D qui recalcule l'image avec la nouvelle résolution. Et c'est ce qu'on attend d'une IHM : que l'interface impose les paramètres au moteur et pas l'inverse.

    Dans Blender, tu as également une fenêtre de rendu avec une taille choisit dans les paramètres. Dans ce cas (taille fixe, rendu 3D, aucune interaction avec l'utilisateur), Blender ouvre simplement une nouvelle fenêtre non redimensionnable avec le rendu en taille fixée.
    En bref, si tu ne veux pas que l'utilisateur puisse choisir dynamiquement la résolution du rendu : n'autorise pas le redimensionnement de la fenêtre de rendu !

    Si tu veux absolument mettre ton rendu dans la fenêtre principale, dans ce cas il faut rendre indépendant la taille du widget et la résolution de ton rendu.
    En supposant que tu produis ton rendu dans un QPixmap (ou équivalent), tu peux :
    - mettre ton widget dans un QScrollArea. Dans ce cas, si la résolution du rendu est supérieur à la taille du widget, tu auras 2 scrolls pour te déplacer dans ton rendu.
    - ou encore mieux, tu mets ta QPixmap dans une QGraphicsView et tu ajoutes des fonctions de "navigation" dans ton rendu : zoom avant et arrière, aucun zoom (1:1), déplacement, etc.


    Concernant ton problème, tu essaies de récupérer les eventMouse pour savoir quand l'utilisateur à finit de redimensionner la fenêtre, pour éviter de relancer un rendu à plusieurs reprises pour rien. Or tu imposes à ton widget de garder une taille constante (la même que ton rendu). Donc ta variable _resolution ne change pas pendant un eventResize et il n'y a aucun intérêt de recalculer le rendu pendant et même après un resize. Ton rendu ne change pas à ce moment là.
    En fait, il faut que tu mettes en cache le rendu 3d et que tu le recalcules uniquement en cas de changement de résolution, de paramètres de rendu ou de contenu de la scène. Tu peux lire le Qt Quarterly sur QPixmapCache pour avoir un exemple de mise en cache (http://qt-quarterly.developpez.com/qq-12/qpixmapcache/).
    Et avec cette approche, toutes les modifications de l'IHM ne relanceront pas de calcul du rendu et ton application sera plus rapide.

  5. #5
    Nouveau membre du Club
    Profil pro
    dev
    Inscrit en
    Avril 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Avril 2010
    Messages : 53
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    si tu ne veux pas que l'utilisateur puisse choisir dynamiquement la résolution du rendu : n'autorise pas le redimensionnement de la fenêtre de rendu !
    Si je fais ça alors, je ne peux pas modifier par exemple la largeur du dock widget de gauche Si j'impose une taille fixe alors le redimensionnent des docks widget dans une taille supérieure est impossible. A moins de créer une fenêtre de rendu à part.

    Je ne veux pas de scroll bar mais je veux que l'utilisateur puisse voir toute la scène. S'il a définit une scène en 1024x768 et que la résolution est fixe alors la taille du widget central doit toujours être de cette taille, indépendamment de ce qui est affiché à l'intérieur et tout en laissant la possibilité de modifier la taille des autres widgets.

    D'ailleurs, je n'utilise pas de QPixmap mais je passe directement le winId() au moteur qui travaille de toute façon à résolution fixe. Si l'utilisateur règle la résolution de la fenêtre en 800x600 et que le moteur travaille en 1024x768, il ne verra de toute façon pas toute la scène. Je cherche surtout à souligner que la taille du rendu ne fit pas à la taille de la fenêtre.

    Citation Envoyé par gbdivers Voir le message
    Concernant ton problème, tu essaies de récupérer les eventMouse pour savoir quand l'utilisateur à finit de redimensionner la fenêtre, pour éviter de relancer un rendu à plusieurs reprises pour rien.
    Pas tout à fait, le rendu étant réalisé dans un thread à part, il est réalisé quoi qu'il arrive, tout du moins je n'ai pas à m'en préoccuper. Néanmoins, je ne veux pas appeler la fonction ResizeRenderer() pour rien. Fonction qui je le rappelle manage uniquement la taille des fenêtres.

    Citation Envoyé par gbdivers Voir le message
    Or tu imposes à ton widget de garder une taille constante (la même que ton rendu).
    Non, j'impose la taille du widget momentanément dans la fonction ResizeRenderer() avec setFixedSize() pour ajuster la MainWindow mais après j'enlève cette contrainte avec setMinimumSize(0, 0) et setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX) Tout les widgets sont redimentionnables mais si le central est redimmensionné à cause du redimensionnent d'un dock widget alors la fonction ResizeRenderer() doit être appelé pour prendre en compte la nouvelle taille.
    Mais tu as raison, je peux au moins empêcher le redimensionnement de la MainWindow par l'utilisateur même si elle pourra s'adapter à cause d'un resize d'un widget.

    Citation Envoyé par gbdivers Voir le message
    ta variable _resolution ne change pas pendant un eventResize
    La variable _resolution représente la taille de contrainte de la fenêtre central (1024x768) et non sa taille courante. Elle ne peut donc pas varier lors d'un size event.

    J'ai également un autre bug (?)
    Afin de prévenir de la réentrance de l'événement resize, j'utilise blockSignals(true) dans la fonction RenderSize()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      ui->_Renderer->blockSignals(true);  
      ui->_Renderer->setFixedSize(resolution); // -->> a resize event is emitted
      ui->_Renderer->blockSignals(false);
    Néanmoins, un événement resize est quand même émis car MainWindow::eventFilter() est appelé


Discussions similaires

  1. Souris non détectée
    Par Problème pc dans le forum Windows 7
    Réponses: 1
    Dernier message: 03/09/2013, 00h23
  2. Bug lors du redimensionnement de la fenêtre
    Par Slayor dans le forum EDT/SwingWorker
    Réponses: 0
    Dernier message: 21/09/2008, 02h09
  3. Nouvelle souris non détectée
    Par adrian07 dans le forum Périphériques
    Réponses: 2
    Dernier message: 30/08/2008, 20h25
  4. Réponses: 2
    Dernier message: 04/01/2008, 16h41
  5. Réponses: 1
    Dernier message: 09/06/2007, 23h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo