1. 程式人生 > >QML中FRAMELESS 和 transparent 窗體的拖動實現

QML中FRAMELESS 和 transparent 窗體的拖動實現

之前的blog中寫到如何設定窗體無邊框以及設定背景透明,參考

因為,窗體設定成無邊框之後,窗體的拖動就要靠自己寫的程式來完成了!

本文參考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 =newQDeclarativeView;      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:

importQt4.7

Item{
Rectangle{
color:"blue"
x:50;y:50;width:100;height:100
MouseArea{
id:mouseRegion
anchors.fill:parent;
propertyvariantclickPos:"1,1"
onPressed:{
clickPos=Qt.point(mouse.x,mouse.y)
}
onPositionChanged:{
vardelta=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中()提到的將一個view物件先註冊到(或者稱暴露給)qml,然後再qml中識別滑鼠的拖拽位移,並將位移傳遞給物件的某個方法。

實現如下:

1、cpp中宣告與實現:

voidmmove(intx,inty);

voidMyDeclarativeView::mmove(intx,inty)

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

2、qml中呼叫:(結合上一篇blog中提到的更改滑鼠cursor圖案)

Rectangle{
id:topTitleContainer
MouseArea{
anchors.fill:parent
propertyvariantclickPos:"1,1"
onPressed:{
clickPos=Qt.point(mouse.x,mouse.y)
WindowControl.msetcursor(topTitleContainer,"SizeAllCursor")
}
onPositionChanged:{
vardelta=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個單位。