ToolTip events not shown for recursive overlapping QGraphicsItem objects



  • 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?


  • Qt Champions 2016

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



  • @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...



  • @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!


  • Qt Champions 2016

    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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.