其他分享
首页 > 其他分享> > c – 修复QGraphicsItem位置,不改变场景中其他QGraphicsItems的行为

c – 修复QGraphicsItem位置,不改变场景中其他QGraphicsItems的行为

作者:互联网

这个问题与:Forcing QGraphicsItem To Stay Put有关

我希望在场景中移动时在固定位置上有一个QGraphicsItem.

建议的解决方案是覆盖子类QGraphicsView的void paintEvent(QPaintEvent *).

void MyGraphicsView::paintEvent(QPaintEvent*) {
  QPointF scenePos = mapToScene(0,0); // map viewport's top-left corner to scene
  myItem->setPos(scenePos);
}

但是,问题在于我希望场景中的其他所有内容保持不变,即如果我缩放或移动,我希望所有其他QGraphicsItem都表现为默认值.

解决此问题的一种不好的方法是从void MyGraphicsView :: paintEvent(QPaintEvent *)中调用void QGraphicsView :: paintEvent(QPaintEvent *).

void MyGraphicsView::paintEvent(QPaintEvent* event) {
  QGraphicsView::paintEvent(event);

  QPointF scenePos = mapToScene(0,0); // map viewport's top-left corner to scene
  myItem->setPos(scenePos);
}

但是,这会给my_item添加一个闪烁的行为,因为它首先使用QGraphicsView :: paintEvent(event)定位;然后使用添加的代码

QPointF scenePos = mapToScene(0,0); // map viewport's top-left corner to scene
myItem->setPos(scenePos);

问题是,我是否必须从头开始重新实现void MyGraphicsView :: paintEvent(QPaintEvent *)并为myItem的所需行为和所有其他QGraphicsItems的默认行为编写代码,或者是否有更简单的方法来执行此操作?

谢谢.

解决方法:

我认为这就是你要找的东西:

http://qt-project.org/doc/qt-4.8/qgraphicsitem.html#setFlag

的QGraphicsItem :: ItemIgnoresTransformations

来自文档的描述:

The item ignores inherited transformations (i.e., its position is still anchored to its parent, but the parent or view rotation, zoom or shear transformations are ignored). This flag is useful for keeping text label items horizontal and unscaled, so they will still be readable if the view is transformed. When set, the item’s view geometry and scene geometry will be maintained separately. You must call deviceTransform() to map coordinates and detect collisions in the view. By default, this flag is disabled. This flag was introduced in Qt 4.3. Note: With this flag set you can still scale the item itself, and that scale transformation will influence the item’s children.

您可能还希望将所有其他内容转移到其他内容.然后,移动或缩放或旋转单个图形组以影响除“不可变形”对象之外的所有内容.

https://qt-project.org/doc/qt-4.8/graphicsview.html#the-graphics-view-coordinate-system

https://qt-project.org/doc/qt-4.8/painting-transformations.html(一个很酷的例子,虽然它没有真正显示这个功能)

http://qt-project.org/doc/qt-4.8/demos-chip.html(使用QGraphicsView的好例子)

希望有所帮助.

编辑:

示例显示如何使用父级实现静态层:

main.cpp中

#include <QApplication>
#include "mygraphicsview.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyGraphicsView w;
    w.show();

    return a.exec();
}

mygraphicsview.h

#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H

#include <QGraphicsView>
#include <QGraphicsItemGroup>
#include <QMouseEvent>

class MyGraphicsView : public QGraphicsView
{
    Q_OBJECT

public:
    MyGraphicsView(QWidget *parent = 0);
    ~MyGraphicsView();

public slots:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
private:
    bool down;
    QPointF m_last_pos;

    QGraphicsItemGroup * m_group;
};

#endif // MYGRAPHICSVIEW_H

mygraphicsview.cpp

#include "mygraphicsview.h"

#include <QGraphicsItem>
#include <QGraphicsEllipseItem>
#include <QGraphicsTextItem>

MyGraphicsView::MyGraphicsView(QWidget *parent)
    : QGraphicsView(parent)
{
    down = false;
    this->setScene(new QGraphicsScene);

    // Anything not added to the "group" will stay put
    this->scene()->addEllipse(20, 20, 50, 50);
    this->scene()->addEllipse(180, 180, 50, 50);
    this->scene()->addText("Click and drag with the mouse to move only the tiny dots.");

    // This group will receive all transformations
    m_group = new QGraphicsItemGroup;
    for(int r = 0; r < 20; r ++)
    {
        for(int c = 0; c < 20; c++)
        {
            if(c % 5 == 0 && r % 5 == 0)
            {
                QGraphicsTextItem * txt = new QGraphicsTextItem(QString::number(r) + "," + QString::number(c));
                m_group->addToGroup(txt);
                txt->setPos(r*100, c*100);
            }
            m_group->addToGroup(new QGraphicsEllipseItem(r *100, c*100, 5, 5));
        }
    }

    this->scene()->addItem(m_group);
}

MyGraphicsView::~MyGraphicsView()
{

}

void MyGraphicsView::mousePressEvent(QMouseEvent *event)
{
    m_last_pos = mapToScene(event->pos());
    down = true;
}

void MyGraphicsView::mouseReleaseEvent(QMouseEvent *)
{
    down = false;
}

void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if(down)
    {
        QPointF temp = mapToScene(event->pos());

        QPointF delta = temp - m_last_pos;
        m_last_pos = temp;

        // Apply transformation to the group, not the scene!
        m_group->translate(delta.x(), delta.y());
    }
}

标签:qgraphicsview,c,qt,qgraphicsscene,qgraphicsitem
来源: https://codeday.me/bug/20190831/1778208.html