Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?



  • Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer? I am trying to use QSvgRenderer::boundonelements(), but i don't understand how to use the QRectF to display the QToolTip.

    QToolTip::showText() needs a Qpoint, so i thoughts perhaps i can create one using x and y of QRectF, but this obviously doesn't work. Since i get the error message:

    error: no matching function for call to ‘QToolTip::showText(const QPoint*&, const char [16], svgform*)’ QToolTip::showText(point, "text on tooltip", this); ^

    Or if i Change const QPoint *point to const QPoint point Will give me another error:

    error: conversion from ‘QPoint*’ to non-scalar type ‘const QPoint’ requested const QPoint point = new QPoint((int)qrect.x(), (int)qrect.y()); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    tried more things, but this is as close as i could get. Could use a little help to get a better understanding about qrect and qpoint and how to use it for a QToolTip.

    svgform.h:

    #ifndef SVGFORM_H
    #define SVGFORM_H
    
    #include <QWidget>
    
    namespace Ui {
    class svgform;
    }
    
    class svgform : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit svgform(QWidget *parent = nullptr);
        ~svgform();
    
    protected:
        virtual void paintEvent(QPaintEvent *event);
    
    
    private:
        Ui::svgform *ui;
    };
    
    #endif // SVGFORM_H
    
    

    svgform.cpp:

    #include "svgform.h"
    #include "ui_svgform.h"
    #include "QPainter"
    #include "QSvgRenderer"
    #include "QDebug"
    #include "QToolTip"
    
    svgform::svgform(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::svgform)
    {
        ui->setupUi(this);
    }
    
    void svgform::paintEvent(QPaintEvent * /* event */)
    {
        //Create qpainter object
        QPainter painter(this);
    
        // file location main wheel in qstring
        QString svgFile = "/home/arjan/qtprojects/svgtooltip/svgTooltip/square.svg";
    
        // create svg object
        QSvgRenderer svgr(svgFile);
    
        QRectF qrect = svgr.boundsOnElement("square2");
    
        const QPoint *point = new QPoint(qrect.x(), qrect.y());
    
        QToolTip::showText(point, "text on tooltip", this, qrect);
    
        // Render paint object
        svgr.render(&painter);
    
        // end paint
        painter.end();
    }
    
    svgform::~svgform()
    {
        delete ui;
    }
    

  • Lifetime Qt Champion

    @Hermes22 said in Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?:

    const QPoint *point = new QPoint(qrect.x(), qrect.y());

    You're creating a pointer to a QPoint for no good reason. QToolTip::showText() wants a const reference.



  • @Christian-Ehrlicher said in Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?:

    You're creating a pointer to a QPoint for no good reason. QToolTip::showText() wants a const reference.

    That's the part i do not yet understand. How can i use the QRectF coardinates in the QToolTip::showtext();


  • Lifetime Qt Champion

    @Hermes22 said in Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?:

    How can i use the QRectF coardinates in the QToolTip::showtext();

    Pass a const ref, not a pointer (and don't create a QPoint on the heap at all)



  • Oke, I'm getting somewhere now. I finally see a tooltip, but right now its shown where ever the mouse hovers the svg image, instead when hovering a red square i have drawn using svg. So how do i manage to show the tooltip on the location of QRectF and not all over the svg image.

    #ifndef SVGFORM_H
    #define SVGFORM_H
    
    #include <QWidget>
    #include <QMouseEvent>
    
    namespace Ui {
    class svgform;
    }
    
    class svgform : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit svgform(QWidget *parent = nullptr);
        ~svgform();
    
    protected:
        void paintEvent(QPaintEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
    
    private:
        Ui::svgform *ui;
        QRectF qrect;
    };
    
    #endif // SVGFORM_H
    

    svgform.cpp:

    #include "svgform.h"
    #include "ui_svgform.h"
    #include "QPainter"
    #include "QSvgRenderer"
    #include "QDebug"
    #include "QToolTip"
    
    svgform::svgform(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::svgform)
    {
        ui->setupUi(this);
        setMouseTracking(true);
    }
    
    // Implement in your widget
    void svgform::mouseMoveEvent(QMouseEvent *event){
    
        QRect rect = qrect.toRect();
        QToolTip::showText(event->pos(), "test", this, rect,100000);
    
    }
    
    void svgform::paintEvent(QPaintEvent * /* event */)
    {
        //Create qpainter object
        QPainter painter(this);
    
        // file location main wheel in qstring
        QString svgFile = "/home/arjan/qtprojects/svgtooltip/svgTooltip/square.svg";
    
        // create svg object
        QSvgRenderer svgr(svgFile);
    
        qrect = svgr.boundsOnElement("square2");
    
        // Render paint object
        svgr.render(&painter);
    
        // end paint
        painter.end();
    }
    
    svgform::~svgform()
    {
        delete ui;
    }
    
    

  • Lifetime Qt Champion

    You have to find out where the red square is and only call setToolTip() there by checking if the current mouse position is over the square.



  • Isn't that what svgr.boundonelements("square") is supposed to do...? Giving me the rectangle of the location of the svg element. I pass the rect data here into the tooltip:

    QRect rect = qrect.toRect(); //Convert QRectF to QRect.
    QToolTip::showText(event->pos(), "test", this, rect,100000);
    

    And how do i check if mouse is where the QRect is? Perhaps this could be the part i am missing?


  • Lifetime Qt Champion

    @Hermes22 said in Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?:

    I pass the rect data here into the tooltip:

    No, you don't pass a rect to the tooltip. It's a point where the tooltip should be shown: https://doc.qt.io/qt-5/qtooltip.html#showText



  • After some more puzzling, i found a part of the solution and i see a tooltip now but the tooltip appears only on half of the square. I can't make a screenshot, because it dissapears if i do. Anyway, now i have a new problem. It seems the geometry is smaller then the geometrie of the actual svg image. So this leads me to another question, why is the boundOnElements returning coardinates that are not correct? Can it be that the viewbox of the svg file is a part of the problem?

    void displaynatalchart::mouseMoveEvent(QMouseEvent *event){
        qDebug() << event->pos();
    
        qDebug() <<"qrect"<< rect;
    
        if(event->pos().x() > (rect.x())
           && event->pos().y() > (rect.y())
           && event->pos().x() < (rect.x() + rect.width())
           && event->pos().y() < (rect.y() + (rect.height())) ) {
                QToolTip::showText(event->pos(), "test", nullptr, rect.toRect(),1000);
        }
    }
    
    

  • Lifetime Qt Champion

    @Hermes22 said in Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?:

    if(event->pos().x() > (rect.x())
       && event->pos().y() > (rect.y())
       && event->pos().x() < (rect.x() + rect.width())
       && event->pos().y() < (rect.y() + (rect.height())) )
    

    Why that complicated? https://doc.qt.io/qt-5/qrect.html#contains



  • @Christian-Ehrlicher said in Is there a way to display a QToolTip on top of a svg image displayed with QSvgRenderer?:

    Why that complicated? https://doc.qt.io/qt-5/qrect.html#contains

    Thanx, probably because i have a talent for thinking to complicated.. Nice solution! Now i need to figure out, why the QRectF returned by the boundOnElement("square") seem not have the correct geometry.


  • Lifetime Qt Champion

    Hi

    • Now i need to figure out, why the QRectF returned by the boundOnElement("square") seem not have the correct geometry.

    I would open the SVG in inkscape and check the viewbox (page)
    to make sure the red part is centered how you expect it.



  • Thanx folks, nailed it! Seems that a viewbox can't be used or i'm missing something. Anyway i can work around that!


Log in to reply