1
votes

The problem is that the coordinates of the window are not set correctly. Therefore, the window is moved incorrectly and errors appear:

QWindowsWindow::setGeometry: Unable to set geometry 400x400+62998+32284 on QQuickApplicationWindow_QML_0/''...

I don't know how to fix this. Here's the code:

main.qml

import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3

ApplicationWindow {
    id: window
    visible: true
    width: 400
    height: 400
    title: qsTr('Frameless')
    flags: Qt.Window | Qt.FramelessWindowHint

    Rectangle {
        width: parent.width
        height: 40
        color: "gold"

        anchors.top: parent.top

        Text {
            anchors.verticalCenter: parent.verticalCenter
            leftPadding: 8
            text: window.title
            color: "white"
        }

        MouseArea {
          anchors.fill: parent

          property real lastMouseX: 0
          property real lastMouseY: 0

          onPressed: {
             lastMouseX = mouse.x
             lastMouseY = mouse.y
          }
          onMouseXChanged: window.x += (mouse.x - lastMouseX)
          onMouseYChanged: window.y += (mouse.y- lastMouseY)
        }
    }
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>


int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}
1
You should read the documentation more carefully. The parameter of MouseArea.MouseArea is mouse. There is no mouseX or mouseY and so you store some random values. Also note that mouse.x is real and so you lose precision while storing it in int. Another recommendation is to use debugger, it allows to solve such problems in moment. - folibis
I fixed my code a bit, but still, the effect remained. Maybe you know a working solution? I can't figure it out. - Michael Shcherbakov
There is no item with id mainWindow, the ApplicationWindow.visible is false by default, you have to set it to true explicitly. It looks like you provide a code different from one you test and there are some other factors that affect the window position. With fixed code that works for me well. - folibis
I have two files in my project: main.cpp and main.qml. I added them. And still doesn't work for me. - Michael Shcherbakov
window.x += (mouse.x - lastMouseX) this is always incremental and will grow indefinitely. - bardao

1 Answers

1
votes

Even if you manage to solve this using QML you will see that the window will move with a LOT of jitter. It's mainly because of how bindings work (asynchronously). A better approach is asking C++ for QCursor::pos()

Here's a brief way on how to do that:

In your main.qml create a MouseArea:

MouseArea {
    property var clickPos
    anchors.fill: parent
    onPressed: {
        clickPos = { x: mouse.x, y: mouse.y }
    }
    onPositionChanged: {
        window.x = cpp_helper_class.cursorPos().x - clickPos.x
        window.y = cpp_helper_class.cursorPos().y - clickPos.y
    }
}

In your c++ cpp_helper_class you should have the following method:

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

The Q_INVOKALBE makes sure your C++ code is accessible from QML.

Also your main.cpp should contain the following:

context->setContextProperty("cpp_helper_class", &helper_class_instance);