将 QGraphicsCustomItem 旋转到 QGraphicsScene

Rotate QGraphicsCustomItem into a QGraphicsScene

我是 C++ 和 QT 的新手,但我正在努力学习尽可能多的东西

我创建了一个简单的 class(称为 MainWindow),并使用 Qt Creator (Qt 5.10.0) 在 Mainwindows.ui

中设置了一个 QGraphicsView

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

此 RecItems 必须根据给定的 "Alpha".

以其中心点旋转

我阅读了大量文档,尝试了很多示例,但它们仍然以画家原点而不是中心点旋转。

谁能给我一个简单的例子来实现这个?

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

谢谢

我创建了一个自定义图形项,因为我想创建一个矩形,其中包含文本。

所以:这是 header 称为 "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

这是 "areagrafica.cpp"

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

在主要 class 里面我用这个:

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

其中 "Grafico_Matita_Nera" 是笔,"Grafico_Scena" 是场景

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

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

输出:

加上:

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

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

}