ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-08-31 20:04:26  阅读:372  来源: 互联网

标签:qgraphicsview c qt qgraphicsscene qgraphicsitem


这个问题与: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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有