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

setSceneRect() behaves differently?



  • Hi, I am new to Graphics View Framework, previously I was using QWidget and it's paintEvent(), however, I want to add interaction capabilities to the items I draw and so I am switching to Graphics View. I want to resize my QGraphicsScene to the exact size of my QGraphicsView each time the view is resized. To achieve this I do the following:

    // MyView is QGraphicsView subclass
    void MyView::resizeEvent(QResizeEvent* event) 
    {
        scene.setSceneRect(rect());
        qDebug() << rect();
        scene.newSceneRectMade();
        QGraphicsView::resizeEvent(event);
    }
    

    Where in the function newSceneRectMade() I just debug the sceneRect to check if the size is correct:

    // MyScene is QGraphicsScene subclass
    void MyScene::newSceneRectMade()
    {
        qDebug() << sceneRect();
    }
    

    The sceneRect is setting correctly.

    I also have a QGraphicsRectIem in MyScene with its rectangle as (0, 0, 100, 100) to check if everything is being set correctly or not. This rectangle appears in the centre if I set the sceneRect in the constructor of MyView or if I do not set the sceneRect at all. But if I set the sceneRect in the resizeEvent() of MyView (like the one shown above) the rectangle appears at the top-left corner. Why is this happening?

    Also, changing the sceneRect of MyScene inside the resizeEvent() of MyView is the correct approach? given, I do not want the scrolling feature of the view, and I want to show the entire scene at all times in my view.



  • @CJha said in setSceneRect() behaves differently?:

    But if I set the sceneRect in the resizeEvent() of MyView (like the one shown above) the rectangle appears at the top-left corner. Why is this happening?

    Your view of the coordinate system has changed. By setting your own sceneRect, the top-left corner will be (0,0), which will match your viewport. AFAIK by default it's centered to (0,0).

    The viewport always starts at 0,0 (top-left)
    https://doc.qt.io/qt-5/graphicsview.html#the-graphics-view-coordinate-system



  • @CJha said in setSceneRect() behaves differently?:

    I want to resize my QGraphicsScene to the exact size of my QGraphicsView each time the view is resized.

    I do not want the scrolling feature of the view, and I want to show the entire scene at all times in my view.

    Just to check. If this is what you want, and you do not say you want the scene scaled to fit the view, this will mean: if you set the view smaller, with no scrolling nor scaling you will now have to (presumably) delete any graphics items which now fall outside the smaller view. Is that really what you want?



  • @Pl45m4 ok, this is great as I like my coordinate system to be (0,0) in the top left corner like in QWidget



  • @JonB Yes, scaling will work for some items but for others not so much. For example, I have texts in my scene and I have a few rectangles that depend on the size of the texts. As far as I know (I haven't tested it yet) that the texts will not scale while rectangles will, this would make the rectangles that depend on texts to be out of sync. I am going to test this feature now to see exactly how it works. So, my current plan is to have graphics items as member variables and then recalculate their positions on each resize and then reposition them accordingly (that is how I was doing it in QWidget, except in QWidget I had to repaint the entire thing on each resize). Would you suggest differently?



  • @CJha
    I really don't know what you're trying to achieve. I don't know why you are changing the scene dimensions to fit the view, I don't know why you are proposing to recalculate/resize/move a whole bunch if scene items in any circumstances. Though I will say I have not put texts on gfx scenes, if that makes a difference.



  • @CJha said in setSceneRect() behaves differently?:

    So, my current plan is to have graphics items as member variables and then recalculate their positions on each resize and then reposition them

    You dont need to store them, your scene knows ;)
    You just have to filter them, if needed
    https://doc.qt.io/qt-5/qgraphicsscene.html#items

    @JonB said in setSceneRect() behaves differently?:

    texts on gfx scenes

    I hope @CJha is talking about QGraphicsTextItem and not labels or other text :)



  • @Pl45m4
    Does a QGraphicsTextItem scale for you (if you do scaling) like any other gfx item, without you being responsible to go in pick font sizes to fit, like you would have to do in a widget?



  • @JonB I am making a line-plot. I have text for axis and tick labels in there. What I want is easy interaction with texts and other parts so that I can give the user the ability to easily change stuff (e.g. double click on axis label to get to it's settings, double click on plot lines to select it, etc.). Since, the entire plot should be visible at all times in the view, so if the view is resized I will have to recalculate/resize/move all stuff. I don't see a way around it.



  • @Pl45m4 Ah, ok. If my scene knows then that's even better. Yes, I am talking about QGraphicsTextItem and not labels, etc.



  • @JonB said in setSceneRect() behaves differently?:

    Does a QGraphicsTextItem scale for you (if you do scaling) like any other gfx item, without you being responsible to go in pick font sizes to fit, like you would have to do in a widget?

    No, of course not. It scales but it doesn't ensure that it looks good afterwards.

    Interesting example
    https://stackoverflow.com/a/32188957

    @CJha said in setSceneRect() behaves differently?:

    I am making a line-plot.

    Why are you using QGraphicsViewand not a QChart or something similar?



  • @Pl45m4 I tried QChart, QCustomPlot and a few others. All of these are very slow when it comes to plotting a vector of hundreds of thousands of doubles. I made my own algorithm which runs in a different thread to do the calculations, this way I get around 10 times faster response as compared to QChart.



  • @CJha said in setSceneRect() behaves differently?:

    hundreds of thousands of doubles

    Which human can read hundreds of thousands data points in one plot?
    Use downsampling to reduce the number of data points shown at a time and show the real data (range between given values), when zoomed in.



  • @Pl45m4 I tried downsampling. It is not useful as I have to be accurate in showing the results since the plot is going to be used in scientific applications in labs. Downsampling is not useful because let's say I have one data point out of hundreds of thousands which is significantly different compared to others (usual case in real recorded data) then this might be lost in downsampling or it's magnitude might get changed (depending on the downsampling algorithm). This behaviour will not be acceptable in the labs that I am making the plot for.

    I have already developed the algorithm to correctly show all the data points, it will show even a single data point out of hundreds of thousands which is significantly different from others without sacrificing its magnitude. This means even if the entire data of hundreds of thousands is visible at the same time, any inconsistencies, no matter how few data points it consists of, will always be visible to the scientist working with my plot.

    Plotting is no longer an issue for me as I have separate threads which calculates the plot lines (one thread per plotline). The user interaction is an issue since the plot is going to be used in multiple circumstances e.g. to view already recorded data, to view real-time data from hardware measuring equipment, and to view user-constructed data.


Log in to reply