QT QML 完成一个可以用鼠标改变大小和位置的矩形绘制

年底了,闲了几天,就学习了一下QML,完成一个鼠标可以交互操作的矩形绘制,个人可以想到的用途就是图像里面的ROI的设置和选取,还是有意义的,各位看完可以继续开发旋转功能,以便适应更多的应用场景。

先上个整体效果图:

1.先建立个Qt Quick 程序,我的主要QML文档如下:main.qml和Myrect.qml.前者是给窗体,用来布局Myrect元素;后者包含了矩形绘制和鼠标响应的逻辑。由于用到鼠标位置的计算,我还插入了C++类来帮助计算。

1.1 main.qml 的主要内容如下:创建 Myrect实例,然后在左下角用两个text来记录矩形左上角的坐标,要不光移动太单调,很无聊。

import QtQuick 2.12
import QtQuick.Window 2.12


Window {

    visible: true
     640
    height: 480
    title: qsTr("Hello World")

    Rectangle
    {


         500
        height: 500
        anchors.fill: parent
        Myrect
        {
            id:testrect
            clr:"red"
        }



        Text {
            anchors.bottom:  parent.bottom
            anchors.left: parent.left
            id: xpos
            text: qsTr("Xpos:"+testrect.rect_X.toString())
            font.pointSize: 25

        }
        Text {
            anchors.bottom:  parent.bottom
            anchors.left: xpos.right
            id: ypos
            text: qsTr("Ypos:"+testrect.rect_X.toString())
            font.pointSize: 25
        }



    }

}
mail.qml

1.2 Myrect.qml的主要内容如下:主要完成矩形绘制和鼠标交互的逻辑处理。

注意两点:

A: acceptedButtons: Qt.LeftButton|Qt.RightButton 必须写上,要不默认是右键不响应的;

