Constantly updating tooltip text



  • Hello all,

    I'd like to ask a question about the tooltip.

    I keep receiving position and orientation data from a server (python socket),
    and I want to display them using a tooltip.
    But I don't know how to keep updating the tooltip text.
    Note that the data is updating about 10 times per second.

    Thanks.



  • @sehnkim

    You could do that with signal/slot
    Every time you receive new data from your server you could fire a signal and in the connected slot you update the tooltip



  • @the_

    Thank you for your reply.

    I've tried like this as SLOT

    ui->pushButton_add->setToolTip(QString::number(ncalls));

    but the tooltip shows only the latest value.
    I need to see the value changing continuously.

    Any advice?
    Thanks.


  • Lifetime Qt Champion

    Hi,

    A tooltip might not be the best tool for that. Why did you choose to use a tooltip ? How is your application supposed to show that changing value ?



  • @SGaist

    I want to show 'Tracker info + its position/orientation' whenever the user hovers the mouse over each item of the ListWidget. All icons are contained in a ListWidget.
    I was using the tooltip for showing the 'Tracker info', and I am trying to add its position/orientation to the info. That's why I am using a tooltip for the changing values.
    What approaches do you recommend?

    Here is a conceptual figure using the MS Paint.
    https://www.dropbox.com/s/iromipvip5680j4/listWidget.png?dl=0

    Thanks a lot. :)


  • Moderators

    @sehnkim
    you can "simulate" a tooltip-like behavior, but more responsive.

    QLabel* toolTipWidget = new QLabel( this, Qt::ToolTip );
    ...
    toolTipWidget->setText( ... );
    toolTipWidget->move( pos );
    toolTipWidget->show();
    


  • @raven-worx

    Oh.. thanks a lot for your advice.
    If I follow your approach, how can I check if my mouse is over each item in a ListWidget? As I explained right above, I am using icons which are in a ListWidget.
    Here is a conceptual diagram by the MS Paint.
    https://www.dropbox.com/s/iromipvip5680j4/listWidget.png?dl=0
    Can I use eventFilter somehow?
    Thanks a lot.

    bool MainWindow::eventFilter(QObject *watched, QEvent *evt)
    {
        if (watched == ui->pushButton)
        {
            if (evt->type() == QEvent::ToolTip)
            {
                QHelpEvent *helpEvent = static_cast<QHelpEvent *>(evt);
                m_ToolTipPos = helpEvent->globalPos();
            }
            else if (evt->type() == QEvent::ToolTipChange)
            {
                if (ui->pushButton->underMouse() && !m_ToolTipPos.isNull())
                    QToolTip::showText(m_ToolTipPos, ui->pushButton->toolTip());
            }
        }
    
        return QMainWindow::eventFilter(watched, evt);
    }
    

  • Moderators

    @sehnkim

    listWidget->viewport()->setMouseTracking( true );
    listWidget->viewport()->installEventFilter( this );
    ...
    bool eventFilter( QObject* watched, QEvent* event )
    {
        if( watched == listWidget->viewport() )
        {
             switch( event->type() )
             {
                    case QEvent::MouseMove:
                    {
                           QMouseEvent* me = static_cast<QMouseEvent*>( event );
                           QModelIndex index = listWidget->indexAt( me->pos() );
                           if( index.isValid() )
                           {
                                    // get the infos needed using the QModelIndex index
                                    toolTipWidget->setText( ... );
                                    toolTipWidget->move( me->globalPos() );
                                    toolTipWidget->show();
                           }
                           else
                           {
                                    toolTipWidget->hide();
                           }
                    }
             }
        }
        return BaseClass::eventFilter( watched, event );
    }
    


  • @raven-worx

    I really appreciate your help and the example code which is very useful.
    I have tested with your code, and worked pretty well mostly except one thing.

    In my code, I have used
    if (evt->type() == QEvent::ToolTipChange))
    since I want to update the tooltip even though I don't move the mouse.
    That is, I wanted to update the tooltip text without moving the mouse.

    Actually, it worked pretty well with a PushButton, but it didn't work with a ListWidget since updating a tooltip for an item doesn't trigger the QEvent::ToolTipChange, but updating a tooltip for ListWidget itself triggered the event. :( Do you know how to trigger the event when updating a tooltip for an item in ListWidget?

    In addition, here is the latest version based on your code. Would you mind proving me with any advice on how to update the label text without moving the mouse? I've tried with other events, but failed. :(

    Thank you so much. :)

    bool MainWindow::eventFilter( QObject* watched, QEvent* event )
    {
        if( watched == ui->listWidget->viewport() )
        {
            switch( event->type() )
            {
                case QEvent::MouseMove:
                {
                    QMouseEvent* me = static_cast<QMouseEvent*>( event );
                    QModelIndex index = ui->listWidget->indexAt( me->pos() );
                    if( index.isValid() ) {
                        // get the infos needed using the QModelIndex index
                        toolTipWidget->setText(QString::number(ncalls++));
                        QPoint rePos = me->globalPos();
                        rePos.setX(rePos.x() + 30);
                        toolTipWidget->move( rePos );
                        toolTipWidget->show();
                    }
                    else
                        toolTipWidget->hide();
                }
            }
        }
        return QMainWindow::eventFilter( watched, event );
    }
    

  • Moderators

    @sehnkim
    ok, depending on how you set the tooltip, this is a bit tricky, lets try it this way:
    (Assuming you set the tooltip via the model directly or via QListWidgetItem::setToolTip())

    class MyToolTipWidget : public QLabel
    {
        Q_OBJECT
    
    public:
        MyToolTipWidget( QWidget* parent )
            : QLabel( parent, Qt::ToolTip )
        {
        }
      
        void setCurrentIndex( const QModelIndex & index )
        {
            if( QAbstractItemModel* model = m_CurrentIndex.model() )
                model->disconnect(this);
    
            m_CurrentIndex = index;
            this->updateToolTipText( m_CurrentIndex );
    
            if( QAbstractItemModel* model = m_CurrentIndex.model() )
                connect( model, SIGNAL(dataChanged(const QModelIndex &,const QModelIndex &)), this, SLOT(updateToolTipText(const QModelIndex &)) );
        }
        QModelIndex currentIndex() const { return m_CurrentIndex; }
      
    protected slots:
        void updateToolTipText( const QModelIndex & index )
        {
            if( !m_CurretnIndex.isValid() || m_CurretnIndex != index )
                return;
                
            // update of tooltip. Maybe m_CurrentIndex.data(Qt::ToolTipRole).toString() ??
            this->setText( ... );
        }
      
    protected:
        virtual void hideEvent( QHideEvent* event )
        {
            this->setCurrentIndex( QModelIndex() );
            QLabel::hideEvent( event );
        }
      
    private:
        QPersistentModelIndex   m_CurrentIndex;
    };
    

    Just implement updateToolTipText() to your needs.
    Now in the eventFilter you simply need to call setCurrentIndex() on the new tooltip widget and the rest should hopefully work out of the box.

    Hope it works. Haven tested it, have just written it down straight from my head.



  • @raven-worx

    Thank you so much for your help.
    I think the code would work for me. :)
    Thanks.


Log in to reply
 

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