Sign in to follow this  

Intense drawing with QT

This topic is 2333 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone.

I am trying to use QT 4.7 to make an emulator's debugger.
I have been able to solve almost all issues about using QT.

The only problem i have now is about drawing "pixels" into a widget.

I have read countless guides and the official documentation.
I always get ways to draw something that remains static.

I need to redraw the content of the widget fast.
I don't need special hardware acceleration, the normal QT rasterizer is ok, but i don't know how to do it.

Has anyone already done it?

Share this post


Link to post
Share on other sites
Typically what people do, is they'd have their widget own a [url="http://doc.qt.nokia.com/latest/qtimer.html"]QTimer[/url]. They'd then connect the QTimer's timeout() signal to a custom repaint() slot, like this:

[code]connect(&myTimer, SIGNAL(timeout()), this, SLOT(repaint()));[/code]

You'd set the timer's interval to whatever you want, for a fixed rate. For example, you might have it fire only 30 times a second.
If you're doing an emulator, it might be a good idea to use this as a way to artificially slow down the emulator to something close to the speed of the device you are emulating.

If you just want it to run constantly, pass it a interval of 0. A timer with a interval of 0, according to the documentations, will run as fast as possible without slowing down any input or GUI events.

[quote][i]A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system's event queue have been processed.[/i][/quote]

Share this post


Link to post
Share on other sites
[quote name='Servant of the Lord' timestamp='1311395285' post='4839207']
Typically what people do, is they'd have their widget own a [url="http://doc.qt.nokia.com/latest/qtimer.html"]QTimer[/url]. They'd then connect the QTimer's timeout() signal to a custom repaint() slot, like this:

[code]connect(&myTimer, SIGNAL(timeout()), this, SLOT(repaint()));[/code]

You'd set the timer's interval to whatever you want, for a fixed rate. For example, you might have it fire only 30 times a second.
If you're doing an emulator, it might be a good idea to use this as a way to artificially slow down the emulator to something close to the speed of the device you are emulating.

If you just want it to run constantly, pass it a interval of 0. A timer with a interval of 0, according to the documentations, will run as fast as possible without slowing down any input or GUI events.

[quote][i]A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system's event queue have been processed.[/i][/quote]

[/quote]

Alright. Actually, that's exactly what i do for the emulator process. I never thought that would work for painting too.
I will try it and see how it gets...

THanks for the help.

Share this post


Link to post
Share on other sites
Ok. That worked wonderfully.

Now. I'm trying to draw the screen.

I have looked at the QT docs. And it seemes QImage is the best choice.
Still i haven't found a descent example of hoy to do it.

I have my main window application with a menu bar.
And i want the central widget to be the drawing "canvas".

But QT really overcomplicates this by having a lot of widgets which do technically the same thing.(QImage, QPixmap, QPainter......)

Does anyone have any idea what's the optimal and most correct way to so this??

Share this post


Link to post
Share on other sites
QImage, QPixmap and QPainter aren't widgets! They each have their own, distinct purpose.

Typically you'll create a derived QWidget and override its [url="http://doc.qt.nokia.com/latest/qwidget.html#paintEvent"]paintEvent()[/url] to do custom rendering of the widget. In here you'll create a QPainter whose methods you call to draw lines, blit images, etc.

The [url="http://doc.qt.nokia.com/latest/qpainter.html"]QPainter[/url] documentation has links to lots of examples.

Share this post


Link to post
Share on other sites
Ofcourse, depending on your needs, the best 'canvas' may be a [url="http://doc.qt.nokia.com/latest/qgraphicsview.html"]QGraphicsView[/url], using [url="http://doc.qt.nokia.com/latest/qgraphicsscene.html"]QGraphicsScene[/url] and [url="http://doc.qt.nokia.com/latest/qgraphicsitem.html"]QGraphicsItem[/url]. It really depends on what you are doing.

Share this post


Link to post
Share on other sites
Ok. After more reading of the descriptions of each class i'm still kind of confuse.

