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.
-
@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.
-
@Wurgl Oh I see, you have an image on the background that is scrolling. That makes a lot more sense.
Try something like this:
http://stackoverflow.com/questions/19852594/image-on-qt-qmdiarea-backgroundBasically 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.
#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 { public: MdiArea(QWidget *parent = 0) : QMdiArea(parent), m_pixmap("logo.jpg") { setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); } protected: void paintEvent(QPaintEvent *event) { QMdiArea::paintEvent(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); } private: // Store the logo image. QPixmap m_pixmap; }; class MdiSubWindow : public QMdiSubWindow { public: MdiSubWindow(QWidget *parent = 0) : QMdiSubWindow(parent) { QWidget *w = new QWidget(this); setWidget(w); new QVBoxLayout(w); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow mainWindow; QMdiArea *mdiArea = new MdiArea(&mainWindow); mainWindow.setCentralWidget(mdiArea); MdiSubWindow *w1 = new MdiSubWindow(&mainWindow); mdiArea->addSubWindow(w1); w1->show(); MdiSubWindow *w2 = new MdiSubWindow(&mainWindow); mdiArea->addSubWindow(w2); w2->show(); mainWindow.show(); return app.exec(); }
-
@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:
- Overriding paint events on the scroll area
- Overriding paint event on the viewport widget specifically
- Setting a custom widget for the viewport that always painted the logo in the corner (this one would be the first I would try).
- 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.
- Painting in the scrollarea:
-
@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.