Qt qm设置切变?(适用于单个或多个项目)

Qt qm设置切变?(适用于单个或多个项目),qt,transformation,qgraphicsitem,Qt,Transformation,Qgraphicsitem,要在QGraphicsItem上应用旋转,我可以调用rotate()或setRotation()。我所看到的是: item.rotate(angle); 如我所料,结果是轮换;但是,如果我复制该项(在子类中使用cop构造函数),则不会复制任何旋转(即使我复制了所有转换) 导致项目具有我可以复制的rotation()属性,但需要更新 所以第二个版本是我需要的 我想能够适用于剪切我的项目以及 item.shear(shx, shy); 第一件看起来不错,但我找不到复制这把剪刀的方法。我也找不到与

要在QGraphicsItem上应用旋转,我可以调用
rotate()
setRotation()
。我所看到的是:

item.rotate(angle);
如我所料,结果是轮换;但是,如果我复制该项(在子类中使用cop构造函数),则不会复制任何旋转(即使我复制了所有转换)

导致项目具有我可以复制的
rotation()
属性,但需要更新

所以第二个版本是我需要的

我想能够适用于剪切我的项目以及

item.shear(shx, shy);
第一件看起来不错,但我找不到复制这把剪刀的方法。我也找不到与旋转类似的属性:我找不到
setShear()

更重要的是,如果我尝试使用变换,以实现群剪切(如此旋转),我会得到非常奇怪的结果

如何为剪切创建类似的存储属性

编辑:

尝试

QTransform t;
t.shear(shx, shy);
item->setTransform(t, true);
也给了我一个巨大的缩放和一些旋转。。。我试着将
shx
shy
除以100,这似乎是合理的(不确定是否正确?)


注意-将移动代码片段作为回答,因为它似乎可以工作。

似乎我必须将剪切因子除以100(这似乎并不总是正确的)

我认为转换是在项目上组合的,所以我不需要做任何操作来组合任何旋转、缩放或剪切。。。我可以用

item->setTransform(t, true);
对于所有变换,无需单独设置旋转或缩放

虽然
translate()
rotate()
scale()
shear()
方法与设置变换矩阵之间似乎不存在任何冲突。因此,组合这些函数,然后复制变换似乎很好。()

似乎没有任何文件证明必须降低剪切系数的原因。。。()。
如果我在item constructor中设置剪切,则它不必除以100即可工作。
然而,如果我像上面的代码那样调用剪切,在不降低因子的情况下,我也会得到一个调整大小的结果。我觉得这很令人困惑。。。但只要它起作用

完整样本代码:包括旋转变化和剪切变化

myview.h

#ifndef MYVIEW_H
#define MYVIEW_H

#include <QGraphicsView>
#include <QAction>
#include <QContextMenuEvent>
#include <QGraphicsItem>

class MyView : public QGraphicsView
{
    Q_OBJECT

public:
    MyView(QWidget *parent = 0);

protected:
    virtual void contextMenuEvent(QContextMenuEvent *event);

private slots:
    void rotateItem(qreal deg = 10);
    void shearItem(qreal shx = 10, qreal shy = 10);

private:
    void createActions();
    QAction *rotateAct;
    QAction *shearAct;
};

#endif // MYVIEW_H
#如果没有我的视图#
#定义我的视图
#包括
#包括
#包括
#包括
类MyView:公共QGraphicsView
{
Q_对象
公众:
MyView(QWidget*parent=0);
受保护的:
虚拟void contextMenuEvent(QContextMenuEvent*事件);
专用插槽:
空心旋转体(qreal度=10);
无效剪切项(qreal shx=10,qreal shy=10);
私人:
void createActions();
QAction*旋转反应器;
QAction*shearAct;
};
#endif//MYVIEW\u H
myview.cpp

#include "myview.h"
#include <QMenu>

MyView::MyView(QWidget *parent) : QGraphicsView(parent)
{
    createActions();
    setScene(new QGraphicsScene(-500, -150, 1000, 600, this));
    setDragMode(RubberBandDrag);
}

void MyView::contextMenuEvent(QContextMenuEvent *event)
{
    QGraphicsItem* item = itemAt(event->pos());
    if(item != NULL)
        item->setSelected(true);

    if(scene()->selectedItems().isEmpty())  return;

    QMenu menu(this);
    menu.addAction(rotateAct);
    menu.addAction(shearAct);
    menu.exec(event->globalPos());
}