What i need is to draw the entire widget(canvas) constantly with pixels.

I already have a buffer with the image to show each frame. I need just to paint what is in the buffer to a widget, and as fast as it can. (At least 60 FPS).

Perhaps QGraphisScrene with QGraphicsView may do the job,(I still have to find out how). But isn't QImage useful here???
Because using QPainter you have to set a pen for each color you want paint. and i have thousands of different pixels with different colors. I don't think this is the optimal way of doing it.

Any suggestion?

Share this post


Link to post
Share on other sites
[b]A)[/b] If you are painting each individual [i]pixel [/i]yourself, use QImage, and draw it with QPainter.
[b]B)[/b] If you are painting a bunch of [i]images [/i](You loading images from disk), then load them as QPixmap, and paint them with QPainter.
[b]C)[/b] If you want QT to handle things like drag-and-drop, or mouse clicks, for each individual image, use a QGraphicsView, and inherit each image from a QGraphicsPixmapItem or a QGraphicsItem.

[hr]
[b]A) [/b]If you want your scene to be larger than the size of your widget, so you can scroll around whatever you a drawing with the arrow keys or whatever, and you want QT to handle that scene for you, use QGraphicsView, and make each item a QPixmap, drawn onto the scene with QPainter.
[b]B) [/b]If your scene is the same size as your widget, or if you plan to manually handle scrolling, inherit QWidget and override the drawing.

Share this post


Link to post
Share on other sites
[quote name='Servant of the Lord' timestamp='1311567614' post='4839844']
[b]A)[/b] If you are painting each individual [i]pixel [/i]yourself, use QImage, and draw it with QPainter.
[b]B)[/b] If you are painting a bunch of [i]images [/i](You loading images from disk), then load them as QPixmap, and paint them with QPainter.
[b]C)[/b] If you want QT to handle things like drag-and-drop, or mouse clicks, for each individual image, use a QGraphicsView, and inherit each image from a QGraphicsPixmapItem or a QGraphicsItem.

[hr]
[b]A) [/b]If you want your scene to be larger than the size of your widget, so you can scroll around whatever you a drawing with the arrow keys or whatever, and you want QT to handle that scene for you, use QGraphicsView, and make each item a QPixmap, drawn onto the scene with QPainter.
[b]B) [/b]If your scene is the same size as your widget, or if you plan to manually handle scrolling, inherit QWidget and override the drawing.
[/quote]

Ok. but again, With QPainter i have to set the pen for each individual pixel which is not quite efficient. If i have a resolution of 640*480 with 32 bpp each frame, that would be thousands of pen-sets to draw all the pixel for each frame(consider i want to get as far as 60 fps).

Do i really have to use QPainter or is another way?
Thanks for the help

Share this post


Link to post
Share on other sites
[quote name='Dospro' timestamp='1311621712' post='4840142']
Ok. but again, With QPainter i have to set the pen for each individual pixel which is not quite efficient. If i have a resolution of 640*480 with 32 bpp each frame, that would be thousands of pen-sets to draw all the pixel for each frame(consider i want to get as far as 60 fps).

Do i really have to use QPainter or is another way?
Thanks for the help
[/quote]

Re-read this line:

[quote][b]A)[/b] If you are painting each individual [i]pixel [/i]yourself, use QImage, and draw it with QPainter.[/quote]

That is to say, create a QImage, and fill the pixels using [url="http://doc.qt.nokia.com/latest/qimage.html#setPixel-2"]setPixel()[/url].
Alternatively, operate on raw data, then when finished, pass that raw data to a new QImage using [url="http://doc.qt.nokia.com/latest/qimage.html#QImage-7"]this constructor[/url].

If you draw your data more often then the data changes, you might try converting the QImage to a QPixmap using [url="http://doc.qt.nokia.com/latest/qpixmap.html#fromImage"]QPixmap::fromImage()[/url], and keeping that QPixmap around until the next time you change your data. But profile it to see if it actually speeds anything up, or just slows it down.

