使用Qt中的事件过滤器绘制多边形

时间:2014-09-17 06:18:26

标签: qt filter polygon

我正在使用GUI中的一个功能,允许用户通过单击点来绘制多边形。 首先,用户需要通过单击按钮启用此功能。之后,用户点击屏幕上的任意四个点。单击第四个点时,将连接所有4个点以形成多边形。

但是,单击第四个多边形后,多边形不会出现。而是有一条消息" QPainter :: begin:Paint device return engine == 0,type:1"。我的代码有什么问题?

bool QTGraphicsShape::eventFilter(QObject *obj, QEvent *event)
{
    double static x[4],y[4];
    int static i;
    if ((event->type() ==  QEvent::GraphicsSceneMouseRelease) && (Draw3Points == true)) {
    QGraphicsSceneMouseEvent *mouseEvent = static_cast< QGraphicsSceneMouseEvent* >( event );
    QPointF img_coord_pt = mouseEvent->scenePos();
    x[i] = img_coord_pt.x();
    y[i] = img_coord_pt.y();
    i++;
    if (i >= 4)
    {
        Draw3Points = false;
        i=0;
        static const QPointF points[4] = {
            QPointF(x[0], y[0]),
            QPointF(x[1], y[1]),
            QPointF(x[2], y[2]),
            QPointF(x[3], y[3])
        };
        QPainter painter(this);
        painter.drawPolygon(points, 4);
    }
    return true;
  } else {
    return QObject::eventFilter(obj, event);
  }
}

void QTGraphicsShape::on_pushButton_clicked()
{
    ui.graphicsView->setMouseTracking(true);
    Draw3Points = true;
    m_pGraphicsScene->installEventFilter(this);
}

1 个答案:

答案 0 :(得分:0)

为什么使用eventFilter(..)绘制多边形?
如您的代码所示,您正在使用QGraphicsScene / View
你可以看到下面的实现..
 注意:虽然以下实现用于在点击点上绘制一条线,但您可以将其更改为绘制多边形..

您可以派生图形视图/场景并覆盖mousePressEvent

下面是使用派生的QGraphicsScene和重写的mousePressEvent

的示例

班级定义:

class MyScene : public QGraphicsScene

数据成员:

QList<QPointF> m_clickPositions;
int m_mode;

代码:

void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(false == sceneRect().contains(event->scenePos()))
    {
        QGraphicsScene::mousePressEvent(event);
    }
    else if(Qt::LeftButton == event->button() && m_mode == ConstructMode)
    {
        m_clickPositions.append(event->scenePos());

        if(m_clickPositions.size() == 2)
        {
            QLineF lineF(m_clickPositions[0], m_clickPositions[1]);
            QGraphicsLineItem* item = this->addLine(lineF);
            m_clickPositions.clear();
            m_mode = ScrollMode;
        }
    }
    else
    {
        QGraphicsScene::mousePressEvent(event);
    }
}

希望你觉得这很有用。 如果您有任何问题,请发表评论

编辑:: 在上述代码中添加了激活构造模式的逻辑。

ConstructMode和Scroll模式在上面的程序中使用,以便我可以区分是否要绘制/构造或只是滚动场景。

如果要使用这些模式,可以定义一些公共常量并添加方法setMode()。请参阅下面的代码。

MyScene.h或一些常量文件(如果你有一个

#define ConstructMode 100
#define ScrollMode 101

并添加以下功能

void MyScene::setMode(int mode)
{
    m_mode = mode;
}

在此之后如果要进入构造模式,则每次都需要调用myScene->setMode(ConstructMode),因为在构建项目后,模式将重置为ScrollMode,或者您可以根据需要更新逻辑。

希望你觉得它很有用。如果有任何问题,请评论。