2DグラフィックスでのQT C ++は、PC(Windows、Linux、およびMac用)で良好な性能を持っている、非常に完璧に行われました。
QT QMLは、特に、QMLは、いくつかの基本的な形状タイプは、携帯端末アプリケーションの開発に適したQtのC ++に対応する一つ一つではなく、QML C ++によって拡張することができます。
QQuickPaintedItemは、QQuickItemからQMLで2Dグラフィックアイテムを拡張するQPainterのAPIを使用する方法を継承しました。
QQuickPaintedItemは、特定のグラフィック項目の実際の形状を得るためQGraphicsItem()メソッドなどの形状のように設けられていないが、()メソッドが含まれて含まれている、我々は、マウスが、間接的に動作点が、実際の形状の範囲に含まれるか否かを判断する組み合わせることができます。
直接テストコードで騒ぎ、:
CustomItem.h
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#ifndefの
CUSTOMITEM_H の#define CUSTOMITEM_H の#include <QQuickPaintedItem> の#include <QQuickItem> の#include <QMouseEvent> の#include <QPainterの> クラス CustomItemの: 公共 QQuickPaintedItem { Q_OBJECT Q_PROPERTY(QStringの名前READ名ライトのsetName) Q_PROPERTY(QColor色READ色書き込みsetColorを) 公共 : CustomItemの(QQuickItem *親= nullptr); 名前()QStringの ポーラ 。 空 のsetName( のconst QStringの&名前)。 QColor色() CONST ; 空 setColorを( のconst QColor&カラー)。 実際の塗装用の塗料を()をオーバーライド//。 仮想ボイド ペイント(QPainterの*画家)。// QML用の形状マスク、Q_INVOKABLEためcontans()をオーバーライドします。 Q_INVOKABLE 仮想ブール値 (含まれているのconst QPointF&ポイント) のconstを。仮想空 mousePressEvent(QMouseEvent *イベント)。仮想空 mouseMoveEvent(QMouseEvent *イベント)。仮想空 mouseReleaseEvent(QMouseEvent *イベント)。プライベート: M_NAMEをQStringの。 QColorのm_color。}。 #endifの // CUSTOMITEM_H |
CustomItem.cpp
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
#include
"CustomItem.h"
#include <QPainter> #include <QPainterPathStroker> #include <QDebug> CustomItem::CustomItem(QQuickItem *parent) : QQuickPaintedItem(parent) { setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton); setFlag(QQuickItem::ItemHasContents); } QString CustomItem::name() const { return m_name; } void CustomItem::setName( const QString &name) { m_name = name; } QColor CustomItem::color() const { return m_color; } void CustomItem::setColor( const QColor &color) { m_color = color; } void CustomItem::paint(QPainter *painter) { // pen & brush QPen pen(m_color, 10 ); QLinearGradient gradient; gradient.setStart( 0 , 50 ); gradient.setFinalStop( 200 , 50 ); gradient.setColorAt( 0 , Qt::blue); gradient.setColorAt( 0 . 2 , Qt::green); gradient.setColorAt( 0 . 4 , Qt::red); gradient.setColorAt( 0 . 6 , Qt::yellow); gradient.setColorAt( 1 , Qt::cyan); painter->setPen(pen); painter->setBrush(gradient); painter->setRenderHints(QPainter::Antialiasing, true ); // Unclosed shape static const QPointF points[ 3 ] = { QPointF( 10 . 0 , 100 . 0 ), QPointF( 20 . 0 , 10 . 0 ), QPointF( 200 . 0 , 50 . 0 ), }; painter->save(); pen.setJoinStyle(Qt::MiterJoin); // MiterJoin, BevelJoin, RoundJoin pen.setCapStyle(Qt::RoundCap); // FlatCap, SquareCap, RoundCap pen.setStyle(Qt::DashLine); painter->drawPolyline(points, 3 ); painter->restore(); // Closed shape QPainterPath path; path.addEllipse(QRectF( 10 . 0 , 10 . 0 , width() - 10 . 0 , height() - 10 . 0 )); painter->drawPath(path); /* 三角形 QPainterPath path; path.moveTo(width() / 2, 0); path.lineTo(width(), height()); path.lineTo(0, height()); path.lineTo(width() / 2, 0); painter->fillPath(path, m_color); */ } bool CustomItem::contains( const QPointF &point) const { // Unclosed shape static const QPointF points[ 3 ] = { QPointF( 10 . 0 , 100 . 0 ), QPointF( 20 . 0 , 10 . 0 ), QPointF( 200 . 0 , 50 . 0 ), }; QPainterPath path; path.moveTo(points[ 0 ]); path.lineTo(points[ 1 ]); path.lineTo(points[ 2 ]); QPainterPathStroker stroker; stroker.setWidth( 10 ); stroker.setJoinStyle(Qt::MiterJoin); stroker.setCapStyle(Qt::RoundCap); stroker.setDashPattern(Qt::SolidLine); return stroker.createStroke(path).contains(point); // Close shape QPainterPath path; path.addEllipse(QRectF( 10 . 0 , 10 . 0 , width() - 10 . 0 , height() - 10 . 0 )); QPainterPathStroker stroker; stroker.setWidth( 10 ); return path.contains(point) || stroker.createStroke(path).contains(point); /* 三角形 QPainterPath path; path.moveTo(width() / 2, 0); path.lineTo(width(), height()); path.lineTo(0, height()); path.lineTo(width() / 2, 0); QPainterPathStroker stroker; stroker.setWidth(10); return return path.contains(point) || stroker.createStroke(path).contains(point); */ } void CustomItem::mousePressEvent(QMouseEvent *event) { qDebug() << "CustomItem::mousePressEvent" ; QQuickPaintedItem::mousePressEvent(event); } void CustomItem::mouseMoveEvent(QMouseEvent *event) { qDebug() << "CustomItem::mouseMoveEvent" ; QQuickPaintedItem::mouseMoveEvent(event); } void CustomItem::mouseReleaseEvent(QMouseEvent *event) { qDebug() << "CustomItem::mouseReleaseEvent" ; QQuickPaintedItem::mouseReleaseEvent(event); } |
在main.cpp中注册CustomItem类型:qmlRegisterType<CustomItem>("CustomItem", 1, 0, "CustomItem");
main.cpp
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include
<QGuiApplication> #include <QQmlApplicationEngine> #include "CustomItem.h" int main( int argc, char *argv[]) { qputenv( "QT_IM_MODULE" , QByteArray( "qtvirtualkeyboard" )); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); qmlRegisterType<CustomItem>( "CustomItem" , 1 , 0 , "CustomItem" ); QQmlApplicationEngine engine; 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(); } |
在qml文件中使用:
main.qml
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
import
QtQuick
2
.
12
import QtQuick.Window 2 . 12 import QtQuick.Controls 2 . 5 import CustomItem 1 . 0 Window { id: window visible: true width: 640 height: 480 title: qsTr( "qml-2d-viewer" ) Button { id: btn anchors.right: parent.right anchors.bottom: parent.bottom text: "Populate" onClicked: { var object = Qt.createQmlObject( 'import QtQuick 2.12; import CustomItem 1 . 0 ; CustomItem { width: 100 height: 50 x: window.width * Math.random() y: window.height * Math.random() name: "A simple Rectangle Item" color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1 ) MouseArea { anchors.fill: parent onPressed: { if (parent.contains(Qt.point(mouse.x, mouse.y))){ drag.target = parent parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1 ); parent.update(); } else { drag.target = null } } drag.axis: Drag.XAndYAxis drag.minimumX: 0 drag.maximumX: window.width - parent.width drag.minimumY: 0 drag.maximumY: window.height - parent.width } } ', parent, "dynamicSnippet" ); } } // QML Rectangle Type Rectangle { id: blueSquare width: 120 ; height: 120 x: window.width - width - 10 ; y: 10 // making this item draggable, so don't use anchors color: "blue" visible: false Text { text: "Drag" ; font.pixelSize: 16 ; color: "white" ; anchors.centerIn: parent } MouseArea { anchors.fill: parent //! [drag] drag.target: blueSquare drag.axis: Drag.XAndYAxis drag.minimumX: 0 drag.maximumX: window.width - parent.width drag.minimumY: 0 drag.maximumY: window.height - parent.width //! [drag] } } // CustomItem Type Inherited from QQuickPaintedItem CustomItem { id: aRectangle width: 200 height: 100 name: "A simple Rectangle Item" color: "red" MouseArea { anchors.fill: parent onPressed: { if (parent.contains(Qt.point(mouse.x, mouse.y))){ drag.target = parent parent.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1 ); parent.update(); } else { drag.target = null } } drag.axis: Drag.XAndYAxis drag.minimumX: 0 drag.maximumX: window.width - parent.width drag.minimumY: 0 drag.maximumY: window.height - parent.width } } } |
Q_INVOKABLE宏将contains()方法注册到元对象系统中,这样QML就可以调用该方法来判断鼠标指针点是否在图形项形状区域,从而实现精准拾取。
在QML中MouseArea为简单的鼠标交互提供了方便,比较容易使用,如果有了MouseArea,则C++中的鼠标响应事件就不再响应。