在 QGraphicsScene 上绘制 QGraphicsItem 的正确方法

Correct way to draw a QGraphicsItem on QGraphicsScene

我在 qt 的网站和此处查看了一些资源,但无法解决我的问题。

我试图在单击鼠标时在 QGraphicsScene 上绘制一个矩形,我希望新矩形正好在用户单击的位置居中,但这在场景足够大之前不起作用。

这是我试过的

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);
=
   ui->graphView->setContextMenuPolicy(Qt::CustomContextMenu);
   scene = new QGraphicsScene();
   ui->graphView->setScene(scene);
...
}


    void MainWindow::on_graphView_customContextMenuRequested(const QPoint &pos)
    {
     auto pp= ui->graphView->mapToScene(pos);
    tableOfRectangles.push_back( new component(pp,s,n,t)); //component is my class that inherits from qgraphicsitem
     scene->addItem(tableOfRectangles[tableOfRectangles.size()-1]);
    }

并在 compenent.cpp

component::component(QPointF pos,unsigned int id, QString cname, QString ctype  )
{
    this->center = pos;
    this->id = id;
    this->name = cname;
    this->type = ctype;
    setFlag(ItemIsMovable);


}

QRectF component::boundingRect() const
{

    return QRectF(center.x(),center.y(),80,80);
}


我的问题是:

第一个矩形是在中间绘制的,随着我向正确位置添加的越多,它会继续轻微移动。通过添加更多矩形(或拖动现有矩形)使场景足够大(当滚动条开始出现时),新矩形将正确添加到鼠标位置。但是我该如何强制将它们从一开始就插入到正确的位置?

您正在将相对于项目的 boundingRect 坐标与相对于场景的坐标结合起来。另一方面,不要使创建自定义项复杂化,而是使用自定义 QGraphicsRectItem。最后建议大家建立一个sceneRect。

component.h

#ifndef COMPONENT_H
#define COMPONENT_H

#include <QGraphicsRectItem>

class Component : public QGraphicsRectItem
{
public:
    Component(unsigned int id, QString cname, QString ctype, QGraphicsItem *parent=nullptr);
private:
    unsigned int m_id;
    QString m_cname;
    QString m_ctype;
};

#endif // COMPONENT_H

component.cpp

#include "component.h"

Component::Component(unsigned int id, QString cname, QString ctype, QGraphicsItem*parent):
    QGraphicsRectItem(parent), m_id(id), m_cname(cname), m_ctype(ctype)
{
    setRect(-40, -40, 80, 80);
    setFlag(ItemIsMovable);
}
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->graphView->setContextMenuPolicy(Qt::CustomContextMenu);
    scene = new QGraphicsScene();
    ui->graphView->setScene(scene);
    ui->graphView->setSceneRect(QRect(0, 0, 400, 400));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_graphView_customContextMenuRequested(const QPoint &pos)
{

    QPointF pp = ui->graphView->mapToScene(pos);
    Component* component = new Component(s, n, t);
    scene->addItem(component);
    component->setPos(pp);
}