如何根据第一个选择的项目对齐图形场景中的图形项目? [英] How to align Graphics items in Graphic scene based on first selected item?

查看:38
本文介绍了如何根据第一个选择的项目对齐图形场景中的图形项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有图形场景,因为我必须根据第一个选择的项目(参考项目)向右、向左、顶部或底部下车.我搜索了一些代码,但在此过程中它与场景的正确位置对齐.我必须根据第一个选定的项目对齐项目.我怎样才能做到这一点?

 void GraphicScene::ItemsRightAlign(){如果 (selectedItems().isEmpty())返回;QRectF refRect = selectedItems().first()->boundingRect();QListsel =selectedItems();//  例如foreach(QGraphicsItem* selItem, sel){qreal dx = 0, dy = 0;QRectF itemRect = selItem->mapToScene(selItem->boundingRect()).boundingRect();//如果(align_right)dx = refRect.right() - itemRect.right();qDebug() <<项目位置"<mapToScene(selItem->boundingRect()).boundingRect();selItem->moveBy(dx, dy);}}

欲知更多详情

输出应该是这样的输出

解决方案

解析方法是将决定右、左、上、下的点映射到第一项和其他项的场景中,得到的差值是必须赔偿.

graphicsscene.h

#ifndef GRAPHICSCENE_H#define GRAPHICSCENE_H#include <QGraphicsScene>#include 类 GraphicsScene:公共 QGraphicsScene{Q_OBJECT上市:GraphicsScene(QObject *parent=nullptr);void moveSelecteds(Qt::Alignment aligment);私人插槽:无效 onSelectionChanged();私人的:void move(QGraphicsItem *ref, QList others, Qt::Alignment aligment);QGraphicsItem *mRef;};#endif//GRAPHICSCENE_H

graphicsscene.cpp

#include "graphicsscene.h"GraphicsScene::GraphicsScene(QObject *parent):QGraphicsScene(父),mRef(nullptr){连接(这个,&GraphicsScene::selectionChanged,这个,&GraphicsScene::onSelectionChanged);}void GraphicsScene::moveSelecteds(Qt::Alignment aligment){QList它的= selectedItems();if(its.size() <2)返回;if(!its.removeOne(mRef))返回;移动(mRef,其,对齐);}void GraphicsScene::onSelectionChanged(){if(selectedItems().isEmpty()){mRef = nullptr;}否则 if(selectedItems().size() == 1){mRef = selectedItems().first();}}void GraphicsScene::move(QGraphicsItem *ref, QList others, Qt::Alignment aligment){QPointFp;开关(对齐){案例 Qt::AlignLeft:p = QPointF(ref->mapToScene(ref->boundingRect().topLeft()).x(), 0);休息;案例 Qt::AlignRight:p = QPointF(ref->mapToScene(ref->boundingRect().topRight()).x(), 0);休息;案例 Qt::AlignTop:p = QPointF(0, ref->mapToScene(ref->boundingRect().topLeft()).y());休息;案例 Qt::AlignBottom:p = QPointF(0, ref->mapToScene(ref->boundingRect().bottomLeft()).y());休息;}for(QGraphicsItem *o: 其他){QPointF 增量;开关(对齐){案例 Qt::AlignLeft:{delta = p - QPointF(o->mapToScene(o->boundingRect().topLeft()).x(), 0);休息;}案例 Qt::AlignRight:{delta = p - QPointF(o->mapToScene(o->boundingRect().topRight()).x(), 0);休息;}案例 Qt::AlignTop:{delta = p - QPointF(0, o->mapToScene(o->boundingRect().topLeft()).y());休息;}案例 Qt::AlignBottom:{delta = p - QPointF(0, o->mapToScene(o->boundingRect().bottomLeft()).y());休息;}}o->moveBy(delta.x(), delta.y());}}

在此示例中,您可以使用向上、向下、向左、向右键移动项目.

ma​​in.cpp

#include "graphicsscene.h"#include #include #include #include <QShortcut>#include <随机>静态无效create_items(QGraphicsScene和场景){std::default_random_engine 生成器;std::uniform_int_distributiondist_size(30, 40);std::uniform_int_distributiondist_pos(-50, 50);for(const QString & colorname : {"red", "green", "blue", "gray", "orange"}){QRectF r(QPointF(dist_pos(generator), dist_pos(generator)),QSizeF(dist_size(generator), dist_size(generator)));auto item = new QGraphicsRectItem(r);item->setPos(QPointF(dist_pos(generator), dist_pos(generator)));item->setBrush(QColor(colorname));item->setFlag(QGraphicsItem::ItemIsSelectable);场景.addItem(item);}}int main(int argc, char *argv[]){QApplication a(argc, argv);GraphicsScene 场景;创建项目(场景);QGraphicsView 视图(&scene);const QList>K a {{Qt::Key_Up, Qt::AlignTop},{Qt::Key_Down, Qt::AlignBottom},{Qt::Key_Left, Qt::AlignLeft},{Qt::Key_Right, Qt::AlignRight}};for(const QPair&p:k_a){QShortcut *shorcut = new QShortcut(p.first, &view);QObject::connect(shorcut, &QShortcut::activated, std::bind(&GraphicsScene::moveSelecteds, &scene, p.second));}view.resize(640, 480);视图.show();返回 a.exec();}

完整示例可在以下链接中找到.>

I have Graphic scene in that i have to alight right,left,top or bottom based on first selected item(Reference Item). i searched i got some code but in this its aligning to scene right position. I have to align items based on first selected item. how can i do this?

    void GraphicScene::ItemsRightAlign()
    {
      if (selectedItems().isEmpty())
          return;
      QRectF refRect = selectedItems().first()->boundingRect();
      QList<QGraphicsItem*> sel =selectedItems();  //   for example
      foreach(QGraphicsItem* selItem, sel)
      {
         qreal dx = 0, dy = 0;
         QRectF itemRect = selItem->mapToScene(selItem->boundingRect()).boundingRect();

         //if(align_right)
         dx = refRect.right() - itemRect.right();
         qDebug() << "item pos "<< dx << dy << selItem->mapToScene(selItem->boundingRect()).boundingRect() ;
         selItem->moveBy(dx, dy);
      }

    }

For more details

Output should be like this output

解决方案

The resolution method is to map the point that determines the right, left, up, down to the scene of the first item and the other items obtaining the difference that must be compensated.

graphicsscene.h

#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H

#include <QGraphicsScene>
#include <QGraphicsItem>

class GraphicsScene: public QGraphicsScene{
    Q_OBJECT
public:
    GraphicsScene(QObject *parent=nullptr);
    void moveSelecteds(Qt::Alignment aligment);
private slots:
    void onSelectionChanged();
private:
    void move(QGraphicsItem *ref, QList<QGraphicsItem *> others, Qt::Alignment aligment);
    QGraphicsItem *mRef;
};
#endif // GRAPHICSSCENE_H

graphicsscene.cpp

#include "graphicsscene.h"

GraphicsScene::GraphicsScene(QObject *parent):
    QGraphicsScene(parent),
    mRef(nullptr)
{
    connect(this, &GraphicsScene::selectionChanged, this, &GraphicsScene::onSelectionChanged);
}

void GraphicsScene::moveSelecteds(Qt::Alignment aligment){
    QList<QGraphicsItem *> its= selectedItems();
    if(its.size() < 2)
        return;
    if(!its.removeOne(mRef))
        return;
    move(mRef, its, aligment);
}

void GraphicsScene::onSelectionChanged(){
    if(selectedItems().isEmpty()){
        mRef = nullptr;
    }
    else if(selectedItems().size() == 1){
        mRef = selectedItems().first();
    }
}

void GraphicsScene::move(QGraphicsItem *ref, QList<QGraphicsItem *> others, Qt::Alignment aligment){
    QPointF p;
    switch (aligment) {
    case Qt::AlignLeft:
        p = QPointF(ref->mapToScene(ref->boundingRect().topLeft()).x(), 0);
        break;
    case Qt::AlignRight:
        p = QPointF(ref->mapToScene(ref->boundingRect().topRight()).x(), 0);
        break;
    case Qt::AlignTop:
        p = QPointF(0, ref->mapToScene(ref->boundingRect().topLeft()).y());
        break;
    case Qt::AlignBottom:
        p = QPointF(0, ref->mapToScene(ref->boundingRect().bottomLeft()).y());
        break;
    }

    for(QGraphicsItem *o: others){
        QPointF delta;
        switch (aligment) {
        case Qt::AlignLeft:{
            delta = p - QPointF(o->mapToScene(o->boundingRect().topLeft()).x(), 0);
            break;
        }
        case Qt::AlignRight:{
            delta = p - QPointF(o->mapToScene(o->boundingRect().topRight()).x(), 0);
            break;
        }
        case Qt::AlignTop:{
            delta = p - QPointF(0, o->mapToScene(o->boundingRect().topLeft()).y());
            break;
        }
        case Qt::AlignBottom:{
            delta = p - QPointF(0, o->mapToScene(o->boundingRect().bottomLeft()).y());
            break;
        }
        }
        o->moveBy(delta.x(), delta.y());
    }
}

In this example you can use the up, down, left, right keys to move the items.

main.cpp

#include "graphicsscene.h"

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QShortcut>
#include <random>

static void create_items(QGraphicsScene  & scene){

    std::default_random_engine generator;
    std::uniform_int_distribution<int> dist_size(30, 40);
    std::uniform_int_distribution<int> dist_pos(-50, 50);

    for(const QString & colorname : {"red", "green", "blue", "gray", "orange"}){
        QRectF r(QPointF(dist_pos(generator), dist_pos(generator)),
                 QSizeF(dist_size(generator), dist_size(generator)));
        auto item = new QGraphicsRectItem(r);
        item->setPos(QPointF(dist_pos(generator), dist_pos(generator)));
        item->setBrush(QColor(colorname));
        item->setFlag(QGraphicsItem::ItemIsSelectable);
        scene.addItem(item);
    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    GraphicsScene scene;
    create_items(scene);
    QGraphicsView view(&scene);

    const QList<QPair<Qt::Key, Qt::Alignment>> k_a {
        {Qt::Key_Up, Qt::AlignTop},
        {Qt::Key_Down, Qt::AlignBottom},
        {Qt::Key_Left, Qt::AlignLeft},
        {Qt::Key_Right, Qt::AlignRight}
    };

    for(const QPair<Qt::Key, Qt::Alignment> & p : k_a){
        QShortcut *shorcut = new QShortcut(p.first, &view);
        QObject::connect(shorcut, &QShortcut::activated, std::bind(&GraphicsScene::moveSelecteds, &scene, p.second));
    }

    view.resize(640, 480);
    view.show();

    return a.exec();
}

The complete example can be found in the following link.

这篇关于如何根据第一个选择的项目对齐图形场景中的图形项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