将QGraphicsCustomItem旋转为QGraphicsScene

时间:2018-01-17 14:44:29

标签: qt rotation qgraphicsitem

我是一个使用c ++和QT的新手,但我试图尽可能多地学习

我创建了一个简单的类(称为MainWindow),使用Qt Creator(Qt 5.10.0)我将QGraphicsView设置为Mainwindows.ui

在Mainwindow构造函数中,我创建了一个QGraphicScene(链接到QGraphicsView项目),我希望用一些QGraphicsRecItems填充。

此RecItems必须以其中心点旋转,并使用给定的" Alpha"。

我已经阅读了大量的文档,尝试了很多例子,但它们仍然以画家的起源而不是他们的中心点旋转。

有人能给我一个简单的例子来实现这个目标吗?

另外,我想在QGraphicView的左下角设置原点。

由于

我已经创建了一个自定义图形项目,因为我想创建一个内部带有文本的矩形。

所以:这是名为" areagrafica.h":

的标题
#ifndef AREAGRAFICA_H
#define AREAGRAFICA_H

#include <QGraphicsItem>
#include <QGraphicsTextItem>
#include <QPainter>
#include <QPen>
#include <moduledata.h>


class Grafica_PPU : public QGraphicsItem
{
  public:
    Grafica_PPU(QString ModuleName, GraphicModuleData tmpInfoGrafiche, QPen Pen, qreal tmpAlpha);


    QRectF boundingRect() const;

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);

    private:
        GraphicModuleData infoGrafiche;
        qreal Alpha,xc,yc;

        QString Testo;

        QPen Penna;

};
#endif // AREAGRAFICA_H

这是&#34; areagrafica.cpp&#34;

#include "areagrafica.h"


Grafica_PPU::Grafica_PPU(QString ModuleName, GraphicModuleData tmpInfoGrafiche, QPen Pen, qreal tmpAlpha)
{
    infoGrafiche = tmpInfoGrafiche;
    Penna = Pen;
    Testo = ModuleName;
    Alpha = tmpAlpha;
}

QRectF Grafica_PPU::boundingRect() const
{
    return QRectF(infoGrafiche.posX,infoGrafiche.posY,infoGrafiche.Width,infoGrafiche.Height);
}

void Grafica_PPU::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
           QWidget *widget)
{
    //Penna.setWidth(5);

    painter->setPen(Penna);


    painter->setRenderHint(QPainter::Antialiasing); //Ottengo bordi senza spingoli
    painter->setRenderHint(QPainter::TextAntialiasing); //Miglioro la lettura del testo ruotato

    painter->translate(QPoint(infoGrafiche.xC,infoGrafiche.yC));
    //painter->scale(1.0, -1.0);
    painter->rotate(Alpha);

    painter->drawRect(boundingRect()); //Disegno il bordo di dimensioni scelte
    painter->drawPoint(boundingRect().center());
    painter->drawText(boundingRect(),Qt::AlignCenter,Testo); //Creo un testo avente dimensione uguale alla dimensione del modulo, con il testo allineato al centro


   // update();
}

在主类中我使用:

 Grafica_PPU *test,*test2;
    GraphicModuleData tmp;
    tmp.posX = 45;
    tmp.posY = -100;
    tmp.Height = 22;
    tmp.Width = 54;


    test = new Grafica_PPU("PP55103",tmp,*Grafico_Matita_Nera,0.0);
    test2 = new Grafica_PPU("PP55103",tmp,*Grafico_Matita_Nera,0.0);

    Grafico_Scena->addItem(test);
    Grafico_Scena->addItem(test2);

其中&#34; Grafico_Matita_Nera&#34;是Pen和&#34; Grafico_Scena&#34;是场景

1 个答案:

答案 0 :(得分:0)

您必须在矩形的中心建立变换的原点,如下所示:

QGraphicsRectItem *r = {...}
r->setTransformOriginPoint(r->rect().center());
r->setRotation(some_value)

示例:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->graphicsView->setScene(new QGraphicsScene(-100, -100, 200, 200));

    QGraphicsRectItem *r = ui->graphicsView->scene()->addRect(0, 0, 60, 60, QPen(Qt::blue), QBrush(Qt::red));
    r->setTransformOriginPoint(r->rect().center());

    QVariantAnimation *animation = new QVariantAnimation(this);
    connect(animation, &QVariantAnimation::valueChanged, [r](QVariant value){
        r->setRotation(value.toReal());
    });
    animation->setStartValue(0);
    animation->setEndValue(360);
    animation->setDuration(1000);
    animation->setLoopCount(-1);
    animation->start();
}

完整示例可在以下link中找到。

您不必旋转QPainter,如果您不必为其旋转项目,则必须使用boundingRect()的中心

Grafica_PPU::Grafica_PPU(const QString &ModuleName, GraphicModuleData tmpInfoGrafiche, QPen Pen, qreal tmpAlpha)
{
    infoGrafiche = tmpInfoGrafiche;
    Penna = Pen;
    Testo = ModuleName;
    Alpha = tmpAlpha;
    setTransformOriginPoint(boundingRect().center());
    setRotation(Alpha);
}

QRectF Grafica_PPU::boundingRect() const
{
    return QRectF(infoGrafiche.XC, infoGrafiche.YC,infoGrafiche.Width,infoGrafiche.Height);
}

void Grafica_PPU::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
           QWidget *)
{
    painter->setPen(Penna);
    painter->setRenderHint(QPainter::Antialiasing); //Ottengo bordi senza spingoli
    painter->setRenderHint(QPainter::TextAntialiasing); //Miglioro la lettura del testo ruotato
    painter->drawRect(boundingRect()); //Disegno il bordo di dimensioni scelte
    painter->drawPoint(boundingRect().center());
    painter->drawText(boundingRect(),Qt::AlignCenter,Testo); //Creo un testo avente dimensione uguale alla dimensione del modulo, con il testo allineato al centro

}

示例:

GraphicModuleData tmp{0, 0, 40, 40};
Grafica_PPU *item = new Grafica_PPU("test", tmp, QPen(Qt::red), 100);

GraphicModuleData tmp2{-50, 50, 60, 40};
Grafica_PPU *item2 = new Grafica_PPU("test", tmp2, QPen(Qt::red), 90);

ui->graphicsView->scene()->addItem(item);
ui->graphicsView->scene()->addItem(item2);

输出:

enter image description here

加:

评论:是否可以旋转矩形,但忽略文字?

void Grafica_PPU::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
           QWidget *)
{
    painter->setPen(Penna);
    painter->setRenderHint(QPainter::Antialiasing); //Ottengo bordi senza spingoli
    painter->setRenderHint(QPainter::TextAntialiasing); //Miglioro la lettura del testo ruotato
    painter->drawRect(boundingRect()); //Disegno il bordo di dimensioni scelte
    painter->translate(boundingRect().center());
    painter->rotate(-rotation());
    painter->translate(-boundingRect().center());
    painter->drawText(boundingRect(),Qt::AlignCenter,Testo); //Creo un testo avente dimensione uguale alla dimensione del modulo, con il testo allineato al centro

}

enter image description here