-1

I'm new in a rather large QML codebase and I want to know the properties of the QML element I click on when running the application, e.g. objectName.

E.g. the name "button" in this main.qml.

The equivalent in Qt is QApplication::widgetAt() or QWidget::childAt() I can call in a QMouseEvent.

I need these to identify QML objects within a mixed Qt/QML application for cucumber-cpp step implementations, where I already have a Helper::click(QString name). I put up an example project here: https://github.com/elsamuko/qml_demo

elsamuko
  • 668
  • 6
  • 16
  • Please provide a minimal example demonstrating the framework in which you'd like an answer – Amfasis Jan 28 '21 at 11:01
  • Visible QML items have a childAt() method and Button inherits Item, so you should be able to call it – Jack Lilhammers Feb 07 '21 at 03:14
  • The QML Item's function `childAt` is indeed equivalent to `QWidget::childAt`. But if you have overlapping objects, the docs say it will just return the first child it finds, which might not be the one you're interested in. I'm really questioning why you want this functionality. This feels like it might be an [XY Problem](https://xyproblem.info/) to me. – JarMan Feb 07 '21 at 22:19
  • @JarMan I updated the description. I need it to identify QML objects for UI testing in a mixed Qt/QML application. – elsamuko Feb 09 '21 at 18:18
  • Well, does the QML `childAt` function do what you want? – JarMan Feb 09 '21 at 18:30
  • I added a [custom class ClickView](https://github.com/elsamuko/qml_demo/blob/main/clickview.cpp#L16) to dump QQuickItem* where the user clicks, but neither the `childAt`, nor all other children are `Button` objects. – elsamuko Feb 09 '21 at 19:03

2 Answers2

0

I have a solution, I can work with.
First I implement mousePressEvent from QQuickView in a derived class.
Then with findChildren<QObject*> on the QQuickView object, I can find and debug the QML objects. Strangely, childAt and children do not list the QML child objects.

void ClickView::mousePressEvent( QMouseEvent* ev ) {

    QObjectList children = this->findChildren<QObject*>( QRegularExpression( ".+" ) );

    for( QObject* child : children ) {

        // only search for QML types
        if( !strstr( child->metaObject()->className(), "_QMLTYPE_" ) ) { continue; }

        QVariant vX = child->property( "x" );
        QVariant vY = child->property( "y" );
        QVariant vW = child->property( "width" );
        QVariant vH = child->property( "height" );

        if( vX.isValid() && vY.isValid() && vW.isValid() && vH.isValid() ) {
            QRect rect( vX.toInt(), vY.toInt(), vW.toInt(), vH.toInt() );

            if( rect.contains( ev->pos() ) ) {
                qDebug() << child;
            }
        }
    }

    QQuickView::mousePressEvent( ev );
}

The complete project is here:
https://github.com/elsamuko/qml_demo

elsamuko
  • 668
  • 6
  • 16
  • Qt not allowing one to easily access elements on the page based on their `id` or `name` is a joke – Bersan Apr 27 '22 at 12:33
-1

try this, it should work

Rectangle {
    id: item
    signal qmlSignal(msg: string)
    objectName: "rectangle"

    MouseArea {
        anchors.fill: parent
        onClicked: item.qmlSignal("rectangle clicked")
        onDoubleClicked: item.qmlSignal("rectangle double clicked")
        onEntered: item.qmlSignal("mouse entered the rectangle")
        onExited: item.qmlSignal("mouse left the rectangle")
    }
}

if this does not suit you, then you can send a signal from the QML and find out the name in the slot

How to connect a QML signal with a C++ slot?

Vahagn Avagyan
  • 750
  • 4
  • 16
  • That's the other way around, I don't have the name "Button". – elsamuko Feb 05 '21 at 12:33
  • this is the same example from your code `objectName: "button"` – Vahagn Avagyan Feb 05 '21 at 12:39
  • sorry i changed `Button` to `button` – Vahagn Avagyan Feb 05 '21 at 13:01
  • @VahagnAvagyan Your code takes an `objectName` and finds a pointer to the object. I think the OP is looking for a way to find the `objectName`. – JarMan Feb 05 '21 at 14:52
  • This still does not give me information about QML objects I click on. Let's assume, I'm in `QApplication::event()` and receive a `QEvent::MouseButtonPress`. Which QML object is under the mouse position. – elsamuko Feb 06 '21 at 13:10
  • @VahagnAvagyan This still doesn't seem helpful to me, sorry. I updated the description and put up an example here: https://github.com/elsamuko/qml_demo – elsamuko Feb 09 '21 at 18:19