B:onPositionChanged:相当于Vs里面的鼠标移动响应。

  1 import QtQuick 2.0
  2 
  3 Item
  4 {
  5     id:myrect
  6     anchors.fill: parent
  7 
  8     property int rect_X: 0
  9     property int rect_Y: 0
 10     property int rect_X1: 100
 11     property int rect_Y1: 100
 12    // property int rect_W: rect_X1-rect_X
 13    // property int rect_H: rect_Y1-rect_Y
 14     property int rectline 5
 15     property var  clr: null
 16     onRect_XChanged:myrect_root.requestPaint();
 17     onRect_YChanged:myrect_root.requestPaint();
 18     onRect_X1Changed:myrect_root.requestPaint();
 19     onRect_Y1Changed:myrect_root.requestPaint();
 20 
 21 
 22     Canvas
 23     {
 24 
 25          parent.width
 26       // console.log: (width)
 27        height: parent.height
 28         id:myrect_root
 29         anchors.fill: parent
 30 
 31        // var ctx= getContext("2d")
 32         onPaint:
 33         {
 34             var ctx= getContext("2d")
 35               ctx.clearRect(0,0,myrect_root.width,myrect_root.height);
 36                 ctx.beginPath()
 37             ctx.lineWidth=rectlinewidth
 38             if(clr==null)
 39             {
 40                  ctx.strokeStyle="green"
 41             }
 42             else
 43             {
 44                  ctx.strokeStyle=clr
 45             }
 46             ctx.rect(rect_X,rect_Y,(rect_X1-rect_X),(rect_Y1-rect_Y))
 47              ctx.stroke()
 48             ctx
 49         }
 50 
 51     }
 52 
 53     MouseArea
 54     {
 55 
 56         property int leftmodifyflag: -1
 57         property int rightmodifytype: -1
 58         property int rightmodifyflag: -1
 59         anchors.fill: parent
 60         id:mousezoon
 61         enabled: true
 62         hoverEnabled: true
 63         acceptedButtons: Qt.LeftButton|Qt.RightButton
 64         function calRightMousetype(mxpos,mypos,rectx,recty,rectw,recth )
 65         {
 66             return mousemath.calRihgtMouseType(mxpos,mypos,rectx,recty,rectw,recth)
 67         }
 68 
 69         onClicked:
 70         {
 71           var   rect_W=rect_X1-rect_X
 72           var   rect_H=rect_Y1-rect_Y
 73 
 74             if(mouse.button==Qt.LeftButton)
 75             {
 76                 leftmodifyflag++
 77                 leftmodifyflag=leftmodifyflag%2
 78                 console.log("leftmodifyflag:"+leftmodifyflag.toString())
 79                 if(leftmodifyflag==1)
 80                 {
 81 
 82                    //change center point
 83                    rect_X=mouse.x-rect_W*0.5
 84                    rect_Y=mouse.y-rect_H*0.5
 85                    rect_X1=mouse.x+rect_W*0.5
 86                    rect_Y1=mouse.y+rect_H*0.5
 87 
 88                 }
 89                // mouse.accepted=true
 90             }
 91              else if(mouse.button==Qt.RightButton)
 92             {
 93                 rightmodifyflag++
 94                 rightmodifyflag=rightmodifyflag%2
 95                 rightmodifytype=calRightMousetype(mouse.x,mouse.y,rect_X,rect_Y,rect_W,rect_H)
 96 
 97              }
 98             myconfig.rect_Xpro=rect_X;
 99             myconfig.rect_Ypro=rect_Y;
100             myconfig.rect_X1pro=rect_X;
101             myconfig.rect_Y1pro=rect_Y1;
102 
103             //myconfig.writeConfig();
104       }
105 
106         onPositionChanged:
107        {
108          var   rect_W=rect_X1-rect_X
109          var   rect_H=rect_Y1-rect_Y
110             if(leftmodifyflag==0)
111             {
112                 // rect_W=rect_X1-rect_X
113                 // rect_H=rect_Y1-rect_Y
114                //change center point
115                rect_X=mouse.x-rect_W*0.5
116                rect_Y=mouse.y-rect_H*0.5
117                rect_X1=mouse.x+rect_W*0.5
118                rect_Y1=mouse.y+rect_H*0.5
119             }
120             else if(rightmodifyflag==0)
121             {
122                 console.log(rightmodifytype.toString())
123                 switch(rightmodifytype)
124                 {
125                 case 0:
126                     //left
127                     rect_X=mouse.x
128                     break
129                 case 1:
130                     //up
131                     rect_Y=mouse.y
132                     break
133                 case 2:
134                     //right
135                     rect_X1=mouse.x
136                     break
137                 case 3:
138                     //up
139                     rect_Y1=mouse.y
140                     break
141                 default:
142                     //left
143                     rect_X=mouse.x
144                     break
145                 }
146             }
147             myconfig.rect_Xpro=rect_X;
148             myconfig.rect_Ypro=rect_Y;
149             myconfig.rect_X1pro=rect_X;
150             myconfig.rect_Y1pro=rect_Y1;
151 
152            // myconfig.writeConfig();
153         }
154     }
155 
156 }
Myrect.qml

