Issues with QScrollArea and custom widget
-
Hey, long time no see!
How do you build the scroll area, do you have a layout there? Mind showing the code/designer form (screenshot's fine)?
It seems to me your initial values for
width
andheight
are wrong for some reason. You could try painting the widget background red (or a bright color) so you can get a glimpse of what it covers (beside the image itself).PS.
The size hint doesn't do much here, as you've set all things to be fixed size, there's nothing to hint really. ;) -
Hey man! Glad to see you alive :)
How do you build the scroll area, do you have a layout there? Mind showing the code/designer form (screenshot's fine)?
Sure, I have nothing to hide. But then again, there's is nothing really to show.
Here's how I create theQScrollArea
and add it as the central widget of theQMainWindow
:// Central scroll area _centralScrollArea = new QScrollArea(this); _centralScrollArea->setFrameShape(QFrame::NoFrame); _centralScrollArea->setAlignment(Qt::AlignCenter); _centralScrollArea->setWidgetResizable(false); // Central widget QVBoxLayout* centralWidgetLayout = new QVBoxLayout; centralWidgetLayout->addWidget(_toolbar); centralWidgetLayout->addWidget(_centralScrollArea); QWidget* centralWidget = new QWidget(this); centralWidget->setLayout(centralWidgetLayout); setCentralWidget(centralWidget);
_toolBar
is just a regularQToolBar
. I add it in that layout instead of usingQMainWindow::addToolbar()
because I want the toolbar to be between theQDockWidget
s that I have left and right of the central widget.It seems to me your initial values for width and height are wrong for some reason. You could try painting the widget background red (or a bright color) so you can get a glimpse of what it covers (beside the image itself).
What makes you think that the initial values for
width
andheight
of my custom widget are wrong? I checked them and they are fine. The widget is exactly the size I expect it to be. There's really no issue with my custom widget as long as I don't zoom into theQScrollArea
deep enough to make it screw up the aspect ration (and make it fail the panning).PS. The size hint doesn't do much here, as you've set all things to be fixed size, there's nothing to hint really. ;)
I was getting desperate ;)
If it helps, here's the source of my custom widget (the one that I put into the
QScrollArea
): ugfxdisplay.cpp
It's aQWidget
wrapper around theGDisplay
provided by the µGFX library. It's like a virtual display inside of aQWidget
. All it does is proxy stuff around. -
@Joel-Bodenmann said in Issues with QScrollArea and custom widget:
Hey man! Glad to see you alive :)
Surprising, right? ;)
What makes you think that the initial values for width and height of my custom widget are wrong?
We old people often get confused. I noticed something strange about the scrollbars but perhaps that's nothing.
QImage img((const uchar*)pixmapSurface, width(), height(), width()*sizeof(color_t), QImage::Format_RGB32); painter.drawImage(event->rect(), img, img.rect());
Can you check how
width()
relates to_width
and the same for the height here? I'm pretty sure you'd find them to differ. -
Surprising, right? ;)
Not really, given all the "healthy" food you eat ;)
Can you check how width() relates to _width and the same for the height here? I'm pretty sure you'd find them to differ.
Well... how can I say this but:int UGfxDisplay::width() const { return _width; }
I don't see how that could possibly go wrong. Unless... is this a shadowing problem?
-
@Joel-Bodenmann said in Issues with QScrollArea and custom widget:
I don't see how that could possibly go wrong. Unless... is this a shadowing problem?
Possibly, yes, try to rename those two methods to something. To be honest I don't really know what
width()
should return for a widget inside a scroll area, but my spidy sense is tingling. Notice that you get the scrolls when one of the dimensions reaches the scroll area border. That makes me think it's a "bad drawing" on your part, some mismatch of image/widget rects. -
I just checked (using
qDebug()
insideUGfxDisplay::paintEvent()
) and they (UGfxDisplay::_width()
andUGfxDisplay::width()
) are always the same value (and they don't change when zooming).
Keep in mind thatUGfxDisplay::width()
returns the width of my virtual display which is not supposed to change even if the person zooms in. This is not likeQWidget::width()
which would return_width * _scale
(which it does as I always callQWidget::setFixedSize(_scale*_width, _scale*_height)
.I assume that
QScrollArea
callsQWidget::width()
and notUGfxDisplay::width()
as it only has the pointer to theQWidget
anyway.Renaming my
width()
andheight()
methods would be quite an effort as they are used on many places. Is the QtCreator refactoring algorithm up to the task? ;) -
No idea, my code is usually so bad it doesn't need refactoring but plain rewriting. ;)
Anyway, forget that for a moment, can you try something like this:
painter.drawImage(event->rect(), img, img.rect().intersected(event->rect()));
-
@kshegunov said in Issues with QScrollArea and custom widget:
No idea, my code is usually so bad it doesn't need refactoring but plain rewriting. ;)
Still waiting on my
QAbstractModel
merging thingy ;)Anyway, forget that for a moment, can you try something like this:
Here you go: https://www.screencast.com/t/nNbHckWi
-
@Joel-Bodenmann said in Issues with QScrollArea and custom widget:
Still waiting on my QAbstractModel merging thingy ;)
I know, I know.
Here you go: https://www.screencast.com/t/nNbHckWi
Well, something moved at least. Can you get the paint rects you get when zoomin in/out and when you scroll up/down/left/right along with the image rects and dump them all into a file?
-
Hi,
Might be a silly question but how are you handling UGfxDisplay ?
-
@kshegunov said in Issues with QScrollArea and custom widget:
Well, something moved at least. Can you get the paint rects you get when zoomin in/out and when you scroll up/down/left/right along with the image rects and dump them all into a file?
Sure, I'll get that done.
@SGaist said in Issues with QScrollArea and custom widget:
Might be a silly question but how are you handling UGfxDisplay ?
I'm sorry, I don't understand what handling means in this context. Can you be more specific?
-
Are you calling something like
_centralScrollArea->setWidget(_myGDisplay);
?Then, are you sure that you should handle the scaling in
GDisplay
?When zooming, what about having something like
_myGDisplay->resize(_scale * _sourceSize);
So you only handle painting in that widget. -
@kshegunov said in Issues with QScrollArea and custom widget:
Well, something moved at least. Can you get the paint rects you get when zoomin in/out and when you scroll up/down/left/right along with the image rects and dump them all into a file?
Here you go: http://paste.ugfx.io/show/a5113bcc08
@SGaist said in Issues with QScrollArea and custom widget:
Are you calling something like _centralScrollArea->setWidget(_myGDisplay); ?
Yep, that's what I am doing.
@SGaist said in Issues with QScrollArea and custom widget:
When zooming, what about having something like _myGDisplay->resize(_scale * _sourceSize); So you only handle painting in that widget.
In my opinion that won't work as it will not scale up the contents inside of my
UGfxDisplay
. Keep in mind that theQPixmap
I draw in myUGfxDisplay::paintEvent()
is the content of a virtual display. That virtual display has a given size (width and height) in pixels. When zooming in I need to scale up everything. I don't display more of the widget, I just display the same content bigger. -
Have you noticed your image doesn't grow (or shrink)?
-
The image is not supposed to grow. The image represents the contents of the virtual display. It will always have the same amount of pixels no matter how much I zoom into the
UGfxDisplay
widget. My virtual display does not grow by zooming into it :p -
But why are you
redrawingreinitializing it at each paint event then? It got me confused, now I believe I know what you want. Should be something like this (I *think*):painter.drawImage(event->rect(), img, event->rect() / _scale);
PS. Or not. I need to think.
PS. After thinking:QRect paintRect = event->rect(); QRect sourceRect(paintRect.topLeft() / _scale, paintRect.size() / _scale); painter.drawImage(paintRect, img, sourceRect);
-
Wooo, I love you \o/ (still, not again, don't worry honey)
This is with your "After thinking" code: https://www.screencast.com/t/cEAa2z4Zd
In retrospect this seems somewhat obvious...
-
@Joel-Bodenmann said in Issues with QScrollArea and custom widget:
Wooo, I love you
Nice! Love and world peace and such things. ;)
In retrospect this seems somewhat obvious...
Yes, quantum mechanics also seems rather obvious to me ... after a few people thought and invented it. ;)
-
@kshegunov said in Issues with QScrollArea and custom widget:
Yes, quantum mechanics also seems rather obvious to me ... after a few people thought and invented it. ;)
invented? ;)
Too bad those people didn't teach you how to write nice code though :pThank you for your help guys, much appreciated!
-
@Joel-Bodenmann said in Issues with QScrollArea and custom widget:
Too bad those people didn't teach you how to write nice code though :p
This is all a fault of my own, sadly, but hey life's not all roses ... :)
Thank you for your help guys, much appreciated!
You are welcome. Now go and make us proud! ;D