Qt:在子部件上使用 QPainter

Posted

技术标签:

【中文标题】Qt:在子部件上使用 QPainter【英文标题】:Qt: Using QPainter on child widgets 【发布时间】:2009-10-30 00:43:07 【问题描述】:

我在一个简单的QWidget 程序中遇到了 Qt/C++ 问题,该程序在子 QWidget 内绘制了一个椭圆。

程序由以下部分组成: (1) 一位家长QWidget (2) 一个孩子QWidget(用作椭圆的绘图表面) (3) 平局QPushButton

这是部分代码(QPushButton Slot 和 Signal 代码为简单起见省略)

void Draw::paintEvent(QPaintEvent *event) 
    QPainter painter;
    painter.begin(child_Widget);    //The line with the problem
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(QPen(Qt::black, 12, Qt::DashDotLine, Qt::RoundCap));
    painter.setBrush(QBrush(Qt::green, Qt::SolidPattern));
    painter.drawEllipse(50, 50, 100, 100);
    painter.end();

第 2 行 painter.begin(child_Widget); 不执行任何操作。仅当我将第 2 行替换为 painter.begin(this); 时,程序才会绘制椭圆,但这会根据需要在父 QWidget 而不是子 QWidget 上绘制。

附:我将 child_Widget 放置在 GroupBox 中,而 GroupBox 又放置在 QVBoxLayout 中。

有什么建议吗?

谢谢。

【问题讨论】:

【参考方案1】:

我会尝试的第一件事是在子小部件上安装一个事件过滤器(请参阅QObject::installeEventFilter()),然后在父小部件中,抓住 QEvent::Paint 事件,并在那里进行绘画。

在哪里创建子小部件:

// ... childWidget = new QWidget(this); childWidget->installEventFilter(this); // ...

然后在父级中:

bool Draw::eventFilter(QObject* 观看,QEvent* 事件) if (watched == childWidget && event->type() == QEvent::Paint) QPainter 画家; 画家.开始(childWidget); Painter.setRenderHint(QPainter::Antialiasing, true); Painter.setPen(QPen(Qt::black, 12, Qt::DashDotLine, Qt::RoundCap)); Painter.setBrush(QBrush(Qt::green, Qt::SolidPattern)); 画家.drawEllipse(50, 50, 100, 100); 画家.end(); 返回真; // 如果您不想让子小部件之后自行绘制,则返回 true,否则返回 false。 返回假;

【讨论】:

【参考方案2】:

如QPainter documentation中所述

警告:当paintdevice是一个小部件时,QPainter只能在paintEvent()函数内部或由paintEvent()调用的函数中使用;除非设置了 Qt::WA_PaintOutsidePaintEvent 小部件属性。在 Mac OS X 和 Windows 上,无论该属性的设置如何,您都只能在 paintEvent() 函数中进行绘制。

如果您想在该小部件上绘图,您需要从它自己的paintEvent() 中进行。

【讨论】:

linuxman,我该怎么做呢?我最初将子小部件放在它自己的类中作为在父小部件类中实例化的渲染区域,但我最终将两者合并到一个类中 b/c 我需要渲染区域来访问父小部件类的成员,并且使用friend关键字不起作用。还有其他设备(除了 QWidget)我可以使用 QPainter 绘制椭圆吗? 通过继承它并重新实现它的paintEvent()函数。【参考方案3】:

您可以在像素图上绘制并在小部件绘制事件中绘制像素图。它可以是任何函数或插槽,不一定是绘画事件,例如您可以有多个用于绘制不同的对象。您可以从像素图上的任何位置绘制,使用绘制事件的要求仅适用于将绘制像素图的小部件。如果是一个复杂的场景,你甚至可以在另一个线程中绘制,并且只在主线程中更新像素图的结果。

【讨论】:

以上是关于Qt:在子部件上使用 QPainter的主要内容,如果未能解决你的问题,请参考以下文章

QT在子窗口外单击关闭子窗口

在QOpenGLWidget上使用Qt5小部件而不重写?

为啥我想在 Qt 小部件上绘制的“矩形”没有出现?

QT之设计部件背景色

在子小部件中,如何在 kivy 中获取父小部件的实例

如何关闭在提升的小部件中单击的按钮上的 qt 小部件 ui?