Think of it like this: QImage is a buffer of pixels that QPainter can then draw onto your QWidget. You can either manipulate the buffer through QImage, or you can create your own buffer and manipulate that directly, and then just convert it to a QImage when finished.
Also, if you want extra drawing speed, you can convert the QImage to a QPixmap, but the actual conversion itself may negate any speed benefits you gain, so you have to profile it to see if it actually helps or not.

QPixmap is optimized for really fast drawing. QImage is optimized for image manipulation. QBitmap is only for binary masks, so ignore it. QPicture is for a program like MSPaint where someone is drawing a picture, so you can ignore that to.

Read this (from the Qt documentation):
[quote][i]QImage is designed and optimized for I/O, and for direct pixel access and manipulation, while QPixmap is designed and optimized for showing images on screen.[/i][/quote]

But both QImage and QPixmap image you'll have to then use QPainter to actually draw, once you are done editing the pixels. [url="http://doc.qt.nokia.com/latest/qpainter.html#drawImage"]QPainter::drawImage()[/url], or [url="http://doc.qt.nokia.com/latest/qpainter.html#drawPixmap"]QPainter::drawPixmap()[/url].

Share this post


Link to post
Share on other sites
[quote name='Servant of the Lord' timestamp='1311627202' post='4840190']
[quote name='Dospro' timestamp='1311621712' post='4840142']
Ok. but again, With QPainter i have to set the pen for each individual pixel which is not quite efficient. If i have a resolution of 640*480 with 32 bpp each frame, that would be thousands of pen-sets to draw all the pixel for each frame(consider i want to get as far as 60 fps).

Do i really have to use QPainter or is another way?
Thanks for the help
[/quote]

Re-read this line:

[quote][b]A)[/b] If you are painting each individual [i]pixel [/i]yourself, use QImage, and draw it with QPainter.[/quote]

That is to say, create a QImage, and fill the pixels using [url="http://doc.qt.nokia.com/latest/qimage.html#setPixel-2"]setPixel()[/url].
Alternatively, operate on raw data, then when finished, pass that raw data to a new QImage using [url="http://doc.qt.nokia.com/latest/qimage.html#QImage-7"]this constructor[/url].

If you draw your data more often then the data changes, you might try converting the QImage to a QPixmap using [url="http://doc.qt.nokia.com/latest/qpixmap.html#fromImage"]QPixmap::fromImage()[/url], and keeping that QPixmap around until the next time you change your data. But profile it to see if it actually speeds anything up, or just slows it down.

Think of it like this: QImage is a buffer of pixels that QPainter can then draw onto your QWidget. You can either manipulate the buffer through QImage, or you can create your own buffer and manipulate that directly, and then just convert it to a QImage when finished.
Also, if you want extra drawing speed, you can convert the QImage to a QPixmap, but the actual conversion itself may negate any speed benefits you gain, so you have to profile it to see if it actually helps or not.

QPixmap is optimized for really fast drawing. QImage is optimized for image manipulation. QBitmap is only for binary masks, so ignore it. QPicture is for a program like MSPaint where someone is drawing a picture, so you can ignore that to.

Read this (from the Qt documentation):
[quote][i]QImage is designed and optimized for I/O, and for direct pixel access and manipulation, while QPixmap is designed and optimized for showing images on screen.[/i][/quote]

But both QImage and QPixmap image you'll have to then use QPainter to actually draw, once you are done editing the pixels. [url="http://doc.qt.nokia.com/latest/qpainter.html#drawImage"]QPainter::drawImage()[/url], or [url="http://doc.qt.nokia.com/latest/qpainter.html#drawPixmap"]QPainter::drawPixmap()[/url].
[/quote]

Ok. Now i understand. That helped a lot. And it actually works the way i want it now.
I have to see if it is as efficient as i expect yet.
Anyway. For now. Thankyou very much for all your help.

Share this post


Link to post
Share on other sites

This topic is 2333 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this