Using QWidget :: render () to draw widgets that other widgets draw (custom paintEvent)

I use Qt and C ++ to create a custom widget, which I call ThumbnailView, which allows you to scroll thumbnails left / right:

class ThumbnailView : public QWidget { public: virtual void paintEvent(QPaintEvent *); private: QList<Thumbnail*> thumbList; }; 

ThumbnailView stores an internal list of Thumbnail objects, which are also QWidget objects:

 class Thumbnail : public QWidget { public: virtual void paintEvent(QPaintEvent *); }; 

I am inserting a ThumbnailView into the PreviewPane object that 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 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 own widget installed on previewPane, which, in turn, processes the user painting through paintEvent () and all mouse events (which I missed here). PreviewPane paintEvent does this:

 void PreviewPane::paintEvent(QPaintEvent *) { QPainter painter(this); ... thumbnailView.render(&painter); } 

The render () method inherits from QWidget; this calls the ThumbnailView :: paintEvent () call:

 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 for each instance of Thumbnail.

There are no problems up to this point, and everything works as I expect. ThumbnailView allows the user to scroll left / right through the list of images (thumbnail objects) using a timer and kinetic scrolling using mouse clicks (or touch clicks).

I turned on ThumbnailView on the PreviewPane, but ThumbnailView is not the only thing I want on the PreviewPane, and I want to indicate the source where 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 one:

 void PreviewPane::paintEvent(QPaintEvent *) { QPainter painter(this); painter.translate(0, 10); thumbnailView.render(&painter); } 

I expect that the 10-pixel offset y that I pointed to paint conversion will be passed to ThumbnailView :: paintEvent (). Instead, it seems that this 10-pixel offset is programmed for each Thumbnail object, but instead of translating the Thumbnail widget, it trims it! Examples I tried typing things like painter.combinedTransform (). Dy () and painter.worldTransform (). Dy (), but they are always 0. Does anyone have an idea of ​​what happens when painter.translate () is called, or what does the targetOffset parameter do in the QWidget :: render () function?

+4
source share
1 answer

In QtWidgets, the whole picture is cropped. It would seem that you need to apply the offset to both the painter and the rectangle of the clip.

+1
source

Source: https://habr.com/ru/post/1495186/


All Articles