【qml】 在QML场景图中使用QPainter 的方法_qquickpainteditem-CSDN博客
QQuickPaintedItem
1.官方资料
QQuickPaintedItem类提供了一种在QML场景图中使用QPainter API的方法。
QQuickPaintedItem使QPainter API与QML场景图一起使用成为可能。它在场景图中设置了一个纹理矩形,并使用QPainter在纹理上作画。
1) 要编写自己的绘制项,首先要创建QQuickPaintedItem的一个子类,然后实现其惟一的纯虚拟公共函数paint(),该函数实现实际的绘制。绘制将在从0,0到width(),height()的矩形内。
2)调用update()来触发重绘。
3)要使QPainter做抗锯齿渲染,使用setAntialiasing()
4)渲染目标可以是QImage,也可以是使用OpenGL时的QOpenGLFramebufferObject。当渲染目标是一个QImage时,QPainter首先渲染到图像中,然后将内容上传到纹理中。当使用QOpenGLFramebufferObject时,QPainter直接在纹理上作画。
**注意:**重要的是要理解这些项目可能引起的性能影响。
参见QQuickPaintedItem::RenderTarget和QQuickPaintedItem::RenderTarget。
1.1. Public Types
1) enum QQuickPaintedItem::PerformanceHint
flags QQuickPaintedItem::PerformanceHints
此枚举描述了可以启用的标志,以提高QQuickPaintedItem中的呈现性能。默认情况下,没有设置这些标志。
2) enum QQuickPaintedItem::RenderTarget
渲染目标是QPainter在项目在屏幕上渲染之前绘制的表面。
1.2. Properties
1) fillColor : QColor
背景填充的颜色。默认为Qt::transparent。
2) renderTarget : RenderTarget
3) textureSize : QSize
纹理大小。
改变纹理的大小不会影响paint()中使用的坐标系统。取而代之的是一个比例因子,所以绘画应该仍然发生在0,0到width(),height()。
默认情况下,纹理大小将与此项目相同。
注意:如果项目位于设备像素比不等于1的窗口上,则此缩放因子将隐式应用于纹理大小。
1.3. Public Functions
Mipmapping 是一种图像处理技术,它采用一个原始的、高分辨率的纹理图像或映射和过滤器,并在同一个纹理文件中将其扩展为多个分辨率更小的纹理映射。依据不同精度的要求,而使用不同版本的材质图样进行贴图
1.4. Reimplemented Public Functions
1.5. Signals
1) void fillColorChanged()
2) void renderTargetChanged()
3) void textureSizeChanged()
1.6. Reimplemented Protected Functions
1) virtual void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override
2) virtual void releaseResources() override
3) virtual QSGNode * updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) override
2. 案例
2.1. QuickPaintedItem 类
2.1.1. QuickPaintedItem.h
#ifndef QUICKPAINTEDITEM_H
#define QUICKPAINTEDITEM_H
#include <QPainterPath>
#include <QtQuick>
class QuickPaintedItem : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(bool draw READ isDraw WRITE setDraw NOTIFY drawChanged)
Q_PROPERTY(bool antialias READ isAntialias WRITE setAntialias NOTIFY antialiasChanged)
public:
QuickPaintedItem(QQuickItem *parent = 0);
void paint(QPainter *painter) override;
Q_INVOKABLE void mousePress (qreal x, qreal y) ;
Q_INVOKABLE void mouseMove (qreal x, qreal y) ;
Q_INVOKABLE void mouseRelease (qreal x, qreal y) ;
bool isDraw() const;
void setDraw(bool newDraw);
bool isAntialias() const;
void setAntialias(bool newAntialias);
private:
signals:
void drawChanged();
void antialiasChanged();
private:
bool draw;
QPainterPath m_path;
QPolygonF m_poly;
};
#endif
2.1.2. QuickPaintedItem.cpp
#include "QuickPaintedItem.h"
#include <QDebug>
#define qout if( 1 ) qDebug()
static QPointF startPoint, lastPoint;
QuickPaintedItem::QuickPaintedItem(QQuickItem *parent)
: QQuickPaintedItem(parent)
, draw(false)
{
}
void QuickPaintedItem::paint(QPainter *painter)
{
painter->drawPath(m_path);
painter->drawPolyline(m_poly);
if(startPoint.isNull() || lastPoint.isNull())
return;
if(draw){
painter->setPen(Qt::red);
painter->drawLine(startPoint,lastPoint);
}
}
void QuickPaintedItem::mousePress(qreal x, qreal y)
{
startPoint.rx() = x;
startPoint.ry() = y;
if(draw){
m_path.addRect(x-1,y-1,2,2);
m_poly.append(startPoint);
update();
}
}
void QuickPaintedItem::mouseMove(qreal x, qreal y)
{
lastPoint.rx() = x;
lastPoint.ry() = y;
update();
}
void QuickPaintedItem::mouseRelease(qreal x, qreal y)
{
if(draw){
lastPoint.rx() = x;
lastPoint.ry() = y;
}else{
}
update();
}
bool QuickPaintedItem::isDraw() const
{
return draw;
}
void QuickPaintedItem::setDraw(bool newDraw)
{
if(newDraw==false) {
startPoint = lastPoint = QPointF();
m_path.addPolygon(m_poly);
m_path.closeSubpath();
m_poly = QPolygonF();
update();
}
if (draw == newDraw)
return;
draw = newDraw;
emit drawChanged();
}
bool QuickPaintedItem::isAntialias() const
{
return antialiasing();
}
void QuickPaintedItem::setAntialias(bool newAntialias)
{
if (antialiasing() == newAntialias)
return;
setAntialiasing(newAntialias);
emit antialiasChanged();
}
2.2. main.qml
import QtQuick 2.0
import QtQml.Models 2.15
import MyQuickPaintedItem 1.0
Item {
height: 480
width: 320
QuickPaintedItem {
id: drawer
anchors.fill: parent
antialias: true
MouseArea{
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled:true
onPressed: {
if(mouse.button == Qt.LeftButton){
drawer.draw = true;
parent.mousePress(mouseX,mouseY)
}
else{
drawer.draw = false;
}
}
onPositionChanged: {
parent.mouseMove(mouseX,mouseY)
}
onReleased: {
if(mouse.button == Qt.LeftButton)
parent.mouseRelease(mouseX,mouseY)
}
}
}
}
2.3. main.cpp
#include <QApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "QuickPaintedItem.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQuickView view;
qmlRegisterType<QuickPaintedItem>("MyQuickPaintedItem",1,0,"QuickPaintedItem");
view.setSource(QUrl(QStringLiteral("qrc:/painteditem/main.qml")));
view.show();
return app.exec();
}