获取 QGraphicsItem 内的 QWidget 的位置
Get the position of a QWidget that is inside a QGraphicsItem
我有一个带有 QPushButton 的 QWidget,同时,这个 QWidget 被嵌入到 QGraphicsItem 中,它位于 QGraphicsScene 中。
我需要在两个指向 QPushButton 的 QGraphicsItems 之间画一条线。为此,我需要获得 QPushButton 的位置。它看起来像这样:
我尝试在 QGraphicsItem 的构造函数中获取 QPushButton 的位置,但它 returns 0,0。我猜这是 QWidget 中按钮的位置。我想我需要的是一种获取屏幕位置的方法。
最小示例:尽可能简化。
QWidget:
NodeFrame::NodeFrame()
{
setFixedSize(200,80);
setStyleSheet("QFrame { background-color: #2e4076; }");
// Creates and add a QPushButton to the frame.
// I need the position of this button on the QGraohicsScene
auto button = new QPushButton("B");
button->setFixedSize(40,20);
auto layout = new QHBoxLayout();
layout->addWidget(button);
setLayout(layout);
}
QGraphicsItem:
class Node : public QGraphicsItem
{
public:
Node();
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
};
Node::Node()
{
setFlag(ItemIsMovable);
// Create a GraphicsProxyWidget to insert the nodeFrame into the scene
auto proxyWidget = new QGraphicsProxyWidget(this);
auto 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);
}
主要:
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);
// Show the the view
view->show();
return app.exec();
}
在nodeframe.cpp
中我添加了一个函数getButtonRect()
:
#ifndef NODEFRAME_H
#define NODEFRAME_H
#include <QWidget>
#include <QPushButton>
#include <QRect>
class NodeFrame: public QWidget
{
public:
NodeFrame();
QRect getButtonRect();
private:
QPushButton *button;
QHBoxLayout *layout;
};
#endif // NODEFRAME_H
nodeframe.cpp
#include "nodeframe.h"
NodeFrame::NodeFrame()
{
setFixedSize(200, 80);
setStyleSheet("QFrame { background-color: #2e4076; }");
// 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);
setLayout(layout);
}
QRect NodeFrame::getButtonRect()
{
return layout->itemAt(0)->geometry();
}
并在 Node 中将此函数传递给 main.cpp
因为 QGraphicsView 在那里:
node.cpp:
#include "node.h"
#include <QGraphicsProxyWidget>
#include <QPainter>
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);
}
QRect Node::getButtonRect()
{
return frame->getButtonRect();
}
main.cpp
#include "node.h"
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
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(0, 0);
// qDebug() << "RECT bottomLeft= " << view->mapToScene(item->getButtonRect().bottomLeft());
// qDebug() << "RECT bottomRight= " << view->mapToScene(item->getButtonRect().bottomRight());
// qDebug() << "RECT topLeft= " << view->mapToScene(item->getButtonRect().topLeft());
// qDebug() << "RECT topRight= " << view->mapToScene(item->getButtonRect().topRight());
auto btnRect = item->getButtonRect();
auto ellipse = new QGraphicsEllipseItem(QRect(view->mapToGlobal(btnRect.center()).x(), view->mapToGlobal(btnRect.center()).y(), 40, 40));
qDebug() << "Center" << view->mapToGlobal(btnRect.center());
scene->addItem(ellipse);
// Show the the view
view->show();
return app.exec();
}
我有一个带有 QPushButton 的 QWidget,同时,这个 QWidget 被嵌入到 QGraphicsItem 中,它位于 QGraphicsScene 中。
我需要在两个指向 QPushButton 的 QGraphicsItems 之间画一条线。为此,我需要获得 QPushButton 的位置。它看起来像这样:
我尝试在 QGraphicsItem 的构造函数中获取 QPushButton 的位置,但它 returns 0,0。我猜这是 QWidget 中按钮的位置。我想我需要的是一种获取屏幕位置的方法。
最小示例:尽可能简化。 QWidget:
NodeFrame::NodeFrame()
{
setFixedSize(200,80);
setStyleSheet("QFrame { background-color: #2e4076; }");
// Creates and add a QPushButton to the frame.
// I need the position of this button on the QGraohicsScene
auto button = new QPushButton("B");
button->setFixedSize(40,20);
auto layout = new QHBoxLayout();
layout->addWidget(button);
setLayout(layout);
}
QGraphicsItem:
class Node : public QGraphicsItem
{
public:
Node();
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
};
Node::Node()
{
setFlag(ItemIsMovable);
// Create a GraphicsProxyWidget to insert the nodeFrame into the scene
auto proxyWidget = new QGraphicsProxyWidget(this);
auto 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);
}
主要:
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);
// Show the the view
view->show();
return app.exec();
}
在nodeframe.cpp
中我添加了一个函数getButtonRect()
:
#ifndef NODEFRAME_H
#define NODEFRAME_H
#include <QWidget>
#include <QPushButton>
#include <QRect>
class NodeFrame: public QWidget
{
public:
NodeFrame();
QRect getButtonRect();
private:
QPushButton *button;
QHBoxLayout *layout;
};
#endif // NODEFRAME_H
nodeframe.cpp
#include "nodeframe.h"
NodeFrame::NodeFrame()
{
setFixedSize(200, 80);
setStyleSheet("QFrame { background-color: #2e4076; }");
// 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);
setLayout(layout);
}
QRect NodeFrame::getButtonRect()
{
return layout->itemAt(0)->geometry();
}
并在 Node 中将此函数传递给 main.cpp
因为 QGraphicsView 在那里:
node.cpp:
#include "node.h"
#include <QGraphicsProxyWidget>
#include <QPainter>
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);
}
QRect Node::getButtonRect()
{
return frame->getButtonRect();
}
main.cpp
#include "node.h"
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
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(0, 0);
// qDebug() << "RECT bottomLeft= " << view->mapToScene(item->getButtonRect().bottomLeft());
// qDebug() << "RECT bottomRight= " << view->mapToScene(item->getButtonRect().bottomRight());
// qDebug() << "RECT topLeft= " << view->mapToScene(item->getButtonRect().topLeft());
// qDebug() << "RECT topRight= " << view->mapToScene(item->getButtonRect().topRight());
auto btnRect = item->getButtonRect();
auto ellipse = new QGraphicsEllipseItem(QRect(view->mapToGlobal(btnRect.center()).x(), view->mapToGlobal(btnRect.center()).y(), 40, 40));
qDebug() << "Center" << view->mapToGlobal(btnRect.center());
scene->addItem(ellipse);
// Show the the view
view->show();
return app.exec();
}