QGraphicsView/QGraphicsScene: How to fix an item's X or Y coordinate during rotation?

☆樱花仙子☆ 提交于 2019-12-24 07:38:45

问题


I have about 150 QGraphicsLineItems in a QGraphicsScene, and I want to "rotate" them, but have the rotation not affect their X coordinate. In other words, they would move vertically according to a given rotation angle, but they wouldn't actually rotate or move horizontally.

The reason I'd like to do this is that there are several other items in an adjacent QGraphicsScene/View that are rotated normally, and I want the items in this new scene/view to match the displayed height of the normally rotating items items.

I'd appreciate some suggestions or feedback. Thanks!

EDIT: Here I have a dialog on which I draw two squares onto scene1, and two lines onto scene2. As I drag the slider, I'm hoping to get the above-specified behavior, but all that's happening is the squares are rotating (as they should), while the lines do nothing (they should move up and down with the squares). Note that there aren't any compile errors.

Here's the dialog constructor:

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);

// These points will initially translate the squares and respective lines.
QPointF p1(-20,-5); 
QPointF p2(30,30);

QGraphicsScene *scene1 = new QGraphicsScene;
QGraphicsRectItem *square1 = new QGraphicsRectItem(-10,-10,20,20);
QGraphicsRectItem *square2 = new QGraphicsRectItem(-10,-10,20,20);
square1->translate(p1.x(),p1.y());
square2->translate(p2.x(),p2.y());
scene1->addItem(square1);
scene1->addItem(square2);

QGraphicsScene *scene2 = new QGraphicsScene;
line1 = new QGraphicsLineItem(0,0,20,0);
line2 = new QGraphicsLineItem(0,0,20,0);
line1->translate(0,p1.y());
line2->translate(0,p2.y());
scene2->addItem(line1);
scene2->addItem(line2);

ui->graphicsView->setScene(scene1);
ui->graphicsView2->setScene(scene2);
}

And the rotation slider slot:

void Dialog::on_verticalSlider_valueChanged(int value)
{
ui->graphicsView->resetTransform();
ui->graphicsView->rotate(value);

p1 = ui->graphicsView->transform().map(p1);
p2 = ui->graphicsView->transform().map(p2);

line1->translate(0,p1.y());
line2->translate(0,p2.y());
}

回答1:


Here's what I came up with that is working:

Dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"
#include <QtGui>

Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog)
{
    ui->setupUi(this);

    p1.setX(-20); p1.setY(-5);
    p2.setX(30); p2.setY(30);

    QGraphicsScene *scene1 = new QGraphicsScene;
    QGraphicsRectItem *square1 = new QGraphicsRectItem(-10,-10,20,20);
    QGraphicsRectItem *square2 = new QGraphicsRectItem(-10,-10,20,20);
    square1->translate(p1.x(),p1.y());
    square2->translate(p2.x(),p2.y());
    scene1->addItem(square1);
    scene1->addItem(square2);

    QGraphicsScene *scene2 = new QGraphicsScene;
    line1 = new QGraphicsLineItem(-20,0,20,0);
    line2 = new QGraphicsLineItem(-20,0,20,0);
    line1->translate(0,p1.y());
    line2->translate(0,p2.y());
    scene2->addItem(line1);
    scene2->addItem(line2);

ui->graphicsView1->setScene(scene1);
ui->graphicsView2->setScene(scene2);

    currentp1tr = p1.y();
    currentp2tr = p2.y();
}

void Dialog::on_verticalSlider_valueChanged(int value)
{
    ui->graphicsView1->resetTransform();
    ui->graphicsView1->rotate(value);

    QPointF temp1 = ui->graphicsView1->transform().map(p1);
    QPointF temp2 = ui->graphicsView1->transform().map(p2);

    line1->translate(0,temp1.y() - currentp1tr);
    line2->translate(0,temp2.y() - currentp2tr);

    currentp1tr = temp1.y();
    currentp2tr = temp2.y();
}

Dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QtGui>

namespace Ui {
    class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);

private slots:
    void on_verticalSlider_valueChanged(int value);

private:
    Ui::Dialog *ui;
    QGraphicsLineItem *line1;
    QGraphicsLineItem *line2;
    QGraphicsScene *scene1;
    QGraphicsScene *scene2;
    QPointF p1;
    QPointF p2;
    float currentp1tr;
    float currentp2tr;
};

You also need a UI file with GraphicsView1, GraphicsView2, and verticalSlider.

As I mentioned in an above comment, I was hoping for a more elegant solution, as I think this won't accommodate situations in which the bounding rects of the two scenes are different.



来源:https://stackoverflow.com/questions/9137189/qgraphicsview-qgraphicsscene-how-to-fix-an-items-x-or-y-coordinate-during-rota

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!