精密マウスQQuickPaintedItemピックアップ(ピック/選択)研究

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++中的鼠标响应事件就不再响应。

おすすめ

転載: www.cnblogs.com/MakeView660/p/11238422.html