QML中FRAMELESS 和 transparent 窗体的拖动实现

来源:互联网 发布:白金数据漫画 编辑:程序博客网 时间:2024/05/22 18:55

之前的blog中写到如何设置窗体无边框以及设置背景透明,参考Qt中设置QML窗体无边框和背景透明

因为,窗体设置成无边框之后,窗体的拖动就要靠自己写的程序来完成了!

本文参考Resize Qml window这篇文章,结合自己的需求解决了拖动窗体的需要!

 首先,介绍上面这个参考文章里的解决方法:

核心思想是:

在main中引入QMainWindow对象,将qml文件作为该对象的widget,并将该对象注册到qml中,然后再qml中通过识别鼠标的位移来更改这个mainwindow的pos属性。

 

实现:

1、win.cpp:

#include <QApplication> #include <QDeclarativeView> #include <QMainWindow> #include <QDeclarativeContext>  int main(int argc, char *argv[]) {     QApplication app(argc, argv);      QMainWindow window;      QDeclarativeView* v = new QDeclarativeView;     window.setCentralWidget(v);      v->setSource(QUrl::fromLocalFile(("draw_rectangles.qml")));         // expose window object to QML     v->rootContext()->setContextProperty("mainwindow",&window);      window.setStyleSheet("background:transparent;");     window.setAttribute(Qt::WA_TranslucentBackground);     window.setWindowFlags(Qt::FramelessWindowHint);     window.show();      app.exec(); } 

 

2、在pro文件中加入下列语句

win.pro:

TEMPLATE += app QT += gui declarative SOURCES += win.cpp 

 

3、qml文件中识别鼠标事件,然后更改窗体的坐标

draw_rectangles.qml:

importQt 4.7

 
Item {           
         Rectangle { 
             color: "blue" 
             x: 50; y: 50; width: 100; height: 100 
 
            MouseArea { 
                id: mouseRegion 
                anchors.fill: parent; 
                property variant clickPos: "1,1" 
 
                onPressed: { 
                    clickPos  = Qt.point(mouse.x,mouse.y) 
                } 
 
                onPositionChanged: { 
                    var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y) 
                    mainwindow.pos = Qt.point(mainwindow.pos.x+delta.x, 
                                      mainwindow.pos.y+delta.y) 
                } 
            } //mousearea
         } //rectangle
 } 

 

这样,通过拖拽蓝色的矩形框就可以实现窗体的拖动效果了!

对于窗体的大小更改效果,同样是采用类似的方法,这个我以后实现了再来写一篇blog吧!

 

其次,我自己的实现方法是,结合之前的blog中(Qt中更改鼠标图形)提到的将一个view对象先注册到(或者称暴露给)qml,然后再qml中识别鼠标的拖拽位移,并将位移传递给对象的某个方法。

实现如下:

1、cpp中声明与实现:

void mmove(intx, inty);

void MyDeclarativeView::mmove(intx,int y)

{
    move(x,y);//(in qml) call function
}

 

2、qml中调用:(结合上一篇blog中提到的更改鼠标cursor图案)

    Rectangle{
        id: topTitleContainer
        MouseArea{
            anchors.fill: parent
            property variant clickPos: "1,1"
            onPressed: {
                clickPos  = Qt.point(mouse.x,mouse.y)
                WindowControl.msetcursor(topTitleContainer,"SizeAllCursor")
            }
            onPositionChanged: {
                var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
                WindowControl.mmove(WindowControl.pos.x+delta.x,
                                   WindowControl.pos.y+delta.y);
            }
            onReleased: {
                WindowControl.msetcursor(topTitleContainer,"ArrowCursor")
            }
        }
    }

 

以上就算是我的实现了,由于在qml中无法直接调用declarativeview的move方法,所以才中转了一下,让qml调用view的一个方法,在方法里调用view的move方法。

这也是我照葫芦画瓢,完成的,不一定是最优的,仅供参考!希望对你有帮助!

 

 

注:这里的view的move方法的x,y参数是窗体左上角的绝对坐标。即窗体相对于显示屏左上角的坐标,是希望窗体左上角移动到(x,y)点上,而不是希望窗体移动x和y个单位。

原创粉丝点击