Which Qt signal is triggerred when 2D image is completely updated on QGraphicalScene
-
I am confused, if you are updating the image then you already know when you are finished. In any case, it seems like an odd design decision to capture the result in a screen shot when you have everything you need to build and store a result image directly.
-
@ChrisW67, thank you very much for reply and queries..
I try to answer to your questions :)
Q) I am confused, if you are updating the image then you already know when you are finished ?
Ans) Yes you are right it can be confusing.
But practically when you draw a pattern on your PC Screen(I have tested using “chip” example in Qt library) using “QGraphicalView” widget, by sending some data and takes screen shot immediately after you have set scene(or transmitted complete data to PC screen) in QGraphicalView in your software using following instructions:
view->view()->setScene(scene); triggerSignalForScreenShot();
Then as a result you get a screen shot of your application, just when it has started plotting your data on your monitor and not at the time it has finished plotting your data on your monitor.
Below I have attached actual and expected screen shot for my application.
Actual Screen Shot
Expected Screen Shot
In other words there a delay between setting a Scene in your software and when the scene actually get displayed on your monitor due to which screen shot get triggered before data is displayed on monitor.
Q) In any case, it seems like an odd design decision to capture the result in a screen shot when you have everything you need to build and store a result image directly?
Ans) Again I agree with you if I have see it as a individual project 😊
But in fact this application will be one of the component of complex automated system, where high speed cameras will be triggered(taking screen shot ) day and night capturing output from sensors displayed on screen. The images taken from camera will be compared in this system with some reference images and further action will be automatically triggered if captured images matches reference images.
I hope that I answered your doubts, please inform me if you need any other information.
@JonB B I have tried as you mentioned but i do know how to find out when plotting of image on screen is completed. As there is a delay between when I send data from my software and when it is actually displayed on screen. Can you please inform me about any signal which i can use to know that my image has been displayed completely on screen.
-
Hi,
Why would you do screenshots ?
What format are you reference images ?
From what you wrote, you need to rebuild a proper image from your camera data and then maybe convert that to the same format as your reference images or if your reference images are already loaded in memory, transform your camera data to the same colorspace than your reference images to do the comparison. -
@SGaist Thank you very much for answer. Following I try to answer your questions and if in case i miss anything please let me know.
Q) Why would you do screenshots ?
Ans) Because I need to save picture of data(received from sensor) displayed on screen.What format are you reference images ?
Ans) right now .png but if you think any other format can better solve problem mentioned above then please suggest me I will take that format.Q) From what you wrote, you need to rebuild a proper image from your camera data and then maybe convert that to the same format as your reference images or if your reference images are already loaded in memory, transform your camera data to the same colorspace than your reference images to do the comparison.
Ans) Sorry if my topic of this post is not clear enough or created miss understanding.
Problem is not: that I do not know, how to process captured image from camera in order to compare it with my reference image.
Problem is: right now when I trigger screenshot/camera capture signal from my software, immediately after setting scene in QGraphicalView widget in my software as mentioned below.view->view()->setScene(scene); triggerSignalForScreenShot();
then the screen shot I get is of my PC screen before data is actually plotted on Screen (in QGraphicalView). As there is a delay between the time when data is set in QGraphicaView in software and the time when it is rendered on screen in reality.
-
@saurabh162
Depends how yourtriggerSignalForScreenShot();
is implemented, about which you say nothing. It's not that there is some hidden delay, per se, it's (presumably) that the view has not been given its chance to render, through the Qt event loop.Which is why choosing to call e.g.
void QGraphicsView::render(QPainter *painter, const QRectF &target = QRectF(), const QRect &source = QRect(), Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio)Renders the source rect, which is in view coordinates, from the scene into target, which is in paint device coordinates, using painter. This function is useful for capturing the contents of the view onto a paint device, such as a QImage (e.g., to take a screenshot), or for printing to QPrinter. For example:
(or same on
QGraphicsScene
rather thanQGraphicsView
if you prefer) would avoid this issue and seem much better to me?P.S.
If, for whatever reason, you are determined to use some external screenshotter you will need to get the view rendered. The easiest is to try callingview->view()->repaint()
immediately before yourtriggerSignalForScreenShot();
. Or you move that (the screenshot call) into something like theQWidget::paintEvent()
for the view and allow code to enter the Qt event loop. I'm not certain whether there are any better calls for a gfx scene/view, but the above is for a generalQWidget
, which aQGraphicsView
is. -
@JonB many many thanks for answer....I will try what you suggest and will update you ..Thanks :)
-
@saurabh162
It's a bit ugly, but like I said if you don't care the absolute minimum change to just try and see if you get what you want would be:view->view()->setScene(scene); view->view()->repaint(); triggerSignalForScreenShot();
Does that at least do what you want, at least then I understand. Though I still think the
QGraphicsView::render()
call to produce aQImage
would seem to me what you really ought be doing. -
@JonB once again thanks for your response. I have tried following code to do what you suggested
view->view()->setScene(scene); view->show(); QPrinter printer(QPrinter::HighResolution); printer.pageLayout().pageSize(); QPainter painter(&printer); // print, fitting the viewport contents into a full page view->render(&painter); triggerSignalForScreenShot();
but still I getting the result/problem as mentioned above.
triggerSignalForScreenShot()
is user defined signal which I connect to its slot using :
connect(this,&MainWindow::triggerSignalForScreenShot, this, &MainWindow::sceneChanged);
and slot I defined as follows:
void MainWindow::sceneChanged( ) { shootScreen(); saveScreenshot(); }
Thanks !! and kindly inform me if you need any other information or if I am making any mistake.
-
@saurabh162 said in Which Qt signal is triggerred when 2D image is completely updated on QGraphicalScene:
view->render(&painter);
triggerSignalForScreenShot();As per the docs this renders the view into the
painter
you pass torender()
, from which it says you can produce aQImage
. I have no idea what you think you are doing by ignoring this and calling your originaltriggerSignalForScreenShot()
, what does that have to do with it?I also suggested you try the simplest current "fix" by putting in a
view->view()->repaint();
initially and seeing that delivers what you want, but you don't seem to have looked at that.I leave it to you now, I have helped all I can.
-
@JonB Thank you !! Actually I have tried view->view()->repaint(); solution provided by you. but it did not help and after that I have tried solution I have pasted in my previous post.
And about " triggerSignalForScreenShot()" signal I have used because I did not understand how I can pass QImage to render() so that it produce image of screen(Sorry I am newbie in Qt).
But many thanks for your help ..I will now try/see how i can pass QImage object in render() function. Thank you !!
-
I am still curious about your need to do the capture of the shown image for comparison rather that do the comparison directly with the image you rebuilt from the camera data.
-
@JonB @ChrisW67 @SGaist ...I am now able to save snapshot of image I display using "QGraphicsScene" using method mentioned by @JonB .
In order to save image in .png format. i have used following code.
// Save rendered image in a .png file
```
QImage image(11000,7000, QImage::Format_RGB32);
QPainter painter(&image); scene->render(&painter); painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); image.mirrored().save("output.png");
many thanks for your help !!
-
@saurabh162 said in Which Qt signal is triggerred when 2D image is completely updated on QGraphicalScene:
@SGaist sorry I could not understand your question....whether you want to ask, why I want to capture image using camera ? instead of directly comparing images with my reference images directly ?
No no, I am wondering about the "capture the scene" step rather than directly save the built image.
-
@SGaist Capturing image(pattern provided by DMDs(Digital micromirror device)) is important in our case to adjust output from DMDs ( feedback loop ) which will be connected to camera responsible to take pictures on screen.
We cannot give feedback to DMDs directly from our PC due to technical reasons...please inform me if i have not answered your question....Thanks !!
-
You are at the wrong end of the system for my question.
I have no issue with the act of capturing that image for your feedback loop. My question is really, why do need to the detour through the painting of the QGraphicsScene rather than simply save the image you built from the camera to disk ? That would likely give you a higher quality image.