天天看點

QMl自定義繪制圖形(一)

QML繪制圖形——矩形

    • 邏輯的代碼

QML中繪圖方式有多種,Canvas是一種,QQuickPaintedItem(C++實作)是一種.這篇文章用第二種方法來實作圖形的繪制(本文隻講矩形),對象類型在main.cpp裡聲明後就可以用。這種方法的優點是邏輯用C++實作, 界面隻負責綁定資料, 邏輯跟界面分離。在邏輯裡可以內建更多的圖形類型,然後對其封裝,寫成插件,使用起來更簡單。

第一步:建立一個Qt Quick Application -Empty 項目

第二步:添加一個C++類 并且繼承自 QQuickPaintedItem

第三步:把類型注冊到Qml裡,在qml調用的話直接import “module” 即可

邏輯的代碼

qmlrect.h

#ifndef QMLRECT_H
#define QMLRECT_H

#include <QQuickPaintedItem>
#include <QPointF>
#include <QRectF>

class QmlRect : public QQuickPaintedItem
{
    Q_OBJECT
public:
    QmlRect();

    Q_INVOKABLE void pressEvent(const QPointF &p);
    Q_INVOKABLE void moveEvent(const QPointF &p);
    Q_INVOKABLE void releaseEvent(const QPointF &p);
    virtual void paint(QPainter *painter) override;
private:
    QRectF  m_rect;
};

#endif // QMLRECT_H
           

qmlrect.cpp

#include "qmlrect.h"
#include <QPainter>

QmlRect::QmlRect()
{
    m_rect = QRectF();
}

void QmlRect::pressEvent(const QPointF &p)
{
    m_rect.setTopLeft(p);
}

void QmlRect::moveEvent(const QPointF &p)
{
    m_rect.setBottomRight(p);
    update();
}

void QmlRect::releaseEvent(const QPointF &p)
{
    m_rect.setBottomRight(p);
    update();
}

void QmlRect::paint(QPainter *painter)
{
    painter->setRenderHint(QPainter::Antialiasing,true);
    painter->drawRect(m_rect);
}
           

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "qmlrect.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

   QQmlApplicationEngine engine;
   ==把QmlRect注冊到Qml中==
  qmlRegisterType<QmlRect>("Area",1,0,"QmlRect");
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
           

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import Area 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    QmlRect{
        id:rect
        anchors.fill: parent
        MouseArea{
            anchors.fill: parent
            onPressed: {
                rect.pressEvent(Qt.point(mouse.x,mouse.y))
            }
            onPositionChanged: {
                rect.moveEvent(Qt.point(mouse.x,mouse.y))
            }
            onReleased: {
                rect.releaseEvent(Qt.point(mouse.x,mouse.y))
            }
        }
    }
}
           
qml