QMdiArea and not scrolling background

  • When I have some QMdiArea with some QMdiSubWindows in it and I move them partially out of the visible area, a scrollbar shows up.

    So far fine.

    Now when I move that scrollbar, the contents of the QMdiArea scrolls, both all QMdiSubWindows and the background.

    Is there some easy way to turn of the scrolling of the background?

    Drawing into the viewport does not work, the paintEvent of the viewport gets never called.

    The only way I currently see is to draw the whole background of the QMdiArea every time a paintEvent happens, I cannot use the events's rect, since it only hold the coordinates of that part which has to be redrawn after scrolling the content.

  • Moderators

    @Wurgl I'm not quite clear on what the problem is. So when you scroll (with your mousewheel?) it is scrolling the content inside the sub windows as well as the area? And you want to stop the area from getting the scroll event?

  • @ambershark Yes! When I scroll (with wheel or with scrollbar) the subwindows inside shall move as normal. But the background (which is an image) should not be moved.

  • Moderators

    @Wurgl Oh I see, you have an image on the background that is scrolling. That makes a lot more sense.

    Try something like this:

    Basically you need to override your MDIArea and handle paint events manually to keep the image drawn on the background after scroll events occur.

  • Okay, I expanded that example to demonstrate my question better, to see what I mean, just copy some logo.jpg to the directory and compile (I used Qt5) Then start the program, move one (or both) subwindows to some very right position, make the main window smaller, this causes the scrollbars to be shown. Then move the scrollbars.

    alt text

    #include <QtWidgets/qmdiarea.h>
    #include <QtWidgets/qmdisubwindow.h>
    #include <QtWidgets/qmainwindow.h>
    #include <QtWidgets/qapplication.h>
    #include <QtWidgets/qboxlayout.h>
    #include <QtGui/qpainter.h>
    class MdiArea : public QMdiArea
        MdiArea(QWidget *parent = 0)
        void paintEvent(QPaintEvent *event)
            QPainter painter(viewport());
            // Calculate the logo position - the bottom right corner of the mdi area.
            int x = width() - m_pixmap.width();
            int y = height() - m_pixmap.height();
            painter.drawPixmap(x, y, m_pixmap);
        // Store the logo image.
        QPixmap m_pixmap;
    class MdiSubWindow : public QMdiSubWindow
        MdiSubWindow(QWidget *parent = 0)
            QWidget *w = new QWidget(this);
            new QVBoxLayout(w);
    int main(int argc, char *argv[])
        QApplication app(argc, argv);
        QMainWindow mainWindow;
        QMdiArea *mdiArea = new MdiArea(&mainWindow);
        MdiSubWindow *w1 = new MdiSubWindow(&mainWindow);
        MdiSubWindow *w2 = new MdiSubWindow(&mainWindow);
        return app.exec();

  • Moderators

    @Wurgl I'll play with this a bit later on or tomorrow and see if I can find a fix for you.

  • Moderators

    @Wurgl Ok I messed around with it quite a bit and I didn't find an easy solution for it.

    I see the problem for sure, but when messing with paint events and such I couldn't find an easy fix.

    Unfortunately I don't have the time to put more effort into fixing it. I'm sure there's a fix for it I just couldn't find it quick enough.

    Some ideas I had were:

    1. Overriding paint events on the scroll area
    2. Overriding paint event on the viewport widget specifically
    3. Setting a custom widget for the viewport that always painted the logo in the corner (this one would be the first I would try).
    4. Catching the "finished scrolling" event and repainting after that with the new coordinates of the corner of the screen. (This should work as well)

    So I didn't have time to test/confirm these but any one of them may work. 3, 4 are the ones I would try first I think.

  • @ambershark I tried:

    • Painting in the scrollarea:
      This does not work at all, I get errors like
    QWidget::paintEngine: Should no longer be called
    QPainter::begin: Paint device returned engine == 0, type: 1

    on the command line (I am using Linux).

    • Painting in viewport::paintEvent():
      Does not work too, viewport::paintEvent() gets never called.

    • messing around with setAutoFillBackground(true) and setAttribute(Qt::WA_OpaquePaintEvent)
      No effect :-(

    At the end I tried to find some hint by looking at the code, did not find any hint.

    BTW: painter.drawPixmap(30, 30, m_pixmap); in the code above makes the example even worth.

    I have one more idea which I did not try: A QWidget which contains QMdiArea as central widget and QMdiArea has a totally transparent color.

  • Moderators

    @Wurgl said in QMdiArea and not scrolling background:

    I have one more idea which I did not try: A QWidget which contains QMdiArea as central widget and QMdiArea has a totally transparent color.

    Did you try my #'s 3 and 4 ideas? Those really should work. I don't have time to test them but I'm betting at least #3 (setting a custom widget for the viewport that can draw the logo correctly) should work.

  • I just got a black rectangle :-(

    Currently I have turned off scrollbars, maybe I try in a few weeks again. Since I have a 4K-monitor there is no real need for scrollbars g

  • Moderators

    @Wurgl If I get more time I'll mess around with it a bit more and try some of my ideas. Just really busy with work and life right now. It's a good time for fishing here, so I'm not in front of my computer as much as normal. ;)

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.