How to make a QLabel widget display a QImage object, without first converting it to a QPixmap.

I have been studying the Qt v5.7.1 GUI Library on a private, informal basis, and making progress. As I was doing this, I observed a fact which is generally thought to be true, but which may not always be so.

GUI Libraries such as Qt have a set of object classes defined, which allow geometries to be drawn onto an abstract surface that exists in software, such geometries being Ellipses, Arcs, Rectangles, Polygons, Polylines, Chords etc.. Under Qt5, this is performed by way of the ‘QPainter’ class, together with a ‘QBrush’ and a ‘QPen’ class, and one out of several subclasses of the ‘QPaintDevice’ class. The crux of the operation is, that the ‘QPaintDevice’ class’s subclass needs to specify some sort of pixel buffer, so that the classes ‘QPixmap’ and ‘QImage’ certainly qualify. Multiple other classes also work. These pixel buffers are necessary physically, for the abstract drawing surface to ‘remember’ what the painting operations left behind, in the form of an image.

But what anybody who incorporates this into their Apps’ GUI will want to solve next is, to display the resulting pixel buffer. And an ugly way to do that, which is often used, is to select the ‘QPixmap’ class as the target, and then to do something like this:

 


void MainWindow::resetQ()
{
    delete sw_pixmap;
    sw_pixmap = NULL;
    sw_pixmap = new QPixmap(":/res/images/Unknown.jpg");
    int width = size().width();
    int height = size().height();
    i_label.setPixmap(sw_pixmap->scaled(width - 20, height - 50, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

 

The main problem with this is, that temporary pixmaps are being generated as arguments to function calls, by what I call ‘Naked Constructor Calls’. The compiler will generate temporary objects, and pass them in to the functions being called. And, because those objects were allocated on the stack, as soon as the function returns, they are just popped off the stack, hopefully in a way that results in no memory leaks.

When such temporary objects are simply complex numbers, I can still live with that, But in this case, they are pixel buffers!

Actually, I bent the truth slightly here. The way the function ‘setPixmap()’ is really prototyped, it accepts its argument via a reference. If this were not the case, the code above would truly become ridiculous. However, because of the way arguments are nevertheless presented and then forgotten, the ‘QLabel’ object that called this function still needs to create an internal copy of the pixel map, and must also deallocate the memory once replaced. Further, the temporary object created by ‘sw_pixmap->scaled()‘ is in fact a modified copy of ‘sw_pixmap’, and the compiler sees to it, that it gets deallocated, after the containing function call has returned. Whenever (larger) objects are returned from function-calls by value, they are stored in a special region of memory, managed by the compiler. (:4)

There has got to be a better way, in certain situations, to display whatever pixel buffer was painted to, from a QLabel object. And there is.

(This is a link to the previous exercise.)

(Updated 8/20/2020, 17h10… )

Continue reading How to make a QLabel widget display a QImage object, without first converting it to a QPixmap.