Search code examples
qtqmlcoordinatesqtquick2qtquickcontrols

Get Screen-Coordinates of a QuickControl


I have to set x,y coordinates of a QWindow. This QWindow has to get the screen coordinates of a QuickControl in my MainWindow + myValue.

How do I get the global Screen-Coordinates for a QuickControl in QML?


Solution

  • As @BaCaRoZzo mentioned, use the mapToItem()/mapFromItem() functions:

    import QtQuick 2.0
    import QtQuick.Window 2.0
    import QtQuick.Controls 1.0
    
    Window {
        id: window
        width: 400
        height: 400
        visible: true
    
        Button {
            id: button
            text: "Button"
            x: 100
            y: 100
    
            readonly property point windowPos: button.mapToItem(null, 0, 0)
            readonly property point globalPos: Qt.point(windowPos.x + window.x, windowPos.y + window.y)
        }
    
        Column {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
    
            Text {
                text: "Button position relative to window: x=" + button.windowPos.x + " y=" + button.windowPos.y
            }
    
            Text {
                text: "Button position relative to screen: x=" + button.globalPos.x + " y=" + button.globalPos.y
            }
        }
    }
    

    As mentioned in the documentation for mapToItem():

    Maps the point (x, y) or rect (x, y, width, height), which is in this item's coordinate system, to item's coordinate system, and returns a point or rect matching the mapped coordinate.

    If item is a null value, this maps the point or rect to the coordinate system of the root QML view.

    That gives us windowPos. To get the position of the control relative to the screen itself, we just add the x and y position of the window.


    After a chat with OP, it's clear that he wants to do this in C++. The same principles apply, and in C++ we have more convenient access to the window:

    class Control : public QQuickItem
    {
        Q_OBJECT
    public:
        Control() {}
        ~Control() {}
    
    public slots:
        void printGlobalPos() {
            qDebug() << mapToItem(Q_NULLPTR, QPointF(0, 0)) + window()->position();
        }
    };
    

    Register the type:

    qmlRegisterType<Control>("Types", 1, 0, "Control");
    

    Use it in QML:

    import QtQuick 2.0
    import QtQuick.Window 2.0
    
    import Types 1.0
    
    Window {
        id: window
        width: 400
        height: 400
        visible: true
    
        Control {
            id: button
            x: 100
            y: 100
            width: 100
            height: 40
    
            MouseArea {
                anchors.fill: parent
                onClicked: button.printGlobalPos()
            }
    
            Rectangle {
                anchors.fill: parent
                color: "transparent"
                border.color: "darkorange"
            }
        }
    }