如何在子窗口小部件上绘制一条线而不是父窗口小部件?

时间:2017-03-11 05:55:38

标签: c++ qt widget

我正在尝试在QWidget上绘制一条线(以及其他一些原语)。 QWidget实际上是“在另一个小部件之上”,其中有一张图片。我想在图片上画线条和圆圈。

我知道如何绘制一条线。我可以用这段代码来做到这一点:

bool MySpecialWidget::eventFilter( QObject* watched, QEvent* event )
{
    if (watched == this && event->type() == QEvent::Paint)
    {
        QPainter painter(this);

        painter.translate(50, 50);

        painter.setPen(QPen(Qt::blue, 12));
        painter.setBrush(Qt::BrushStyle::SolidPattern);
        painter.drawLine(0, 0, 200, 200);
    }

    return false;
}

但我真正想做的是定位一个小部件来保存图片,然后将小部件放在它上面以保持线条。像这样:

MySpecialWidget::MySpecialWidget(QWidget *parent) : QWidget(parent)
{
    QRect position = QRect(30, 50, 600, 600);

    pictureBox = new QLabel(parent);
    pictureBox->setGeometry(position);
    pictureBox->setPixmap(QPixmap(QString::fromUtf8(":/main/graphics/MyPicture.png")));
    pictureBox->setScaledContents(true);

    drawnElements = new QWidget(parent);
    drawnElements->setGeometry(position);
    drawnElements->raise();

    this->installEventFilter(this);
}

然后绘制线条和图元,我想这样做:

bool MySpecialWidget::eventFilter( QObject* watched, QEvent* event )
{
    if (watched == this && event->type() == QEvent::Paint)
    {
        QPainter painter(drawnElements);

        painter.translate(50, 50);

        painter.setPen(QPen(Qt::blue, 12));
        painter.setBrush(Qt::BrushStyle::SolidPattern);
        painter.drawLine(0, 0, 200, 200);
    }

    return false;
}

但这不起作用。什么都没画。空白。

问题是读取QPainter painter(drawnElements);

的行

如果我说QPainter painter(this);,它会绘制一些内容,但它不在子窗口小部件上,而是在父窗口小部件上。

2 个答案:

答案 0 :(得分:1)

关于这个主题的文件很清楚:

  

每个小部件都在其中执行所有绘制操作   paintEvent()函数。只要小部件需要,就会调用此方法   重新绘制,或者由于某些外部更改或在请求时重新绘制   通过申请。

您应该只从其绘制事件中绘制一个小部件,并且您应该只绘制该特定小部件。

答案 1 :(得分:0)

  

问题是读取QPainter painter(drawnElements);

的行

当然。您需要改为观看目标小部件并捕获其绘制事件。要控制绘图顺序,您还应该将事件明确地传递给目标。

bool MySpecialWidget::eventFilter( QObject* watched, QEvent* event )
{
    //         *** vvvvvvvvvvvvv *** (A)
    if (watched == drawnElements && event->type() == QEvent::Paint)
    {
        // Let the target draw itself first.
        watched->event(event);
        // Then overlay our content on it.
        //           *** vvvvvvvvvvvvv *** (B) - must match (A)!
        QPainter painter(drawnElements);
        painter.translate(50, 50);
        painter.setPen(QPen(Qt::blue, 12));
        painter.setBrush(Qt::BrushStyle::SolidPattern);
        painter.drawLine(0, 0, 200, 200);
        return true; // The event is already handled.
    }
    return false;
}

MySpecialWidget::MySpecialWidget(QWidget *parent) : QWidget(parent)
{
    //...
    drawnElements->installEventFilter(this);
}

您也可以考虑使用overlay widget