Home > Blockchain >  Map QWidget center position to QGraphicsScene coordinates?
Map QWidget center position to QGraphicsScene coordinates?

Time:04-27

I have a QGraphicsItem with an embedded QWidget, this QWidget have a QPushButton in it. I'm trying to map the center of the QPushButton to the QGraphicsScene coordinates, so for example, I can add a Circle to the center of the QPushButton.

With the help from another post I was able to find the center of the QPushButton, but it doesn't correspond to its actual position in the QGraphicsScene.

enter image description here

What I tried:

  1. Getting the QRect of the button and then its center, finally mapping to the global coordinates of the view.

  2. Getting the QRect of the button, then its center and mapping it to the QGraphicsItem.

  3. Getting the QRect of the button, then its center, mapping it to the QGraphicsItem and than mapping it to the scene.

In general, I tried mapping it to Scene, to Global and to Item but it always looks incorrect. And the farther I move the QGraphicsItem, the less accurate it gets. Here the circle is supposed to be positioned at the center of the "B" button: enter image description here

Qwidget:

class NodeFrame : public QFrame
{
public:
  NodeFrame();
  QRect getButtonRect()
  {
    return layout->itemAt(0)->geometry();
  }
  
private:
  QPushButton* button = nullptr;
  QHBoxLayout* layout = nullptr;
};

NodeFrame::NodeFrame()
{
  setFixedSize(200,80);
  
  // Creates and add a QPushButton to the frame.
  // I need the position of this button on the QGraohicsScene
  button = new QPushButton("B");
  button->setFixedSize(40,20);
  
  layout = new QHBoxLayout();
  layout->addWidget(button);
  layout->setAlignment(Qt::AlignCenter);
  setLayout(layout);
}

QGraphicsItem:

class Node : public QGraphicsItem
{
public:
  Node();
  QRectF boundingRect() const override;
  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
  
  QRect getButtonRect()
  {
    return frame->getButtonRect();
  }
  
  NodeFrame* frame = nullptr;
};

Node::Node()
{
  setFlag(ItemIsMovable);

  // Create a GraphicsProxyWidget to insert the nodeFrame into the scene
  auto proxyWidget = new QGraphicsProxyWidget(this);
  frame = new NodeFrame();
  proxyWidget->setWidget(frame);
  // Center the widget(frame) at the center of the QGraphicsItem
  proxyWidget->setPos(boundingRect().center() - proxyWidget->boundingRect().center());
}

QRectF Node::boundingRect() const
{
  return QRectF(-10, -10, 280, 150);
}

void Node::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
  QPainterPath path;
  path.addRoundedRect(boundingRect(), 10, 10);
  painter->drawPath(path);
}

main:

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);
  
  // Create scene and view
  auto scene = new QGraphicsScene();
  auto view = new QGraphicsView(scene);
  
  view->setMinimumSize(800, 800);
  
  // Create the QGraphicsItem and add it to the scene
  auto item = new Node();
  scene->addItem(item);
  item->setPos(50, 50);

  
  auto btnRect = item->getButtonRect();
  auto center = view->mapToGlobal(btnRect.center());
  auto circle = new QGraphicsEllipseItem();
  circle->setRect(QRectF(center.x(), center.y(), 25, 25));
  scene->addItem(circle);


  // Show the the view
  view->show();
  return app.exec();
}

Appreciate any help.

CodePudding user response:

Solved. This was caused by two things:

1: QRectF getButtonRect() was returning layout->itemAt(0)->geometry(), (index 0 being the first and only widget in the layout) but button->frameGeometry() seems to be a more accurate visual representation of the button's geometry.

2: When adding the widget to the graphic item using QGraphicsProxyWidget, I was adjusting the position of the widget inside the graphic item using:

proxyWidget->setPos(boundingRect().center() - proxyWidget->boundingRect().center());

This was changing the position (obviously) of the widget inside the graphic item, so visually it didn't align with the result given by button->frameGeometry().

  •  Tags:  
  • c qt
  • Related