如何根据第一个选定的项目对齐图形场景中的图形项目?
Posted
技术标签:
【中文标题】如何根据第一个选定的项目对齐图形场景中的图形项目?【英文标题】:How to align Graphics items in Graphic scene based on first selected item? 【发布时间】:2018-07-30 11:57:40 【问题描述】:我有图形场景,我必须根据第一个选定的项目(参考项目)向右、向左、顶部或底部下车。我搜索了一些代码,但在这个代码中它与场景正确的位置对齐。我必须根据第一个选定的项目对齐项目。我怎样才能做到这一点?
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);
更多详情
输出应该是这样的输出
【问题讨论】:
据我了解,如果您选择例如 5 个项目,您希望最后 4 个项目位于例如第一个选定项目的下方,我是否正确? @eyllanesc 是的...根据第一次选择正确...请检查图片 图片说明了很多,:) 我有一个疑问,你在图像中显示一条垂直线,将移动到左边,右边还是中间的项目?它可以显示您想要获得的图片。 @eyllanesc 就行了 【参考方案1】:替换 topLeft.x -- 右对齐用 topRight.x ,上对齐用 dy 替换 topLeft.y 和 dx ,下对齐用 dy 替换 bottomLeft.y 和 dx
void GraphicScene::ItemsLeftAlign
if (selectedItems().isEmpty())
return;
QGraphicsItem *FirstSelItem = selectedItems().first();
QList<QGraphicsItem*> sel =selectedItems(); // for example
foreach(QGraphicsItem* selItem, sel)
qreal dx = 0, dy = 0;
dx = (FirstSelItem->mapToScene(FirstSelItem->boundingRect().topLeft()).x()) -
(selItem->mapToScene(selItem->boundingRect().topLeft()).x());
selItem->moveBy(dx, dy);
【讨论】:
【参考方案2】:分辨率的方法是将确定右、左、上、下的点映射到第一个项目的场景中,其他项目获得必须补偿的差异。
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());
在本例中,您可以使用上、下、左、右键来移动项目。
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();
完整的例子可以在下面的link找到。
【讨论】:
以上是关于如何根据第一个选定的项目对齐图形场景中的图形项目?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据 DataGridView 中的选定行将组合框中的特定项目设置为选定项?