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 Update on Monday, May 27th 2025

ToolTip events not shown for recursive overlapping QGraphicsItem objects

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 1.2k Views
  • 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.
  • TGVFT Offline
    TGVFT Offline
    TGVF
    wrote on 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?

    TGVFT 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on 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) { .... }

      TGVFT 1 Reply Last reply
      0
      • mrjjM mrjj

        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) { .... }

        TGVFT Offline
        TGVFT Offline
        TGVF
        wrote on 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
        • TGVFT TGVF

          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?

          TGVFT Offline
          TGVFT Offline
          TGVF
          wrote on 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
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on 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

            • Login

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