• 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!

  • 相关阅读:
    Markdown学习笔记
    Go 学习笔记(一)
    case中定义变量
    <转>MySql 与Oracle区别
    Java 时间转换问题总结
    线程之间共享
    并发编程快速入门
    redis主从复制
    jedis操作redis
    redis持久化方案
  • 原文地址:https://www.cnblogs.com/banluqiaodaima/p/14345537.html
Copyright © 2020-2023  润新知