QML: Move a frameless window by dragging



  • 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
    


  • 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:os();
    }
    else if (event->type() == QEvent::MouseMove)
    {
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    
    if(mouseEvent->buttons() == Qt::LeftButton)
    {
    QPoint offset = m_previousPos - QCursor:os();
    m_previousPos = QCursor:os();
    move(pos() - offset);
    }
    }
    
    return false;
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.