之前的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个单位。