Search code examples
qtpaintevent

Building a ray tracer with Qt, cannot display pixel by pixel in paintEvent


I am using Qt to build a ray tracer with GUI. The ideal effect is to paint a pixel immediately after computing the RGB value of that pixel, as in most professional renderer. But I find out that my tracer could only display the entire rendered image after the loop below:

for(int i=0; i<row; ++i)
    for(int j=0; j<column; ++j) {
        compute pixel value;
        painter.drawPoint(i, j);
    }

I am drawing to the central widget of the mainwindow. I reimplemented QWidget paintEvent function and put the loop above in this function. It seems that paintEvent only display the whole screen after being executed once and in the process it gives me this:

enter image description here

I don't know if this is just how paintEvent works or I am doing something wrong.

Anyway, it cannot display pixel in real time. And this is very unsatisfying for an interactive tracer. I hope you guys can provide some explanations and/or solutions. A million thanks!


Solution

  • The OS is giving you the "not responsive" alert because you are doing all the calculation in the GUI thread.

    This means that the event loop is stuck at doing your havy calculations and can't process other events.

    On a Windows system, this means it won't react to Windows messages. That's why after a certain time the OS tells you that the application is not responsive.

    You should perform your heavy calculations in a separated thread, pass the results to the GUI thread when you want to update the GUI and let the GUI thread perform the rendering.

    Apart from that, you should consider painting to a backbuffer, as suggested in the comments (although please note that QPixmap is not thread safe).

    QPainter::drawPoint() is very slow and it is an unefficient way to paint the whole central area.

    Please have a look at the documentation here for more details on how to keep the GUI responsive.