gpt4 book ai didi

c++ - QGraphicsScene 项目在两次 (x2) 位置绘制

转载 作者:行者123 更新时间:2023-11-30 04:45:42 27 4
gpt4 key购买 nike

(警告交叉发布于:https://forum.qt.io/topic/105158/qgraphicsscene-item-is-drawn-at-twice-x2-position)

在下面的代码中,我创建了一个自定义小部件,其中嵌入了 QGraphicsScene 的子类。我的目标是单击并向场景添加一个点。一个点是我的 QGraphicsItem (GIPoint) 的子类。我想移动那个点,然后将它连接到其他点并制作一条样条路径。

我面临的问题是点不是绘制在我单击的位置,而是绘制在通过将鼠标事件的 scenePos() 坐标加倍形成的位置。因此,如果我在 (100,100) 处单击,则该点将绘制在 (200,200) 处。尽管阅读了文档,但我怀疑我误解了坐标系。

问题How to add item in a QGraphicsScene?似乎是相关的,但是通过 mapToScene(event->pos()); 转换鼠标事件坐标的建议解决方案实际上加倍了位置(在它打印它绘制在相同位置之前,它会然后是 x2。现在它也将其打印为 x2)。

因此,我还要求向我指出一些关于小部件放置如何工作的简单易懂的建议。顺便提一句。是 QRectF GIPoint::boundingRect() const {
返回 QRectF(pos().x(), pos().y(), 5, 5);
关于矩形的 (x,y) 坐标是否正确?

我的示例代码如下:

/* use the following pro:
QT += widgets core gui

CONFIG += debug console
SOURCES = example.cpp
TARGET = example
*/
#include <QGraphicsItem>
#include <QPainter>
#include <QWidget>
#include <QRectF>
#include <QPointF>
#include <QGraphicsScene>
#include <QStyleOptionGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QKeyEvent>
#include <QGraphicsView>
#include <QApplication>
#include <QOpenGLWidget>
#include <QMainWindow>
#include <QGridLayout>
#include <QDebug>

class GIPoint : public QGraphicsItem{
public:
GIPoint(QGraphicsItem * parent, const QPointF &position);
protected:
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
QRectF boundingRect() const override;
void paint(
QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget
);
};
class GraphicsSceneWidget : public QGraphicsScene {

public:
explicit GraphicsSceneWidget(QObject *parent);
~GraphicsSceneWidget();
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
};

class VectorGraphicsWidget : public QWidget {
public:
VectorGraphicsWidget(QWidget *parent);
~VectorGraphicsWidget();
private:
GraphicsSceneWidget *myGraphicsSceneWidget;
};

// implementation
GIPoint::GIPoint(
QGraphicsItem *parent,
const QPointF &position
) : QGraphicsItem(parent) {
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setPos(position);
qWarning() << "GIPoint::GIPoint() : init at " << position;
}
QVariant GIPoint::itemChange(
GraphicsItemChange change,
const QVariant &value
){
if (change == QGraphicsItem::ItemPositionChange) {
qWarning("position changed");
}
return value;
}
QRectF GIPoint::boundingRect() const {
return QRectF(pos().x(), pos().y(), 5, 5);
// return QRectF(0,0, 5, 5);
}
void GIPoint::paint(
QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget
){
(void )option;
(void )widget;
QPointF xx = scenePos();
QRectF rect = QRectF(xx.x(), xx.y(), 10, 10);
qWarning() << "painting: scenePos " << scenePos() << ", rect " << rect;
QBrush brush = QBrush(Qt::black, Qt::SolidPattern);
//painter->fillRect(rect, brush);
painter->drawRect(rect);
}

GraphicsSceneWidget::GraphicsSceneWidget(QObject *parent)
: QGraphicsScene(parent)
{}
GraphicsSceneWidget::~GraphicsSceneWidget(){}
void GraphicsSceneWidget::mousePressEvent(
QGraphicsSceneMouseEvent *event
){
GIPoint *gip = new GIPoint(Q_NULLPTR, event->scenePos());
addItem(gip);
QGraphicsScene::mousePressEvent(event);
}

VectorGraphicsWidget::VectorGraphicsWidget(QWidget *parent) :
QWidget(parent)
{
myGraphicsSceneWidget = new GraphicsSceneWidget(this);
QGraphicsView *view = new QGraphicsView(myGraphicsSceneWidget);
myGraphicsSceneWidget->setSceneRect(QRectF(0, 0, 500, 500));
QGridLayout *centralLayout = new QGridLayout;
centralLayout->addWidget(view);
setLayout(centralLayout);
myGraphicsSceneWidget->addRect(
QRectF(0, 0, 100, 100),
QPen(Qt::black),
QBrush(Qt::green)
);
view->show();
}
VectorGraphicsWidget::~VectorGraphicsWidget() {
delete myGraphicsSceneWidget;
}
int main(int argc, char **argv){
QApplication app(argc, argv);
app.setApplicationName("test");
app.setOrganizationName("myorg");
app.setOrganizationDomain("myorg.com");

QMainWindow *w = new QMainWindow();
w->resize(500, 500);
w->setCentralWidget(new VectorGraphicsWidget(Q_NULLPTR));
w->show();

return app.exec();
}

最佳答案

问题在于 boundingRect()paint() 方法遵循项目的坐标系,而不是场景。所以解决方案不是在这两种方法中都使用 scenePos(),而是使用 0, 0:

QRectF GIPoint::boundingRect() const {
return QRectF(0, 0, 10, 10);
}
void GIPoint::paint(
QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget
){
(void )option;
(void )widget;
QRectF rect = QRectF(0, 0, 10, 10);
qWarning() << "painting: scenePos " << scenePos() << ", rect " << rect;
QBrush brush = QBrush(Qt::black, Qt::SolidPattern);
painter->fillRect(rect, brush);
painter->drawRect(rect);
}

尽管我建议使用 QGraphicsRectItem,因为它实现了您所做的一切。

关于c++ - QGraphicsScene 项目在两次 (x2) 位置绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57118393/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com