void MyView::rotateItem(qreal deg)
{
    QRectF rect;
    foreach(QGraphicsItem* item, scene()->selectedItems())
        rect |= item->mapToScene(item->boundingRect()).boundingRect();    
    QPointF center = rect.center();

    QTransform t;
    t.translate(center.x(), center.y());
    t.rotate(deg);
    t.translate(-center.x(), -center.y());

    foreach(QGraphicsItem* item, scene()->selectedItems())
    {
        item->setPos(t.map(item->pos()));
        item->setRotation(item->rotation() + deg);
    }
}

void MyView::shearItem(qreal shx, qreal shy)
{
    QRectF rect;
    foreach(QGraphicsItem* item, scene()->selectedItems())
        rect |= item->mapToScene(item->boundingRect()).boundingRect();    
    QPointF center = rect.center();

    QTransform t;

    t.translate(center.x(), center.y());
    t.shear(shx, shy);
    // seems shear increases item to gigantic proportions so I tried
    //t.shear(shx/100, shy/100);
    t.translate(-center.x(), -center.y());

    foreach(QGraphicsItem* item, scene()->selectedItems())
    {
        item->setPos(t.map(item->pos()));
        item->setTransform(t, true);
    }
}

void MyView::createActions()
{
    rotateAct = new QAction(tr("Rotate 10 degrees"), this);
    connect(rotateAct, SIGNAL(triggered()), this, SLOT(rotateItem()));
    shearAct = new QAction(tr("Shear 10, 10"), this);
    connect(shearAct, SIGNAL(triggered()), this, SLOT(shearItem()));
}
#包括“myview.h”
#包括
MyView::MyView(QWidget*父级):QGraphicsView(父级)
{
createActions();
setScene(新的qgraphicscene(-500,-1501000600,this));
setDragMode(橡胶垫);
}
void MyView::contextMenuEvent(QContextMenuEvent*事件)
{
QGraphicsItem*item=itemAt(事件->位置());
如果(项!=NULL)
item->setSelected(真);
如果(scene()->selectedItems().isEmpty())返回;
QMenu菜单(此菜单);
菜单.addAction(rotateAct);
菜单.添加动作(剪切动作);
menu.exec(event->globalPos());
}
void MyView::rotateItem(qreal deg)
{
qrectfrect;
foreach(QGraphicsItem*项目,场景()->selectedItems())
rect |=item->maptosene(item->boundingRect()).boundingRect();
QPointF center=rect.center();
qt转化;
t、 平移(center.x(),center.y());
t、 旋转(度);
t、 平移(-center.x(),-center.y());
foreach(QGraphicsItem*项目,场景()->selectedItems())
{
item->setPos(t.map(item->pos());
项目->设置旋转(项目->旋转()+度);
}
}
void MyView::shearItem(qreal shx,qreal shy)
{
qrectfrect;
foreach(QGraphicsItem*项目,场景()->selectedItems())
rect |=item->maptosene(item->boundingRect()).boundingRect();
QPointF center=rect.center();
qt转化;
t、 平移(center.x(),center.y());
t、 剪切(shx,shy);
//似乎剪切增加项目的巨大比例,所以我尝试
//t、 剪切力(shx/100、shy/100);
t、 平移(-center.x(),-center.y());
foreach(QGraphicsItem*项目,场景()->selectedItems())
{
item->setPos(t.map(item->pos());
item->setTransform(t,true);
}
}
void MyView::createActions()
{
rotateAct=新的QAction(tr(“旋转10度”),即:;
连接(rotateAct,信号(已触发()),此,插槽(rotateItem());
剪切力=新的QAction(tr(“剪切力10,10”),本);
连接(剪切动作,信号(已触发()),此,插槽(剪切项());
}
main.cpp:

#include <QtGui>    
#include "myview.h"    

int main( int argc, char **argv )
{
    QApplication app(argc, argv);
    MyView* view = new MyView();

    QGraphicsRectItem* rItem = view->scene()->addRect(30, 40, 100, 100, Qt::NoPen, Qt::blue);
    QGraphicsRectItem* rItem1 = view->scene()->addRect(-30, -40, 100, 100, Qt::NoPen, Qt::red);
    QGraphicsEllipseItem* eItem = view->scene()->addEllipse(70, -50, 100, 100, Qt::NoPen, Qt::blue);

    foreach(QGraphicsItem* item, view->scene()->items())
    {
        item->setFlag(QGraphicsItem::ItemIsMovable);
        item->setFlag(QGraphicsItem::ItemIsFocusable);
        item->setFlag(QGraphicsItem::ItemIsSelectable);
    }

    view->show();
    return app.exec();
}
#包括
#包括“myview.h”
int main(int argc,字符**argv)
{
QApplication应用程序(argc、argv);
MyView*视图=新建MyView();
qgraphicsrecitem*rItem=view->scene()->addRect(30,40,100,100,Qt::NoPen,Qt::blue);
qgraphicsrecitem*rItem1=view->scene()->addRect(-30,-40100100,Qt::NoPen,Qt::red);
QGraphicsEllipseItem*eItem=view->scene()->addEllipse(70,-50100100,Qt::NoPen,Qt::blue);
foreach(QGraphicsItem*项目,视图->场景()->项目())
{
item->setFlag(QGraphicsItem::ItemIsMovable);
item->setFlag(QGraphicsItem::ItemIsFocusable);
item->setFlag(QGraphicsItem::ItemIsSelectable);
}
查看->显示();
返回app.exec();
}

您使用的是什么版本的Qt?您看过使用void QGraphicsItem::setTransform(const QTransform&matrix,bool combine=false)吗。QTransform是用剪切矩阵构造的,你说“即使我复制了所有的变换”——这是有问题的,除非你说错了。只有一个转换,存储为矩阵,如果分段复制,很可能会有一个损坏的副本。@KubaOber我的意思是,当我创建项目副本时,我还执行
copy->setTransform(original->transform()
#include "myview.h"
#include <QMenu>

MyView::MyView(QWidget *parent) : QGraphicsView(parent)
{
    createActions();
    setScene(new QGraphicsScene(-500, -150, 1000, 600, this));
    setDragMode(RubberBandDrag);
}

void MyView::contextMenuEvent(QContextMenuEvent *event)
{
    QGraphicsItem* item = itemAt(event->pos());
    if(item != NULL)
        item->setSelected(true);

    if(scene()->selectedItems().isEmpty())  return;

    QMenu menu(this);
    menu.addAction(rotateAct);
    menu.addAction(shearAct);
    menu.exec(event->globalPos());
}

void MyView::rotateItem(qreal deg)
{
    QRectF rect;
    foreach(QGraphicsItem* item, scene()->selectedItems())
        rect |= item->mapToScene(item->boundingRect()).boundingRect();    
    QPointF center = rect.center();

    QTransform t;
    t.translate(center.x(), center.y());
    t.rotate(deg);
    t.translate(-center.x(), -center.y());

    foreach(QGraphicsItem* item, scene()->selectedItems())
    {
        item->setPos(t.map(item->pos()));
        item->setRotation(item->rotation() + deg);
    }
}

void MyView::shearItem(qreal shx, qreal shy)
{
    QRectF rect;
    foreach(QGraphicsItem* item, scene()->selectedItems())
        rect |= item->mapToScene(item->boundingRect()).boundingRect();    
    QPointF center = rect.center();

    QTransform t;

    t.translate(center.x(), center.y());
    t.shear(shx, shy);
    // seems shear increases item to gigantic proportions so I tried
    //t.shear(shx/100, shy/100);
    t.translate(-center.x(), -center.y());

    foreach(QGraphicsItem* item, scene()->selectedItems())
    {
        item->setPos(t.map(item->pos()));
        item->setTransform(t, true);
    }
}

void MyView::createActions()
{
    rotateAct = new QAction(tr("Rotate 10 degrees"), this);
    connect(rotateAct, SIGNAL(triggered()), this, SLOT(rotateItem()));
    shearAct = new QAction(tr("Shear 10, 10"), this);
    connect(shearAct, SIGNAL(triggered()), this, SLOT(shearItem()));
}
#include <QtGui>    
#include "myview.h"    

int main( int argc, char **argv )
{
    QApplication app(argc, argv);
    MyView* view = new MyView();

    QGraphicsRectItem* rItem = view->scene()->addRect(30, 40, 100, 100, Qt::NoPen, Qt::blue);
    QGraphicsRectItem* rItem1 = view->scene()->addRect(-30, -40, 100, 100, Qt::NoPen, Qt::red);
    QGraphicsEllipseItem* eItem = view->scene()->addEllipse(70, -50, 100, 100, Qt::NoPen, Qt::blue);

    foreach(QGraphicsItem* item, view->scene()->items())
    {
        item->setFlag(QGraphicsItem::ItemIsMovable);
        item->setFlag(QGraphicsItem::ItemIsFocusable);
        item->setFlag(QGraphicsItem::ItemIsSelectable);
    }

    view->show();
    return app.exec();
}