Reputation: 6840
I'm using Qt and C++ to create a custom widget I call ThumbnailView, which allows for left/right scrolling of thumbnail images:
class ThumbnailView : public QWidget {
public:
virtual void paintEvent(QPaintEvent *);
private:
QList<Thumbnail*> thumbList;
};
The ThumbnailView keeps an internal list of Thumbnail objects, which are also QWidget objects:
class Thumbnail : public QWidget
{
public:
virtual void paintEvent(QPaintEvent *);
};
I embed the ThumbnailView into a PreviewPane object I created:
class PreviewPane : public QWidget {
public:
virtual void paintEvent(QPaintEvent *);
private:
ThumbnailView thumbnailView;
};
When the main application loads, I create a dock widget and add the PreviewPane:
previewPaneDock = new QDockWidget(QString("PREVIEW"), this);
previewPane = new PreviewPane;
previewPaneDock->setWidget(previewPane);
this->addDockWidget(Qt::RightDockWidgetArea, previewPaneDock, Qt::Vertical);
So the idea is this: the dock widget has its widget set to previewPane, which in turn handles custom painting via paintEvent() and all mouse events (which I have omitted here). The previewPane's paintEvent does this:
void PreviewPane::paintEvent(QPaintEvent *)
{
QPainter painter(this);
...
thumbnailView.render(&painter);
}
The render() method is inherited from QWidget; this causes ThumbnailView::paintEvent() to be called:
void ThumbnailView::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QList<Thumbnail*>::iterator itr;
int curX = 0;
for (itr = thumbList.begin(); itr != thumbList.end(); ++itr) {
curX += (*itr)->width();
if (curX < xScrollOffset) continue;
(*itr)->render(&painter, QPoint(curX - xScrollOffset - (*itr)->width(), 0));
if (curX - xScrollOffset >= this->width() ) break;
}
}
As you can see, the render() method is called again on each instance of Thumbnail.
Up to this point, there are no problems, and everything works as I expect it to. ThumbnailView allows the user to scroll left/right through a list of images (Thumbnail objects) by using a timer and kinetic scrolling using mouse flicks (or touch flicks).
I've embedded a ThumbnailView onto the PreviewPane, but the ThumbnailView isn't the only thing I want on the PreviewPane, and I want to be able to specify the origin at which the widget should start drawing--this is what I tried:
void PreviewPane::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// specify a target offset of 10 pixels in y direction
thumbnailView.render(&painter, QPoint(0, 10));
}
which seems to have the same effect as this:
void PreviewPane::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.translate(0, 10);
thumbnailView.render(&painter);
}
What I am expecting to happen is that the 10 pixel y-offset that I've specified to the paint transform will be passed to ThumbnailView::paintEvent(). Instead, it seems that this 10 pixel offset is propgated to each Thumbnail object, but instead of translating the Thumbnail widget, it crops it!
I've tried printing things like painter.combinedTransform().dy() and painter.worldTransform().dy() but they are always 0. Does anyone have some insight as to what happens when painter.translate() is called, or what the targetOffset parameter does in the function QWidget::render()?
Upvotes: 6
Views: 9608
Reputation: 98425
In QtWidgets, all painting is clipped. It would seem that you need to apply an offset to both the painter and the clip rectangle.
Upvotes: 3