我正在使用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);
}
答案 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,或者您可以根据需要更新逻辑。
希望你觉得它很有用。如果有任何问题,请评论。