Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Rotating a SVG image



  • Greetings,

    I am trying to rotate a needle (an SVG image). The image does get loaded as expected, but it does not rotate; the paintEvent does not get called either.

    This document
    https://doc.qt.io/qt-5/qwidget.html#paintEvent

    states that calling update() will invoke the paintEvent()
    In my current situation that does not happen, which likely explains why it does not rotate the svg image.

    Any idea what could be wrong ?

    Thanks,

    This is my main.cpp

    int main(int argc, char *argv[])
    {
    	QApplication a(argc, argv);
    	Gauge gauge;
    
    	gauge.setSkin("Tachometer");
    	gauge.setNeedleOrigin(0.486, 0.486);
    	gauge.setMinimum(0);
    	gauge.setMaximum(120);
    	gauge.setStartAngle(-130);
    	gauge.setEndAngle(133);
    
    	gauge.setValue(0);
    
    	return a.exec();
    }
    

    gauge.cpp

    // constructor
    Gauge::Gauge(QWidget *parent)
    	: QWidget(parent),
    	m_minimum(0),
    	m_maximum(100),
    	m_value(0),
    	m_startAngle(0),
    	m_endAngle(100),
    	m_originX(0.5),
    	m_originY(0.5)
    {
    	setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
    }
    
    // set skin for the widget
    void Gauge::setSkin(const QString &skin)
    {
    	m_skin = skin;
    
    	background = new QGraphicsSvgItem(":/Skins/Tachometer/background.svg");
    	background->setCachingEnabled(QGraphicsItem::NoCache);
    
    	shadow = new QGraphicsSvgItem(":/Skins/Tachometer/needle_shadow.svg");
    	shadow->setCachingEnabled(QGraphicsItem::NoCache);
    
    	needle = new QGraphicsSvgItem(":/Skins/Tachometer/needle.svg");
    	needle->setCachingEnabled(QGraphicsItem::NoCache);
    
    	overlay = new QGraphicsSvgItem(":/Skins/Tachometer/overlay.svg");
    	overlay->setCachingEnabled(QGraphicsItem::NoCache);
    
    	scene = new QGraphicsScene;
    	scene->setSceneRect(background->boundingRect());
    
    	view = new QGraphicsView(scene);
    
    	scene->addItem(background);
    	scene->addItem(shadow);
    	scene->addItem(needle);
    	scene->addItem(overlay);
    
    	// SVG item positioning
    	// position should be topLeft, if view->rect().center is used,
    	// the SVG top left corner will be set to the view.center
    	// That will not be the real center one would be expecting
    	background->setPos(view->rect().topLeft());
    	shadow->setPos(view->rect().topLeft());
    	needle->setPos(view->rect().topLeft());
    	overlay->setPos(view->rect().topLeft());
    
    	updateGeometry();
    	qDebug() << "update(), Call paintEvent";
    	update();						// call paintEvent
    
    	view->show();
    }
    
    // set actual value to widget
    void Gauge::setValue(int value)
    {
    	if (value < m_minimum)
    		value = m_minimum;
    
    	else if (value > m_maximum)
    		value = m_maximum;
    
    	m_value = value;
    	update();
    }
    
    void Gauge::paintEvent(QPaintEvent *event)
    {
    	QPainter painter(this);
    	Q_UNUSED(event);
    
    	qreal xc = needle->boundingRect().width() * 0.5;
    	qreal yc =needle->boundingRect().height() * 0.5;
    
    	qDebug() << "Hello from paintEvent";
    	painter.translate(xc, yc);
    	painter.rotate(45);
    	painter.translate(-xc, -yc);
    }
    
    

    gauge.h

    class Gauge : public QWidget
    {
    	Q_OBJECT
    public:
    	explicit Gauge(QWidget *parent = nullptr);
    	~Gauge();
    
    	void setSkin(const QString& skin);
    	QString skin() const;
    
    	void setMinimum(int minimum);
    	void setMaximum(int maximum);
    	void setNeedleOrigin(qreal x, qreal y);
    	void setStartAngle(qreal angle);
    	void setEndAngle(qreal angle);
    
    public slots:
    	void setValue(int value);
    
    signals:
    
    
    private:
    	QRectF availableRect(QGraphicsSvgItem *item) const;
    	QGraphicsSvgItem *background;
    	QGraphicsSvgItem *shadow;
    	QGraphicsSvgItem *needle;
    	QGraphicsSvgItem *overlay;
    
    	QGraphicsScene *scene;
    	QGraphicsView *view;
    
    	int m_minimum;						/** minimum possible value **/
    	int m_maximum;						/** maximum possible value **/
    	int m_value;						/** actual value **/
    
    	qreal m_startAngle;					/** smallest start angle **/
    	qreal m_endAngle;					/** largest end angle **/
    	qreal m_originX;					/** position x of needle **/
    	qreal m_originY;					/** position y of needle **/
    
    	QString m_skin;						/** name of actual skin **/
    protected:
    	void paintEvent(QPaintEvent *event) override;
    };
    

    GaugeWidget.PNG


  • Lifetime Qt Champion

    You completely overwrite paintEvent() and don't paint anything... !? Also I don't understand what QGraphicsScene and others should do.



  • Greetings,

    @Christian-Ehrlicher said in Rotating a SVG image:

    You completely overwrite paintEvent() and don't paint anything... !? Also I don't understand what QGraphicsScene and others should do.

    I am not sure, what else to be used in there ? The needle is a SVG image, should I use the setPen() or setBrush() ?

    Most likely, I'm missing something, you appear to be quite terse.
    Previously, the QT website itself had a fair amount examples, recently the code examples themselves are terse and confusing.

    Dont know what else to say!

    But, Thanks!


  • Lifetime Qt Champion

    I simply don't understand what your code tries to do - you create a QGraphicsScene but don't use it, you overwrite paintEvent() but don't paint anything in there so your widget can't display anything. You create a QGraphicsView inside a widget but show it as standalone widget - it's just confusing.
    btw: QGpraphicsObject has a rotation property.


Log in to reply