英文:
How to join two QGraphicsPixmapItem with a QLine?
问题
现在我有两个QGraphicsPixmapItem
添加到我的QGraphicsScene
中。
现在我想要添加一个连接这两个QGraphicsPixmapItem
的QLine
,并且应该能够随着QLine
的拉伸而移动。
我已经查看了这个Elastic Nodes Example,但对我来说太复杂了。
根据这个链接:https://stackoverflow.com/questions/32192607/how-to-use-itemchange-from-qgraphicsitem-in-qt/32198716#32198716,我能够解决我的问题,只是我在替换QGraphicsEllipseItem
为QGraphicsPixmapItem
时遇到了困难,因为需要rect
参数,这在另一个函数中用于计算位置。
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
class CustomEllipse : public QGraphicsEllipseItem
{
public:
CustomEllipse(const QRectF& rect) : QGraphicsEllipseItem(rect)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem* line, bool isPoint1)
{
this->line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant& value)
{
if (change == ItemPositionChange && scene())
{
// value is the new position.
QPointF newPos = value.toPointF();
moveLineToCenter(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
void moveLineToCenter(QPointF newPos)
{
// Converts the ellipse position (top-left) to its center position
int xOffset = rect().x() + rect().width() / 2;
int yOffset = rect().y() + rect().height() / 2;
QPointF newCenterPos = QPointF(newPos.x() + xOffset, newPos.y() + yOffset);
// Move the required point of the line to the center of the ellipse
QPointF p1 = isP1 ? newCenterPos : line->line().p1();
QPointF p2 = isP1 ? line->line().p2() : newCenterPos;
line->setLine(QLineF(p1, p2));
}
private:
QGraphicsLineItem* line;
bool isP1;
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
CustomEllipse* ellipse1 = new CustomEllipse(QRectF(30, 30, 15, 25));
scene.addItem(ellipse1);
CustomEllipse* ellipse2 = new CustomEllipse(QRectF(70, 70, 25, 15));
scene.addItem(ellipse2);
QGraphicsLineItem* line = scene.addLine(QLineF(40, 40, 80, 80));
ellipse1->addLine(line, true);
ellipse2->addLine(line, false);
QGraphicsView view(&scene);
view.show();
return a.exec();
}
英文:
I have two QGraphicsPixmapItem
added to my QGraphicsScene
.
Now I want to add a QLine
connecting both of this QGraphicsPixmapItem
and should be able to move around with QLine
stretching like graph.
I have looked into this Elastic Nodes Example, but it's too complicated for me.
based on this: https://stackoverflow.com/questions/32192607/how-to-use-itemchange-from-qgraphicsitem-in-qt/32198716#32198716, I was able to solve my problem except I am struggling to replace QGraphicsEllipseItem
with QGraphicsPixmapItem
because of rect argument, which is needed in another function for calculating position.
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
class CustomElipse : public QGraphicsEllipseItem
{
public:
CustomElipse (const QRectF& rect) : QGraphicsEllipseItem(rect) {
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem *line, bool isPoint1) {
this->line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
// value is the new position.
QPointF newPos = value.toPointF();
moveLineToCenter(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
void moveLineToCenter(QPointF newPos) {
// Converts the elipse position (top-left)
// to its center position
int xOffset = rect().x() + rect().width()/2;
int yOffset = rect().y() + rect().height()/2;
QPointF newCenterPos = QPointF(newPos.x() + xOffset, newPos.y() + yOffset);
// Move the required point of the line to the center of the elipse
QPointF p1 = isP1 ? newCenterPos : line->line().p1();
QPointF p2 = isP1 ? line->line().p2() : newCenterPos;
line->setLine(QLineF(p1, p2));
}
private:
QGraphicsLineItem *line;
bool isP1;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
CustomElipse *elipse1 = new CustomElipse(QRectF(30, 30, 15, 25));
scene.addItem(elipse1);
CustomElipse *elipse2 = new CustomElipse(QRectF(70, 70, 25, 15));
scene.addItem(elipse2);
QGraphicsLineItem *line = scene.addLine(QLineF(40, 40, 80, 80));
elipse1->addLine(line, true);
elipse2->addLine(line, false);
QGraphicsView view(&scene);
view.show();
return a.exec();
}
答案1
得分: 1
来自QGraphicsPixmapItem的Qt文档:
QGraphicsPixmapItem类提供了一个可以添加到QGraphicsScene的像素图项。
以下是我所做更改的带有注释的示例:
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QGraphicsLineItem>
#include <QPixmap>
class CustomEllipse : public QGraphicsPixmapItem
{
public:
// 使用QPixmap代替QRect
CustomEllipse(const QPixmap& pixmap) : QGraphicsPixmapItem(pixmap)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem *line, bool isPoint1)
{
this->line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene())
{
// value是新的位置。
QPointF newPos = value.toPointF();
moveLineToCenter(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
void moveLineToCenter(QPointF newPos)
{
// 将椭圆位置(左上角)转换为其中心位置
// 使用pixmap的矩形来计算偏移量
int xOffset = pixmap().rect().x() + pixmap().width() / 2;
int yOffset = pixmap().rect().y() + pixmap().height() / 2;
QPointF newCenterPos = QPointF(newPos.x() + xOffset, newPos.y() + yOffset);
// 将线的所需点移动到椭圆的中心
QPointF p1 = isP1 ? newCenterPos : line->line().p1();
QPointF p2 = isP1 ? line->line().p2() : newCenterPos;
line->setLine(QLineF(p1, p2));
}
private:
QGraphicsLineItem *line;
bool isP1;
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
// 我使用了一个绿色圆的图像来测试它
CustomEllipse *ellipse1 = new CustomEllipse(QPixmap(":green.png"));
scene.addItem(ellipse1);
CustomEllipse *ellipse2 = new CustomEllipse(QPixmap(":green.png"));
scene.addItem(ellipse2);
QGraphicsLineItem *line = scene.addLine(QLineF(40, 40, 80, 80));
ellipse1->addLine(line, true);
ellipse2->addLine(line, false);
QGraphicsView view(&scene);
view.show();
return a.exec();
}
这是结果:
英文:
From the Qt Documentation of QGraphicsPixmapItem:
>The QGraphicsPixmapItem class provides a pixmap item that you can add to a QGraphicsScene.
Here's an example with comments on the changes I made:
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QGraphicsLineItem>
#include <QPixmap>
class CustomElipse : public QGraphicsPixmapItem
{
public:
//Use a QPixmap instead of QRect
CustomElipse (const QPixmap& pixmap) : QGraphicsPixmapItem(pixmap)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem *line, bool isPoint1)
{
this->line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene())
{
// value is the new position.
QPointF newPos = value.toPointF();
moveLineToCenter(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
void moveLineToCenter(QPointF newPos)
{
// Converts the elipse position (top-left)
// to its center position
//use pixmap's rect to calculate the offset
int xOffset = pixmap().rect().x() + pixmap().width()/2;
int yOffset = pixmap().rect().y() + pixmap().height()/2;
QPointF newCenterPos = QPointF(newPos.x() + xOffset, newPos.y() + yOffset);
// Move the required point of the line to the center of the elipse
QPointF p1 = isP1 ? newCenterPos : line->line().p1();
QPointF p2 = isP1 ? line->line().p2() : newCenterPos;
line->setLine(QLineF(p1, p2));
}
private:
QGraphicsLineItem *line;
bool isP1;
};
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
//I used an image of a green circle to test it
CustomElipse *elipse1 = new CustomElipse(QPixmap(":green.png"));
scene.addItem(elipse1);
CustomElipse *elipse2 = new CustomElipse(QPixmap(":green.png"));
scene.addItem(elipse2);
QGraphicsLineItem *line = scene.addLine(QLineF(40, 40, 80, 80));
elipse1->addLine(line, true);
elipse2->addLine(line, false);
QGraphicsView view(&scene);
view.show();
return a.exec();
}
Here's the result:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论