在上一期的QGraphicsItem图片,图形不随QGraphicsScene的缩放而缩放的博客中讲解过通过painter->matrix().m11()获取缩放比例,然后对这个比例做处理来实现不随场景的缩放而缩放,但是也留了一个问题,那就是对于文字和不规则图形都没法实现不随场景的缩放而缩放。
经过一段时间的研究用到另外一种方式来实现了不随场景缩放而缩放的功能,且支持任何图片,图形,文字。思路还是来源于我之前写的一篇文章的Qt提升绘制效率,绘制加速。
效果图:
实现思路:
将要绘制的所有图形都先按照正常的比例进行绘制,绘制的画布设置为图片,这样相对于绘制了一张图片。然后将这张图片按照缩放比例来进行绘制。
实现代码:
.h
#ifndef MACHORMETER_H
#define MACHORMETER_H
#include <QGraphicsObject>
#include <QPainter>
class MAchorItem : public QGraphicsObject
{
Q_OBJECT
public:
MAchorItem(QPointF pt,double w,double h);
void setPos(QPointF p){m_startPos = p;update();}
virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr);
private:
QPointF m_startPos;
double m_w;
double m_h;
double m_scaleFactor = 0;
QImage _img;
void drawMeter();
};
#endif // MACHORMETER_H
.cpp
#include "machormeter.h"
#include <QDebug>
MAchorItem::MAchorItem(QPointF pt, double w, double h)
{
m_startPos = pt;
m_w = w;
m_h = h;
drawMeter();
}
QRectF MAchorItem::boundingRect() const
{
return QRectF(m_startPos.x() - m_w/2,m_startPos.y() - m_h/2,m_w,m_h);
}
void MAchorItem::drawMeter()
{
QImage img(boundingRect().width(),boundingRect().height(),QImage::Format_ARGB32);
QPainter p(&img);
img.fill(QColor("#00000000"));
p.setRenderHint(QPainter::Antialiasing);
QPen pen;
p.drawPixmap(QRectF(0,88,m_w,m_w-14),QPixmap(":/img/anchormeter.png").scaled(m_w,m_w-14,Qt::IgnoreAspectRatio,Qt::SmoothTransformation),QRectF());
p.save();
p.translate(m_w/2,295);
pen.setWidthF(3);
pen.setColor("#ff01dc");
p.setPen(pen);
p.drawEllipse(QPointF(0,0),281,281);
p.save();
p.rotate(-60);
QFont font;
font.setFamily("Helvetica-Condensed");
font.setPointSize(20);
p.setFont(font);
p.drawText(QRectF(-50,235,100,50),Qt::AlignCenter,"16M");
p.restore();
pen.setWidthF(2);
pen.setColor("#22ad36");
p.setPen(pen);
p.drawEllipse(QPointF(0,0),11,11);
p.restore();
p.setPen(Qt::NoPen);
p.setBrush(QBrush(QColor("#bf272c")));
p.drawRect(m_w/2,118,12,31);
p.end();
_img = img;
}
void MAchorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
double scaleFactor = painter->matrix().m11();
if (scaleFactor > 0)
m_scaleFactor = scaleFactor;
QPen pen = painter->pen();
double oldwidthF = pen.widthF();
pen.setWidthF(oldwidthF / m_scaleFactor);
painter->drawImage(QRectF(m_startPos.x()-m_w/m_scaleFactor/2,m_startPos.y()-m_h/m_scaleFactor/2,m_w/m_scaleFactor,m_h/m_scaleFactor),_img);
}