i'm a newbie with c++ and QT, but i've trying to learn as much as i can
i've created a simple class (called MainWindow) and with Qt Creator (Qt 5.10.0) i set a QGraphicsView into the Mainwindows.ui
inside the Mainwindow costructor i've created a QGraphicScene (linked to the QGraphicsView item) that i would like to populate with some QGraphicsRecItems.
This RecItems must to be rotated with their center point, with a given "Alpha".
I've read tons of docs, tryed lots of example, but they still rotate with the painter origin e not their center point.
Can someone give me a simple example to achive this?
Also, i would like to set the origin on the lower left point for the QGraphicView.
Thanks
i've created a custom Graphic item because i want to create a rectangle with a text inside of it.
So: this is the header called "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
and this is the "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();
}
Inside the main class i use this:
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);
where "Grafico_Matita_Nera" is a Pen and "Grafico_Scena" is the scene
You have to establish the origin of the transformations in the center of the rectangle as shown below:
QGraphicsRectItem *r = {...}
r->setTransformOriginPoint(r->rect().center());
r->setRotation(some_value)
Example:
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();
}
The complete example can be found in the following link.
You do not have to rotate the QPainter
, if you do not have to rotate the item for it you must use the center of 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
}
Example:
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);
Output:
Plus:
comment: is it possible to rotate the rectangle, but leave out the text?
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
}