go-qml / qml

QML support for the Go language
Other
1.96k stars 189 forks source link

Type-independent analogue for qml.ObjectByName #60

Closed xlab closed 9 years ago

xlab commented 10 years ago

Hi! There is a little issue with the qml.ObjectByName method. Actually it works only with standard QML-objects and fails for exported Go types.

<example story>

import MyTypes 1.0
Item {
    id: root
    MyType {
        objectName: "control"
    }
}

I cannot just write win.Root().ChildByName("control").(*Ctrl), which is idiomatic in Qt, but need to write an additional property alias:

import MyTypes 1.0
Item {
    id: root
    property alias control: control
    MyType {
        id: control
        objectName: "control"
    }
}

and then retrieve my go-object with win.Root().Property("control").(*Ctrl), that's a bit clumsy (imho).

</example story>

The problem arises from the qml.ObjectByName implementation:

object, ok := unpackDataValue(&dvalue, obj.engine).(Object)
if !ok {
    panic(fmt.Sprintf("cannot find descendant with objectName == %q", objectName))
}

and of course my custom type is not qml.Object (even with embedding of *qml.Common on the Go-side).

So I've made a general method that finds objects and treats them as interface{}. Please consider the pull request as a reference. The question is — which is the more idiomatic way to retrieve created go-objects from the qml-context, and do we need that kind of method (which treats found objects as interface{}s) in the future and what is your personal opinion for that? Thanks!

niemeyer commented 9 years ago

I don't think I understand the problem. The qml.Object interface should be implemented by all qml objects, including your MyType. Why is ObjectByName not working? Do you have a small reproducer example I could run?

The code would also need such a test case exercising that specific edge, that fails with the current ObjectByName.

xlab commented 9 years ago

The qml.Object interface should be implemented by all qml objects, including your MyType

Oh, I see. However, my type is a simple Go type like

type MyType struct {
    Text string
}

That was registered inside a qml context via

qml.RegisterTypes("MyTypes", 1, 0, []qml.TypeSpec{
    {Init: func(v *MyType, obj qml.Object) {}},
})

That's the point of my report — we could search for true QML objects using the ObjectByName method, but can't get an exported plain Go object that way.

See an example here: https://github.com/xlab-private/qml-search-objects

xlab commented 9 years ago

And the proposed method just searches for every child with the given objectName, not taking into account its type.

niemeyer commented 9 years ago

Thanks, I see the issue now. The proper way to handle this is to return the real qml.Object that represents the Go value in QML space. That's an easy fix.

I've opened issue #91 to track it.