painterDemo.png
C++渲染图像到QML
C++部分:
-继承QQuickPaintedItem
属性设置:Q_PROPERTY, QML_ELEMENT
函数设置:Q_INVOKABLE
-重载 void paint(QPainter *painter)效率低。
-绘制到QImage,效率高。
QPainter--drawLine
QPen
-update paint QImage
-样式设置,QQuickStyle::setStyle
QML部分。
MyPainter:
beginPaint(point)
movePaint(point)
penColor---ColorDialog
penSize---Slider
3.实现绘图板Demo。
1.QML使用到了cpp中定义的开放属性:Q_PROPERTY
value: mypainter.penSize
2.QML调用了cpp定义的方法:Q_INVOKABLE
parent.beginPaint(Qt.point(mouse.x, mouse.y));
3.QML给cpp的属性,设置新值
onValueChanged: mypainter.penSize = value
//mypainter.h
#ifndef MYPAINTER_H
#define MYPAINTER_H
#include <QObject>
#include <QQmlEngine>
#include <QPainter>
#include <QQuickPaintedItem>
#include "QDebug"
//自定义qml组件 MyPainter.
class MyPainter : public QQuickPaintedItem
{
Q_OBJECT
//画笔大小和颜色,开放属性让QML调用.
Q_PROPERTY(int penSize MEMBER penSize_ NOTIFY penSizeChanged FINAL)
Q_PROPERTY(QColor penColor MEMBER penColor_ NOTIFY penColorChanged FINAL)
// QML_ELEMENT;
public:
explicit MyPainter(QQuickPaintedItem *parent = nullptr);
//开始绘制,记录开始坐标.qml可调用
Q_INVOKABLE void beginPaint(QPoint pos) {
last_ = pos; //记录上次坐标
}
//移动
Q_INVOKABLE void movePaint(QPoint pos) {
if(img_.isNull()){
img_ = QImage(this->width(),this->height(), QImage::Format_RGB32);
}
QPainter painter(&img_);
QPen pen;
pen.setStyle(Qt::SolidLine);
pen.setWidth(penSize_); //画笔宽度/颜色
pen.setBrush(penColor_);
pen.setCapStyle(Qt::RoundCap);
pen.setJoinStyle(Qt::RoundJoin);
painter.setPen(pen);
painter.setRenderHints(QPainter::Antialiasing, true);
painter.drawLine(last_, pos);
last_ = pos;
update();
}
signals:
void penSizeChanged();
void penColorChanged();
private:
//内联函数,绘制
void paint(QPainter *painter) override
{
//qDebug() << "paint called";
// painter->setPen(QPen(Qt::red, 1)); // 蓝色,3像素宽
// painter->drawLine(QPoint(0,0), QPoint(100,100)); // 绘制线条
if(!img_.isNull()){
painter->drawImage(QPoint(0,0),img_);
}
painter->drawText(QPoint(100, 100), "test painter demo");
}
//画图绘制到img中,方便做导出和撤销动作。
QImage img_;
QPoint last_;
int penSize_ = 2; //成员
QColor penColor_ = QColor("yellow");
public slots:
};
#endif // MYPAINTER_H
//mypainter.cpp
#include "mypainter.h"
MyPainter::MyPainter(QQuickPaintedItem *parent)
: QQuickPaintedItem{parent}
{
qDebug() << "create MyPainter 构造函数";
}
//main.cpp
#include "mypainter.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
//将自定义cpp 注册成QML组件,后续版本可以直接用 QML_ELEMENT关键字。
qmlRegisterType<MyPainter>("com.example", 1, 0, "MyPainter");
//设置Control样式 Basic,Fusion,Material
//QQuickStyle::setStyle("Material");
QQmlEngine eng;
QQmlComponent com(&eng);
com.loadUrl(QUrl("qrc:/main.qml"));
if(com.isError()) qDebug() << com.errorString();//解析代码
//auto comwin = static_cast<QQuickWindow*>(com.create());
//智能指针,用完之后,ct会自动释放.
std::unique_ptr<QQuickWindow> ct(
static_cast<QQuickWindow*>(com.create()));
if(com.isError()) qDebug() << com.errorString();//运行代码
return app.exec();
}
//mypainter.h
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 1.0
import com.example 1.0 //使用自定义的cpp组件 MyPainter
import QtQuick.Dialogs 1.0
Window {
id:root
visible: true
width: 640
height: 480
title: qsTr("cpp渲染到扩展的QML类型中:绘图demo")
//cpp 扩展qml的类型MyPainter。
MyPainter {
id: mypainter
anchors.fill: parent
MouseArea {
Row{ //设置画笔粗细+颜色
spacing:10
Slider{ //修改penSize
width: 220
minimumValue:1
maximumValue:100
value: mypainter.penSize
onValueChanged: mypainter.penSize = value
}
ColorDialog{ //弹框,选中了颜色 onAccepted
id:colorDialog
color:"lightblue"
onAccepted: mypainter.penColor = color;
}
Rectangle{ //字体颜色选择。
width: 30; height: 30;
color: colorDialog.color
MouseArea{
anchors.fill: parent
onClicked: colorDialog.open()
}
}
}
anchors.fill: parent
hoverEnabled: true
//鼠标按下,记录开始位置。
onPressed: (mouse) =>
{
parent.beginPaint(Qt.point(mouse.x, mouse.y));
console.log("onPressed "+ mouse.x+" :"+ mouse.y);
}
//鼠标位置按下移动。
onPositionChanged: (mouse)=>
{ //左键未按住
if(!mouse.buttons & Qt.LeftButton) return;
parent.movePaint(Qt.point(mouse.x, mouse.y));
console.log("onMove "+ mouse.x+" :"+ mouse.y);
}
}
}
}













网友评论