QGraphicsView/QGraphicsScene:如何在旋转过程中修复项目的 X 或 Y 坐标?

发布于 2025-01-02 17:46:07 字数 1610 浏览 0 评论 0原文

我在 QGraphicsScene 中有大约 150 个 QGraphicsLineItems,我想“旋转”它们,但旋转不会影响它们的 X 坐标。换句话说,它们会根据给定的旋转角度垂直移动,但实际上不会旋转或水平移动。

我想这样做的原因是相邻的 QGraphicsScene/View 中有几个其他项目可以正常旋转,并且我希望这个新场景/视图中的项目与正常旋转项目的显示高度相匹配。

我很感激一些建议或反馈。谢谢!

编辑:这里有一个对话框,我在场景 1 上绘制两个正方形,在场景 2 上绘制两条线。当我拖动滑块时,我希望获得上述指定的行为,但所发生的只是方块正在旋转(正如它们应该的那样),而线条什么也不做(它们应该随方块一起上下移动)。请注意,没有任何编译错误。

这是对话框构造函数:

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);
}

和旋转滑块槽:

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());
}

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());
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

┼── 2025-01-09 17:46:07

以下是我想出的有效方法:

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;
};

您还需要一个包含 GraphicsView1、GraphicsView2 和 VerticalSlider 的 UI 文件。

正如我在上面的评论中提到的,我希望有一个更优雅的解决方案,因为我认为这不能适应两个场景的边界矩形不同的情况。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文