Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. ToolTip events not shown for recursive overlapping QGraphicsItem objects
Forum Updated to NodeBB v4.3 + New Features

ToolTip events not shown for recursive overlapping QGraphicsItem objects

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TGVF
    wrote on 15 Feb 2018, 15:48 last edited by
    #1

    Hello folks,
    Newbee with event programming (and more generally GUI programming) I am in deep trouble to understand how events and signals-slots are supposed to be managed. Would you recommend some clear and basic course or wiki or book, with nice simple examples using QtGUI?
    Precisely, I am presently stuck with a QGraphicsScene object on which are painted a number of QgraphicsPG objects. QgraphicsPG class is based on QGraphics item class. QgraphicsPG objects are constructed and painted recursively (tree-like) , with the same tree structure as their ptr_source member (my type Phygenic*).
    I wanted to display as ToolTip some text describing the ptr_source, for instance its ptr_source->nom i.e. its name.
    The QgraphicsPG sub-objects have their rectBounds rectangle inside the mother QgraphicsPG object, and they are painted after the mother QgraphicsPG object, assuming this gives them a higher Z-value (correct?) .
    Neverthess, tooltip behavior is not what I expect, using the re-implemented QGraphicsPG::hoverEnterEvent as shown below:
    I never see the QgraphicsPG sub-objects' ToolTip appearing inside the mother object's RectBounds , but only the mother QgraphicsPG ToolTip itself.

    PG_Qt_MainWindow::PG_Qt_MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::PG_Qt_MainWindow)
    {
        ui->setupUi(this);
        ui->graphicsView->setScene(&scene);
        ui->graphicsView->show() ;
    }
    //-----------------------------------------------------
    void PG_Qt_MainWindow::on_actionOuvrir_triggered()
    {
        QString fileName = QFileDialog::getOpenFileName(this, tr("Ouvrir le fichier..."), QString(),
                tr("Fichiers de modèle brut (*.pgML);") ) ;
    // (...) file opened and model constructed, if file is valid
            QGraphicsPG* item= new QGraphicsPG(ptr_modele.back(), position  ) ;
            items.push_back(item);
            scene.addItem(item);
    }
    //-------------------------------------------------------------------------------------------------------
    QGraphicsPG::QGraphicsPG(Phygenic *ptr_pg, Indices2D position, QGraphicsItem *parent, bool develop, bool avecCalcul )
        : rectBoite() , rectTexte(), texte() , flecheEntreeBoite() , flecheSortieBoite() , rectCadre(), rectBounds()
    {
        setAcceptHoverEvents(true) ;
        setToolTip( c_QString(" "+ptr_pg->nom) ) ;
    
        Q_UNUSED(parent) ;
        ptr_source= ptr_pg ;
        Etat_develop= develop ;
        boite= position ;
        cadre= position ;
        flechesInternes.clear() ;
        Indices2D ss_pos ;
        for  ( int iph= 0 ; iph< ptr_source->Nph ; iph++ ) {
           ss_pos.iH= position.iH ; ss_pos.iV= position.iV + iph ;
           ss_qgpg.push_back ( new QGraphicsPG(ptr_source->ph[iph], ss_pos, this, Etat_develop, false ) ) ; 
    // NOTE: recursive constructor is called for sub-objects. No calc for sub-objects
        } // next iph
        if (avecCalcul) calculer(boite, develop) ; 
    } // fin de QGraphicsPG::QGraphicsPG(Phygenic *ptr_pg, QGraphicsItem *parent, bool develop)
    //--------------------------
    void QGraphicsPG::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
               QWidget *widget) {
        if ( !Etat_develop || ptr_source->Nph== 0 ) {
            // boite
            painter->setBrush(brush);
            painter->setPen(noir);
            painter->drawRect(rectBoite) ;
    // (...)
           // sous-boites
            if (Etat_develop) {
                for  ( int iph= 0 ; iph< ptr_source->Nph ; iph++ ) ss_qgpg.at(iph)->paint(painter, option, widget)  ;
    // NOTE: paint function is called recursively here for sub-objects, after the paint operations on the mother object.
            } // end if (Etat_develop)
    } // fin de QGraphicsPG::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    //-------------------
    void QGraphicsPG::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
        QToolTip::showText(event->screenPos(), c_QString(" "+ptr_source->nom) ) ;
    } // fin de: void QGraphicsPG::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
    

    Apparently, no hoverEnterEvent is triggered for the sub-objects QGraphicsPG although they should be painted on top of the mother object. What did I miss?

    T 1 Reply Last reply 19 Feb 2018, 06:56
    0
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 15 Feb 2018, 19:19 last edited by
      #2

      Hi
      I cant answer for the HoverEvent but i wondered if you checked with

      http://doc.qt.io/qt-5/qgraphicsitem.html#sceneEvent
      and
      if (event->type() == QEvent::ToolTip) { .... }

      T 1 Reply Last reply 15 Feb 2018, 20:38
      0
      • M mrjj
        15 Feb 2018, 19:19

        Hi
        I cant answer for the HoverEvent but i wondered if you checked with

        http://doc.qt.io/qt-5/qgraphicsitem.html#sceneEvent
        and
        if (event->type() == QEvent::ToolTip) { .... }

        T Offline
        T Offline
        TGVF
        wrote on 15 Feb 2018, 20:38 last edited by
        #3

        @mrjj
        Following your suggestion, this is what I tried :

        bool QGraphicsPG::sceneEvent(QEvent *event) {
            bool retour= false ;
            if (event->type() == QEvent::ToolTip) {
                QToolTip::showText(event->screenPos(), c_QString(" "+ptr_source->nom) ) ;
                retour= true ;
            } // end if
            return retour ;
        } // fin de: QGraphicsPG::sceneEvent(QEvent *event)
        

        But it won't compile since event->screenPos() is not defined, apparently. Should I cast event somehow (static or dynamic?) to be able to compile.

        But may be I should not re-implement any event handler and let Qt do the work for me, (since QToolTip being set in the constructor, everything else should work automatically)? So I tried and removed all specific event handlers from this class, but the result is event worse: there is no longer any ToolTip text displayed...

        1 Reply Last reply
        0
        • T TGVF
          15 Feb 2018, 15:48

          Hello folks,
          Newbee with event programming (and more generally GUI programming) I am in deep trouble to understand how events and signals-slots are supposed to be managed. Would you recommend some clear and basic course or wiki or book, with nice simple examples using QtGUI?
          Precisely, I am presently stuck with a QGraphicsScene object on which are painted a number of QgraphicsPG objects. QgraphicsPG class is based on QGraphics item class. QgraphicsPG objects are constructed and painted recursively (tree-like) , with the same tree structure as their ptr_source member (my type Phygenic*).
          I wanted to display as ToolTip some text describing the ptr_source, for instance its ptr_source->nom i.e. its name.
          The QgraphicsPG sub-objects have their rectBounds rectangle inside the mother QgraphicsPG object, and they are painted after the mother QgraphicsPG object, assuming this gives them a higher Z-value (correct?) .
          Neverthess, tooltip behavior is not what I expect, using the re-implemented QGraphicsPG::hoverEnterEvent as shown below:
          I never see the QgraphicsPG sub-objects' ToolTip appearing inside the mother object's RectBounds , but only the mother QgraphicsPG ToolTip itself.

          PG_Qt_MainWindow::PG_Qt_MainWindow(QWidget *parent) :
              QMainWindow(parent),
              ui(new Ui::PG_Qt_MainWindow)
          {
              ui->setupUi(this);
              ui->graphicsView->setScene(&scene);
              ui->graphicsView->show() ;
          }
          //-----------------------------------------------------
          void PG_Qt_MainWindow::on_actionOuvrir_triggered()
          {
              QString fileName = QFileDialog::getOpenFileName(this, tr("Ouvrir le fichier..."), QString(),
                      tr("Fichiers de modèle brut (*.pgML);") ) ;
          // (...) file opened and model constructed, if file is valid
                  QGraphicsPG* item= new QGraphicsPG(ptr_modele.back(), position  ) ;
                  items.push_back(item);
                  scene.addItem(item);
          }
          //-------------------------------------------------------------------------------------------------------
          QGraphicsPG::QGraphicsPG(Phygenic *ptr_pg, Indices2D position, QGraphicsItem *parent, bool develop, bool avecCalcul )
              : rectBoite() , rectTexte(), texte() , flecheEntreeBoite() , flecheSortieBoite() , rectCadre(), rectBounds()
          {
              setAcceptHoverEvents(true) ;
              setToolTip( c_QString(" "+ptr_pg->nom) ) ;
          
              Q_UNUSED(parent) ;
              ptr_source= ptr_pg ;
              Etat_develop= develop ;
              boite= position ;
              cadre= position ;
              flechesInternes.clear() ;
              Indices2D ss_pos ;
              for  ( int iph= 0 ; iph< ptr_source->Nph ; iph++ ) {
                 ss_pos.iH= position.iH ; ss_pos.iV= position.iV + iph ;
                 ss_qgpg.push_back ( new QGraphicsPG(ptr_source->ph[iph], ss_pos, this, Etat_develop, false ) ) ; 
          // NOTE: recursive constructor is called for sub-objects. No calc for sub-objects
              } // next iph
              if (avecCalcul) calculer(boite, develop) ; 
          } // fin de QGraphicsPG::QGraphicsPG(Phygenic *ptr_pg, QGraphicsItem *parent, bool develop)
          //--------------------------
          void QGraphicsPG::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                     QWidget *widget) {
              if ( !Etat_develop || ptr_source->Nph== 0 ) {
                  // boite
                  painter->setBrush(brush);
                  painter->setPen(noir);
                  painter->drawRect(rectBoite) ;
          // (...)
                 // sous-boites
                  if (Etat_develop) {
                      for  ( int iph= 0 ; iph< ptr_source->Nph ; iph++ ) ss_qgpg.at(iph)->paint(painter, option, widget)  ;
          // NOTE: paint function is called recursively here for sub-objects, after the paint operations on the mother object.
                  } // end if (Etat_develop)
          } // fin de QGraphicsPG::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
          //-------------------
          void QGraphicsPG::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
              QToolTip::showText(event->screenPos(), c_QString(" "+ptr_source->nom) ) ;
          } // fin de: void QGraphicsPG::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
          

          Apparently, no hoverEnterEvent is triggered for the sub-objects QGraphicsPG although they should be painted on top of the mother object. What did I miss?

          T Offline
          T Offline
          TGVF
          wrote on 19 Feb 2018, 06:56 last edited by
          #4

          @TGVF
          Finally, I nailed my bug:
          I added what was missing e.g.construction of the base object in the QGraphicsPG constructor, with : QGraphicsItem(parent) instead of declaring Q_USED (parent) .

          QGraphicsPG::QGraphicsPG(Phygenic *ptr_pg, Indices2D position, QGraphicsItem *parent, bool develop, bool avecCalcul )
              : QGraphicsItem(parent) , rectBoite() , rectTexte(), texte() , flecheEntreeBoite() , flecheSortieBoite() , rectCadre(), rectBounds()
          {
              //setAcceptHoverEvents(true) ;
              setToolTip( c_QString(" "+ptr_pg->nom) ) ;
          
              //Q_UNUSED(parent) ;
          (...)
          

          I also changed the default value of parent to 0 instead of NULL pointer, since the documentation says =0 (isn't it the same, actually?).

          public:
             QGraphicsPG(Phygenic* ptr_pg, Indices2D position, QGraphicsItem *parent = 0, bool develop= true, bool avecCalcul= true );
          

          Finally, ToolTip works as desired without need for a hoverEnterEvent handler, nor any other specific event handler!
          I feel better now, thanks!

          1 Reply Last reply
          1
          • M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 19 Feb 2018, 07:19 last edited by
            #5

            Hi
            Super you found it.
            Yes using 0 or NULL is the same.
            If you want use something else beside 0 or NULL , then use std::nullptr

            1 Reply Last reply
            0

            1/5

            15 Feb 2018, 15:48

            • Login

            • Login or register to search.
            1 out of 5
            • First post
              1/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved