0

I have the following QML Rectangle which has a parent item. The most important thing to note is that it applies a Translate QML element which I am struggling to understand as to what exactly it does the QML item and its children it applies to.

Code:

Window {
    id: main_window
    width: 640
    height: 480
    visible: true

    Item {
        id: rect_parent
        objectName: "rect_parent_object"
        x: 0
        y: 0
        width: parent.width
        height: parent.height
        transform: Translate {x: -20; y: -30}

        Rectangle {
            id: rect
            objectName: "rect_object"
            x: parent.width/2
            y: parent.height/2
            width: parent.width/3
            height: parent.height/3
            color: "red"
        }
    }
}

rect_parent has a property transform: Translate as you see in above code. Following is the X Y translation that is applied to it

transform: Translate {x: -20; y: -20}

In C++ part of my code in main.cpp I am getting the QQuickItems in the following way.

QQuickItem *rectQuickItem = qml_engine->rootObjects()[0]->findChild<QQuickItem*>("rectObject");
QQuickItem *rectQuickItemParent = qml_engine->rootObjects()[0]->findChild<QQuickItem*>("rectParentObject");

Yes, I can get the x and y of rectQuickItem in the following way.

QQuickItem *rectQuickItemParent = qml_engine->rootObjects()[0]->findChild<QQuickItem*>("rectParentObject");
qreal item_x = rectQuickItem->x();
qreal item_y = rectQuickItem->y();

Question:
But how do I get rectQuickItem's translated x and y?
I found that item_x and item_y are not the x and y that are actually applied on the UI. It seems that transform: Translate is adding some units to both x and y of rect which I dont get when I query rectQuickItem->x().

In simpler words, I need the -20 and -30 applied on x and y in transform: Translate block of rect_parent which eventually applies to rect

Objective:
I am changing the parent of rectQuickItem to display it on another window with the same respective x and y location as original parent. I need the units that got added to x and y of properties of rectQuickItem due to transform: Translate being set so as to display rect on visually the same location as previous parent.

Additional question:
Would QQuickItem::MapToItem help me in any way here?

TheWaterProgrammer
  • 7,055
  • 12
  • 70
  • 159
  • relative to which Item does he need to obtain the coordinates of rect_object? relative to the window, relative to the screen, relative to the parent item? – eyllanesc Feb 27 '18 at 22:02
  • I need it relative to the parent item that is `rect_parent`. On that note, is there a way I can get the coordinates relative to the window(`main_window`) as well that is ? – TheWaterProgrammer Feb 27 '18 at 22:06
  • `rect_parent` is the direct parent of `rect`. If you see the sample code, you will understand what I mean. I am referring to the QQuickItems by their IDs on QML. – TheWaterProgrammer Feb 27 '18 at 22:09
  • @eyllanesc Did I provide the information that you were looking for? My knowledge is very basic with regards to what the `transform: Translate` block does. hence my question might be bit off as well :-) – TheWaterProgrammer Feb 27 '18 at 22:18
  • 1
    If you reach from C++ into QML you are already in the land of bad software design practices. – dtech Feb 28 '18 at 00:58
  • @dtech I am doing a quite complex thing where a some `QQuickItem`s showing on screen need to be rendered "off screen" visually with the same coordinates as on screen. The way I am doing it now is that I create a base `QQuickItem` on C++ side which has the same dimensions as the on-screen window. Then I pick the `QQuickItem`s from on screen which are required to be rendered off screen and set their parent as off screen window then call update on the off screen window. This certainly requires C++ handling.. Hence need to deal with QML items on C++ side. – TheWaterProgrammer Feb 28 '18 at 15:01
  • You can make that into an interface that QML connects to and thus avoid reaching into QML from C++. That's the right way. Having to rely on finding objects by object name... that's not really an approach that should be used in production code. – dtech Feb 28 '18 at 15:04
  • @dtech I am interested in doing to that improvement to my code. is there a concrete example which shows how to get a `QQuickItem` pointer to a QML item without dealing with it object name necessarily. I think I should raise a separate question on this for everyones benefit – TheWaterProgrammer Feb 28 '18 at 16:31
  • The idea was that you have to facilitate the functionality on the C++ side completely independently of any GUI. No touching of qml objects whatsoever. But since it is all GUI related, the big question is why do you even need C++ in the first place? It sounds like something that can and should be done entirely in qml. – dtech Feb 28 '18 at 16:34

1 Answers1

1

If you want to obtain the coordinates of an item with respect to another item, the procedure is:

  • convert the position of the item to a position relative to the scene
  • convert the position with respect to the scene to the position with respect to the other item.

static QPointF positionToAnotherItem(QQuickItem *source, QQuickItem *destine){
    QPointF p = source->mapToScene(QPointF(0, 0));
    return destine->mapFromScene(p);
}

static QPointF positionToParent(QQuickItem *item){
    return positionToAnotherItem(item, item->parentItem());
}

the transformations do not apply immediately so by applying the above procedure you will not get the right positions, you must apply them with the help of the xChanged and YChanged signals.

QQuickItem *rectQuickItem = qml_engine.rootObjects()[0]->findChild<QQuickItem*>("rect_object");
//QQuickItem *rectQuickItemParent = qml_engine.rootObjects()[0]->findChild<QQuickItem*>("rect_parent_object");

QObject::connect(rectQuickItem, &QQuickItem::xChanged, [rectQuickItem]{
    qDebug()<<positionToParent(rectQuickItem);
});

QObject::connect(rectQuickItem, &QQuickItem::yChanged, [rectQuickItem]{
    qDebug()<<positionToParent(rectQuickItem);
});

In the following link there is a complete example

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Just for you to know, I am doing a `rectQuickItem->setParentItem(new_parent_window)` when I drawing it on the new window/QQuickItem. But irrespective of that your answer, explains a way to get a QPointF from one parent and map to another parent. Looks like this is what I need to do – TheWaterProgrammer Feb 27 '18 at 23:05
  • Let me properly understand and try this out. – TheWaterProgrammer Feb 27 '18 at 23:06