【问题标题】:How to draw a line on a child widget instead of the parent widget?如何在子小部件而不是父小部件上画一条线?
【发布时间】:2017-03-11 05:55:38
【问题描述】:

我正在尝试在 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);,它会绘制一些东西,但它不在子小部件上,而是在父小部件上。

【问题讨论】:

    标签: c++ qt widget


    【解决方案1】:

    文档在这个主题上非常清楚:

    每个小部件都在其内部执行所有绘画操作 油漆事件()函数。每当需要小部件时调用它 由于某些外部更改或在请求时重绘 由应用程序。

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

    【讨论】:

      【解决方案2】:

      问题在于QPainter painter(drawnElements);这一行

      当然。您需要改为观看 target 小部件并捕捉其绘制事件。要控制绘制顺序,您还应该将事件显式传递给目标。

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-01
        • 1970-01-01
        • 2019-01-14
        • 1970-01-01
        • 2020-01-01
        • 1970-01-01
        • 2017-10-08
        • 1970-01-01
        相关资源
        最近更新 更多