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個單位。