c++ - 使用 QWidget::render() 绘制绘制其他小部件的小部件(自定义 paintEvent)

标签 c++ qt qwidget

我正在使用 Qt 和 C++ 创建一个自定义小部件,我称之为 ThumbnailView,它允许左右滚动缩略图:

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

ThumbnailView 保留了一个 Thumbnail 对象的内部列表,这些对象也是 QWidget 对象:

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

我将 ThumbnailView 嵌入到我创建的 PreviewPane 对象中:

class PreviewPane : public QWidget {
public:
  virtual void paintEvent(QPaintEvent *);
private:
  ThumbnailView thumbnailView;
};

当主应用程序加载时,我创建一个停靠小部件并添加 PreviewPane:

previewPaneDock = new QDockWidget(QString("PREVIEW"), this);
previewPane     = new PreviewPane;
previewPaneDock->setWidget(previewPane);
this->addDockWidget(Qt::RightDockWidgetArea, previewPaneDock, Qt::Vertical);

所以想法是这样的:停靠小部件将其小部件设置为 previewPane,它又通过 paintEvent() 和所有鼠标事件(我在这里省略了)处理自定义绘画。 previewPane 的 paintEvent 执行此操作:

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

render()方法继承自QWidget;这会导致调用 ThumbnailView::paintEvent():

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;
  }
}

如您所见,在每个 Thumbnail 实例上再次调用 render() 方法。

到目前为止,没有任何问题,一切都按我预期的那样进行。 ThumbnailView 允许用户使用计时器向左/向右滚动图像列表(缩略图对象),并使用鼠标轻弹(或触摸轻弹)进行动态滚动。

我已经在 PreviewPane 上嵌入了一个 ThumbnailView,但 ThumbnailView 并不是我想要在 PreviewPane 上唯一的东西,我希望能够指定小部件应该开始绘制的原点——这就是我试过:

void PreviewPane::paintEvent(QPaintEvent *)
{      
    QPainter painter(this);
    // specify a target offset of 10 pixels in y direction
    thumbnailView.render(&painter, QPoint(0, 10));
}

这似乎与此具有相同的效果:

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

我期望发生的是,我指定给绘画变换的 10 像素 y 偏移量将传递给 ThumbnailView::paintEvent()。相反,似乎这个 10 像素的偏移量被传播到每个 Thumbnail 对象,但它不是平移 Thumbnail 小部件,而是裁剪它! Examples 我试过打印 painter.combinedTransform().dy() 和 painter.worldTransform().dy() 之类的东西,但它们始终为 0。有没有人对调用 painter.translate() 时发生的事情有一些了解,或者 targetOffset 参数在函数 QWidget::render() 中做了什么?

最佳答案

在 QtWidgets 中,所有绘画都被剪裁。看起来您需要对画家和剪辑矩形应用偏移量。

关于c++ - 使用 QWidget::render() 绘制绘制其他小部件的小部件(自定义 paintEvent),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18042969/

相关文章:

python - 如何让按钮随着窗口大小的调整而移动? (PyQt4)

c++ - 如何使用多重继承执行转换

c++ - QTimer::SingleShot 在删除对象后触发

c++ - 使用打开的端口获取应用程序

C++ 指针设置为地址,但在程序的不同部分莫名其妙地指向不同的值

qt - 如何为 QMacStyle 获取整个 Qt 样式表

c++ - 如何让图形保持在主窗口的中央

c++ - QWidget继承自自定义QWidget

c++ - 在已经初始化我的 2d 矩阵后动态增加行数

c++ - CodeSourcery 给出编译错误 : missing bits/c++config. h