PDA

View Full Version : QML: Move a frameless window by dragging



ddonate
21st November 2016, 11:44
I have a frameless QQuickWindow, and I want to move it with the mouse by dragging. Before trying in my big application, I have created a simple test application to try what I found here, using cursor position from C++ class to avoid problems from QML:
http://www.tickanswer.com/solved/5390888353/dragging-frameless-window-jiggles-in-qml

But I failed with the code below. When I press over the red RECT and move the mouse, my yellow rect (root RECT) moves, but only inside the original size it had (in this case, 500x500)... What am I doing wrong?

Thanks in advance


In my main.cpp:


int main(int argc, char *argv[])
{
QtQuickControlsApplication a(argc, argv);

QQuickView* pView = new QQuickView();

CursorPosProvider mousePosProvider;
pView->rootContext()->setContextProperty("mousePosition", &mousePosProvider);
pView->setSource(QUrl("qrc:/Test.qml"));
pView->setFlags(Qt::FramelessWindowHint);
pView->show();

return a.exec();
}

Test.qml:


import QtQuick 2.0

Rectangle {
id: myWindow
width: 500; height: 500
color: "yellow"

Rectangle {
anchors.centerIn: parent
width: 200; height: 200

color: "red"

MouseArea {
id: titleBarMouseRegion
property var clickPos
anchors.fill: parent

onPressed: clickPos = { x: mousePosition.cursorPos().x, y: mousePosition.cursorPos().y }

onPositionChanged: {
myWindow.x = mousePosition.cursorPos().x - clickPos.x
myWindow.y = mousePosition.cursorPos().y - clickPos.y
}
}
}
}

cursorprovider.h:


#ifndef CURSORPOSPROVIDER_H
#define CURSORPOSPROVIDER_H

#include <QObject>
#include <QPointF>
#include <QCursor>

class CursorPosProvider : public QObject
{
Q_OBJECT
public:
explicit CursorPosProvider(QObject *parent = nullptr) : QObject(parent)
{
}
virtual ~CursorPosProvider() = default;

Q_INVOKABLE QPointF cursorPos()
{
return QCursor::pos();
}
};

#endif // CURSORPOSPROVIDER_H

anda_skoa
21st November 2016, 14:50
You are moving content, not the window.

I.e. "myWindow" is the root content item of your QQuickView, but that view is the window.

You also need to expose the view object to QML and set its x/y properties.

Cheers,
_

ddonate
22nd November 2016, 10:52
I have changed the structure, I have used a QQuickWidget with a QML inside, and now I have what I wanted. Here is my code in case anyone needs something similar


main.cpp

...
MovableWidget *view = new MovableWidget;
view->setSource(QUrl("qrc:/Test.qml"));
view->setWindowFlags(Qt::FramelessWindowHint);
view->show();
...

Test.qml

import QtQuick 2.0

Rectangle {
id: myWindow
width: 500; height: 500
color: "yellow"

Rectangle {
anchors.centerIn: parent
width: 200; height: 200

color: "red"
}
}



MovableWidget.cpp

#include "movableWidget.h"

#include <QMouseEvent>

// ************************************************** **************************
MovableWidget::MovableWidget(QWidget *parent)
: QQuickWidget(parent),
m_previousPos(0,0)
{
installEventFilter(this);
}

// ************************************************** **************************
bool MovableWidget::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
m_previousPos = QCursor::pos();
}
else if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);

if(mouseEvent->buttons() == Qt::LeftButton)
{
QPoint offset = m_previousPos - QCursor::pos();
m_previousPos = QCursor::pos();
move(pos() - offset);
}
}

return false;
}

anda_skoa
22nd November 2016, 12:52
Obviously that had nothing to do with using a QQuickWidget instead of a QQuickView.

Just in case anyone is reading this and wondering.

Cheers,
_

ddonate
22nd November 2016, 15:08
Thanks anda_skoa,

I tried with QQuickView but I didn't get a good solution... So I decided to change and this works for me...

Cheers

anda_skoa
22nd November 2016, 20:50
I tried with QQuickView but I didn't get a good solution... So I decided to change and this works for me...

Not sure I understand, tatt would be exactly the same code, wouldn't it?

Cheers,
_

ddonate
24th November 2016, 09:24
Not sure I understand, tatt would be exactly the same code, wouldn't it?

Cheers,
_

You are right, I tried again the first option, with QQuickView, and it also works properly... I don't know what I was doing wrong in the previous try...

Thanks a lot!