Direct drawing on UI
-
Hello,
I am making QT app with need to display images (from camera or HDD) in real time.
I am looking for fastest way to do this.
Ideal is to copy RGB data directly into video memory.I am new in QT.
In .NET I can make object to draw from any Control (analog of Widget) like this:
Graphics g = control.CreateGraphics();
using this object draw anything on Control like this:
g.DrawRect
g.DrawImage
g.DrawPixel
...
and even have direct access to the memory and make memcopy(...);Can i do the same in QT?
Is any other way is exist?Thank for the answer.
THE SOLUTION
I need to use paint event
-
Hi, welcome to the Qt forum! Have a look at QOpenGLWidget Class for hardware accelerated graphics and see QPainter Class to learn about 2D drawing operations.
-
Hello.
Thank you for welcoming. Hope i can find my way in QT with your help.I had a short a look on it and have some questions
-Is QOpenGLWidget hardware/software depended?
-Can i attach QPainter to widget outside of paint event. For example like this:
QPainter* DrawTool = new QPainter(DrawWidgetName);May be you can point me to some examples?
Thank you in advance.
-
hi
No, you are not allowed to paint outside paintEvent of the widget.
You can cheat and draw on image and show image though.here is small sample of that
https://www.dropbox.com/s/qwde8lb0fkjrrh3/mycheapgraph.zip?dl=0 -
Hi
And it is fast enough?
I mean it will not take my RGB, convert it to Image, when to Pixmap, when use slow OS methods to display,....
The reason i asking, similar way in .NET is terribly slow.
Update:
Some more questions:
-Can i pass my image (RGB data in a memory) to paintEvent(QPaintEvent *)?
-Can it be inside of QPaintEvent?
-How to pass it? Something like this: videoFrame->update(RGBPointer)?
-Pass image using global variable? -
@Mikl
hi
sorry just saw the question about painting outside of event.
You should use opengl :) The sample to draw on pixmap will have way to much overhead.-Can i pass my image (RGB data in a memory) to paintEvent(QPaintEvent *)?
No, it has fixed signature so u cant change it. (adding the param)-Can it be inside of QPaintEvent?
yes. should not be an issue-How to pass it? Something like this: videoFrame->update(RGBPointer)?
Really depends on what format you get from camera.-Pass image using global variable?
nope. never really a reason to use globals.
since you might create your own widget , you can just add a function
to assign/share the data from the source. -
Hi
-I like the way to draw on opengl. Should be 'fast'. But will i meet capability problem? it will run on Win AND Linux?
Can you point me to the example, please?-Pass image using global variable?
never was thinking about it. just looking for solution-Can i pass my image (RGB data in a memory) to paintEvent(QPaintEvent *)?
-Can it be inside of QPaintEvent?
-How to pass it? Something like this: videoFrame->update(RGBPointer)?
From camera i have raw 24bit RGB data.
If it is not possible to pass my data to paintEvent(QPaintEvent *) how can i get it? Even if it is inside of QPaintEvent. Not really see how to do it. I will start something. Correct/add me please.main() { char* RGBData = new char[frame size];//data from camera videoFrame = new VideoFrameWidget(); videoFrame->update(RGBData); } class VideoFrameWidget : public QWidget { Q_OBJECT public: VideoFrameWidget(QWidget *parent); virtual void paintEvent(QPaintEvent *); }; void VideoFrameWidget::paintEvent(QPaintEvent *data) { //use opengl to draw image from data }
-
hi
why cant RGBData just live in VideoFrameWidget ?
so you dont need to give it from main. ?but else u just use functions to give it to the widget.
-
It can, but i found it not logic. it is coming from the camera.
It was simplification of main. In a reality it will be a loop.If i understood you correctly, you propose to do it like this:
main() { char* RGBData;//data from camera VideoFrameWidget videoFrame = new VideoFrameWidget(); CameraDevice videoSource = new CameraDevice (); for(;;) { RGBData = videoSource->getFrame(); videoFrame->setFrame(RGBData); videoFrame->update(); } } class VideoFrameWidget : public QWidget { Q_OBJECT public: VideoFrameWidget(QWidget *parent); virtual void paintEvent(QPaintEvent *); void setFrame(char* newFrameData); private: char* frameData; }; void VideoFrameWidget::paintEvent(QPaintEvent*) { //use opengl to draw image from frameData } void VideoFrameWidget::setFrame(char* newFrameData) { frameData = newFrameData; }
-
yes exactly and then u can use
char* frameData;
in paintEvent -
@mrjj
Ok. Thanks.For me it is looks strange, but reading this example
http://doc.qt.io/qt-5/qtopengl-2dpainting-example.html
i found, what the only different is using GLWidget as base class.
All painting is done by the same QPainter.Am i right?
If it is so, task can be really simple.
Maybe you know the fastest way to paint from RGB raw data on widget: draw line by line, pixel by pixel, memcopy,.... -
@Mikl
Yes as far as i know its VERY similar to
normal widget drawing even when opengl.
(when 2d)well, the sample i have seen , used something like
uchar* data = getDataFromSomewhere();
QImage img(data, width, height, QImage::Format_ARGB32);
and then convert ot pixmap and draw.
or directly into pixmap with
http://doc.qt.io/qt-4.8/qpixmap.html#loadFromData -
@Mikl said:
For me it is looks strange, but reading this example
http://doc.qt.io/qt-5/qtopengl-2dpainting-example.html
i found, what the only different is using GLWidget as base class.
All painting is done by the same QPainter.Am i right?
Hi! Yes, getting 2D hardware acceleration for QPainter is really easy :)