2:C++数据处理部分:主要完成鼠标点击位置和矩形4边位置关系的计算。主要需要知道Qml调用C++的方法。

 1 #ifndef MOUSEMOVINGMATH_H
 2 #define MOUSEMOVINGMATH_H
 3 
 4 #endif // MOUSEMOVINGMATH_H
 5 #include <QObject>
 6 
 7 class  MouseMovingMath:public QObject
 8 {
 9         Q_OBJECT
10         public:
11     MouseMovingMath();
12     ~MouseMovingMath();
13       public :
14     Q_INVOKABLE int calRihgtMouseType(const int mxpos,const int mypos,int rectx,int recty,int recw,int recth );
15 
16     Q_INVOKABLE int test( );
17 
18 }
19 ;
MOUSEMOVINGMATH_H
  1 #include "MyrectConfig.h"
  2 
  3     MyrectConfig::MyrectConfig(QString configfilename):Myconfig(configfilename)
  4     {
  5 
  6         node="RectProperty";
  7     }
  8 
  9     MyrectConfig::~MyrectConfig()
 10     {
 11 
 12     }
 13 
 14    void  MyrectConfig::readConfig()
 15     {
 16        rect_X= getValue(node,"rect_X").toInt();
 17        rect_Y= getValue(node,"rect_Y").toInt();
 18        rect_X1= getValue(node,"rect_X1").toInt();
 19        rect_Y1= getValue(node,"rect_Y1").toInt();
 20        rect_Color=getValue(node,"rect_Color").toString();
 21         //Transfer color data
 22         auto colorarray=  rect_Color.split(";",QString::SplitBehavior::SkipEmptyParts,Qt::CaseSensitivity::CaseSensitive);
 23         if(colorarray.length()==4)
 24         {
 25             rect_color_r=colorarray[0].toFloat();
 26             rect_color_g=colorarray[1].toFloat();
 27             rect_color_b=colorarray[2].toFloat();
 28             rect_color_a=colorarray[3].toFloat();
 29 
 30         }
 31         else
 32         {
 33             rect_color_r=0.1;
 34             rect_color_g=0.1;
 35             rect_color_b=0.1;
 36             rect_color_a=1;
 37         }
 38     }
 39    void  MyrectConfig::writeConfig()
 40     {
 41         setValue(node,"rect_X",rect_X);
 42         setValue(node,"rect_Y",rect_Y);
 43         setValue(node,"rect_X1",rect_X1);
 44         setValue(node,"rect_Y1",rect_Y1);
 45         rect_Color=QString("%1;%2;%3;%4").arg(rect_color_r).arg(rect_color_g).arg(rect_color_b).arg(rect_color_a);
 46         setValue(node,"rect_Color",rect_Color);
 47    }
 48 
 49    int MyrectConfig::rect_Xpro()
 50    {
 51        return rect_X;
 52    }
 53    int  MyrectConfig::rect_Ypro()
 54    {
 55         return rect_Y;
 56    }
 57    int  MyrectConfig::rect_X1pro()
 58    {
 59          return rect_X1;
 60    }
 61    int  MyrectConfig::rect_Y1pro()
 62    {
 63         return rect_Y1;
 64    }
 65 
 66    void MyrectConfig::set_rect_Xpro(int v)
 67    {
 68         rect_X=v;
 69    }
 70    void  MyrectConfig::set_rect_Ypro(int v)
 71    {
 72          rect_Y=v;
 73    }
 74    void  MyrectConfig::set_rect_X1pro(int v)
 75    {
 76           rect_X1=v;
 77    }
 78    void  MyrectConfig::set_rect_Y1pro(int v)
 79    {
 80          rect_Y1=v;
 81    }
 82 
 83 
 84    float  MyrectConfig::rect_color_rpro()
 85    {
 86          return rect_color_r;
 87    }
 88    float  MyrectConfig::rect_color_gpro()
 89    {
 90         return rect_color_g;
 91    }
 92    float  MyrectConfig::rect_color_bpro()
 93    {
 94         return rect_color_b;
 95    }
 96    float  MyrectConfig::rect_color_apro()
 97    {
 98         return rect_color_a;
 99    }
100 
101    void  MyrectConfig::set_rect_color_rpro(float v)
102    {
103           rect_color_r=v;
104    }
105    void  MyrectConfig::set_rect_color_gpro(float v)
106    {
107          rect_color_g=v;
108    }
109    void  MyrectConfig::set_rect_color_bpro(float v)
110    {
111          rect_color_b=v;
112    }
113    void  MyrectConfig::set_rect_color_apro(float v)
114    {
115          rect_color_a=v;
116    }
MyrectConfigcpp

2.1:初始化C++函数的调用

engine.rootContext()->setContextProperty("mousemath",&mousemovingmath);

3.主要实现功能,左键点击一次,矩形将跟随着鼠标的中心移动,左键第二次,移动停止,再则周而复始。

右键点击一次,矩形最靠近右键点击位置的边将随着鼠标的移动,即改变矩形的大小,右键第二次,移动停止,再则周而复始。

上几个图,放置视频不可见。呵呵。

 

需要源码联系我!转载请注明出处。

BR!

原文地址:https://www.cnblogs.com/banluqiaodaima/p/14345537.html