如何将两个QGraphicsPixmapItem与QLine连接起来?

huangapple go评论74阅读模式
英文:

How to join two QGraphicsPixmapItem with a QLine?

问题

现在我有两个QGraphicsPixmapItem添加到我的QGraphicsScene中。

现在我想要添加一个连接这两个QGraphicsPixmapItemQLine,并且应该能够随着QLine的拉伸而移动。

我已经查看了这个Elastic Nodes Example,但对我来说太复杂了。

根据这个链接:https://stackoverflow.com/questions/32192607/how-to-use-itemchange-from-qgraphicsitem-in-qt/32198716#32198716,我能够解决我的问题,只是我在替换QGraphicsEllipseItemQGraphicsPixmapItem时遇到了困难,因为需要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 &lt;QApplication&gt;
#include &lt;QGraphicsScene&gt;
#include &lt;QGraphicsView&gt;
#include &lt;QGraphicsEllipseItem&gt;
#include &lt;QGraphicsLineItem&gt;
class CustomElipse : public QGraphicsEllipseItem
{
public:
CustomElipse (const QRectF&amp; rect) : QGraphicsEllipseItem(rect) {
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem *line, bool isPoint1) {
this-&gt;line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant &amp;value)
{
if (change == ItemPositionChange &amp;&amp; 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-&gt;line().p1();
QPointF p2 = isP1 ? line-&gt;line().p2() : newCenterPos;
line-&gt;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-&gt;addLine(line, true);
elipse2-&gt;addLine(line, false);
QGraphicsView view(&amp;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();
}

这是结果:

如何将两个QGraphicsPixmapItem与QLine连接起来?

英文:

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 &lt;QApplication&gt;
#include &lt;QGraphicsScene&gt;
#include &lt;QGraphicsView&gt;
#include &lt;QGraphicsPixmapItem&gt;
#include &lt;QGraphicsLineItem&gt;
#include &lt;QPixmap&gt;
class CustomElipse : public QGraphicsPixmapItem
{
public:
//Use a QPixmap instead of QRect
CustomElipse (const QPixmap&amp; pixmap) : QGraphicsPixmapItem(pixmap) 
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem *line, bool isPoint1) 
{
this-&gt;line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant &amp;value)
{
if (change == ItemPositionChange &amp;&amp; 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&#39;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-&gt;line().p1();
QPointF p2 = isP1 ? line-&gt;line().p2() : newCenterPos;
line-&gt;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(&quot;:green.png&quot;));
scene.addItem(elipse1);
CustomElipse *elipse2 = new CustomElipse(QPixmap(&quot;:green.png&quot;));
scene.addItem(elipse2);
QGraphicsLineItem *line = scene.addLine(QLineF(40, 40, 80, 80));
elipse1-&gt;addLine(line, true);
elipse2-&gt;addLine(line, false);
QGraphicsView view(&amp;scene);
view.show();
return a.exec();
}

Here's the result:

如何将两个QGraphicsPixmapItem与QLine连接起来?

huangapple
  • 本文由 发表于 2023年5月28日 22:57:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76352091.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定