Mouseclick and SVG images



  • I'm trying to write a program with two svg files. A click on one element of the first svg file would have an effect on the second svg file.

    I have very little experience with GUI programming and I have a lot of trouble finding documentation for this kind of problem, very likely because I don't know where to look. I just need to know where to look at: what kind of object can be used to bind the element of a svg file to an action, or do I need to use the position of the cursor when the click happens to deduce what element was selected, etc. I'm using svg files because they're easy to generate but if there's a better approach I'd like to hear about it.



  • I'm sorry, my friend. Your question is not clear at all. You didn't mention how the GUI has to look like, and where the clicks are to happen. Please explain in more details about your plan and the results you're expecting.

    Regards.



  • OK! Sorry about that.

    So I need a simple window that can display two figures. Both figures are networks: a bunch of circles (the vertices) linked by lines (the edges). My C++ program can generate these networks as SVG files, but if another format is needed I could change it (although I really like SVG files).

    Now here's the tricky part (at least from my perspective). When I click on a circle in figure 1, it should have an effect on figure 2. More precisely, it should change the color of many lines/circles in figure 2, and when I click on a circle in figure 2, it should change the color of many lines/circles in figure 1.

    I can deal with the "changing color" part either by generating a new SVG file or by modifying the existing file with QtXML, it doesn't really matter. The problem is: I have no idea how to create an action for "clicking on a circle in a SVG file". Also, the svg files are never the same, I need to read many different networks.

    My idea was to get the position of the cursor in the svg file when a click is made and then read the svg file to see if a circle was selected, but I'm not sure if it's a smart way to do things. It seems rather inefficient.

    Thank you.



  • Hello there,

    first thing, take a look at this example. It may inspire you.

    http://developer.qt.nokia.com/doc/qt-4.8/painting-svggenerator.html

    I'm not an expert in graphics. I only worked on OpenGL stuff. But I could suggest the following.

    First, please try to understand signals and slots, which are the main method for communicating between windows and UI controls in Qt.

    From my point of view, I think the way to do this is by getting the coordinates of the object you want to activate with this thing.
    With every click you do on the widget, at which you want to display your graphics, a signal is sent automatically from the widget called MouseClicked. Please take a look at the following link

    http://developer.qt.nokia.com/doc/qt-4.8/qmouseevent.html

    The signal is basically a function call with a parameter (or more). The parameter in this case is the object QMouseEvent. The event object has the coordinates of the position where the mouse clicked. And has all the information about that click, like whether it's a double click, single click, or mouse button held, etc...

    A slot function "receives" that signal. Now you have to re-implement the virtual function (slot) called mousePressEvent(QMouseEvent *event). For example, in my OpenGL apps, I use this event to rotate the object if pulled over by user. The virtual functions I reimplement are:
    @
    protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    @

    So you have to redeclare the function that holds the slot to the signal you wanna use, and then reimplement it to utilise it.

    Here's an example to how I to that:

    @

    void OpenGLClass::mousePressEvent(QMouseEvent *event)
    {
    lastPos = event->pos();
    }

    void OpenGLClass::mouseMoveEvent(QMouseEvent *event)
    {
    GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
    GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();
    if (event->buttons() & Qt::LeftButton)
    {
    if(simulationSettings->viewRotationDirectionIndex == 0)
    {
    simulationSettings->xAngle += 180 * dx;
    simulationSettings->yAngle += 180 * dy;
    }
    else if(simulationSettings->viewRotationDirectionIndex == 1)
    {
    simulationSettings->yAngle += 180 * dx;
    simulationSettings->zAngle += 180 * dy;
    }
    else
    {
    simulationSettings->zAngle += 180 * dx;
    simulationSettings->xAngle += 180 * dy;
    }
    //updateGL();
    } else if (event->buttons() & Qt::RightButton) {
    //xAngle += 180 * dy;
    //zAngle += 180 * dx;
    simulationSettings->xShift += 10 * dx;
    simulationSettings->yShift -= 10 * dy;
    //updateGL();
    }
    lastPos = event->pos();
    }
    @

    I hope this helps.

    Regards.



  • wow, thank you very much for the detailed answer! I'll look into it.


Log in to reply
 

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