由父级绘制 QWidget

Posted

技术标签:

【中文标题】由父级绘制 QWidget【英文标题】:Painting QWidgets by their parent 【发布时间】:2013-04-25 19:33:48 【问题描述】:

我有一个非常不寻常的情况 - 我有一个带有子小部件的小部件,我需要由父级完成子级的绘画,绕过 Qt 5 绘画系统。详细说明:有一个具有 OpenGL 上下文的 QWidget,它在正常的paintEvent() 中进行绘制:

    mRenderer->activate();
    mRenderer->preRender();
    mRenderer->setClearColor(Color(0.75f));
    mRenderer->clear(Renderer::CLEAR_Color);

    QList<RendererWidgetWrapper *> wrappers = findChildren<RendererWidgetWrapper *>();
    foreach (RendererWidgetWrapper *wrapper, wrappers)
        wrapper->paint();

    mRenderer->postRender();

其中 mRenderer 是 OpenGL(或任何其他可能的 3D 渲染器)的包装器。请注意,它在其子代上显式调用paint()。这个paint() 函数只是使用mRenderer 渲染一些东西,因此绕过了正常的Qt 绘制管道。父小部件设置了一些属性:

    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_NoSystemBackground);
    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_PaintUnclipped);

并返回 nullptr 作为其 QPaintEngine。孩子也返回 nullptr 作为 QPaintEngine,但不设置除 Qt::WA_NoSystemBackground 和 Qt::WA_OpaquePaintEvent 之外的任何属性。简而言之 - 整个事情是一种将数百个小部件渲染到其父级拥有的一个 OpenGL 上下文的方法,以避免在许多上下文中杀死系统。 这种方法的问题是孩子都是黑人。有东西正在清除它们的可见区域,我不知道如何使这种黑色消失。有谁知道如何处理它?

编辑:

使用 setUpdatesEnabled(false);删除了黑色背景,但现在子小部件的区域没有更新。而是包含以前在屏幕上可见的内容。

编辑 2:

我发现如果父级具有 Qt::WA_PaintOnScreen 属性,Qt 会创建本机子级窗口,这会导致问题。那么现在的问题是如何避免它,同时强制父窗口变成原生窗口?

【问题讨论】:

【参考方案1】:

如果你想为你的孩子绕过绘画事件,你可以重新实现

virtual void    paintEvent ( QPaintEvent * event );

为他们。像这样:

.h

class QWidgetNoPaintEvent : public QWidget

   //reimplement all ctors here
   virtual void paintEvent ( QPaintEvent * event );

.cpp

void QWidgetNoPaintEvent::paintEvent ( QPaintEvent * event )

 //do nothing, or reject event, or do something custom ???

我不能 100% 确定它是否会解决其他问题,因为它只会通过 Qt 阻止从 QWidgetNoPaintEvent 继承的小部件的绘制事件。

【讨论】:

这并不能解决问题,因为 QWidget::paintEvent() 已经什么都不做了。

以上是关于由父级绘制 QWidget的主要内容,如果未能解决你的问题,请参考以下文章

Unity - 2D 瞄准鼠标,同时限制最小/最大旋转并考虑父级旋转

创建和删除元素

jquery实现nav的下拉

C UNIX 多进程间信号量同步

自动调整 Canvas 的大小以填充封闭的父级

Qt 在不使用线程时从不同的线程设置父级