go-qml / qml

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

Handling of slice of struct declared in main package #160

Open cjslep opened 9 years ago

cjslep commented 9 years ago

I was trying my hand at creating a dynamically-populated table from data in go, when I got a please report to the developers error:

panic: handling of []main.ColumnHeader (&[]main.ColumnHeader{main.ColumnHeader{Text:"Test text header", Role:"sign", Kind:3}, main.ColumnHeader{Text:"Bool Header", Role:"isok", Kind:0}, main.ColumnHeader{Text:"Integer", Role:"num", Kind:1}}) is incomplete; please report to the developers

I am basically trying to access the following struct definitions with test data:

type TableData struct {
    Cols    int
    Rows    int
    Headers []ColumnHeader
    Data    [][]CellData
}

type ColumnHeader struct {
    Text string
    Role string
    Kind int
}

type CellData struct {
    Role        string
    Editable    bool
    ValueBool   bool
    ValueInt    int
    ValueString string
}

The registration on the go side to make it accessible:

func main() {
    // ...
    engine := qml.NewEngine()
    context := engine.Context()
    // Define the value to share to QML
    tableModel := TableData {
        // Lots of handrolled test data
    }
    context.SetVar("tableData", &tableModel)
    // ...
}

The basic QML:

TableView {
    id: root
    Component.onCompleted: {
        function refresh() {
            // ...
            for (var i = 0; i < adminModel.cols; i++) {
                root.addColumn(columnPrototype.createObject(root, {"title": tableModel.headers[i].text, "role": tableModel.headers[i].role, "goType": tableModel.headers[i].kind}))
            }
            // ...
        }
    }
    Component {
        id: columnPrototype
        TableViewColumn {
            width: 125
        }
    }
}

I looked into other API calls to see if I was doing something incorrect. Nothing seemed obvious to me. The only thing slightly relevant could be registering the ColumnHeader go type, but I am not instantiating new copies of that struct on the qml side. I have another data type (lets call it AppSettings) that is SetVard similarly but does not have any interactions with TableViews. AppSettings also contains a slice of structs from a different package that is nothing but a struct of primitives, and it seems to do fine, so I am slightly baffled.

hkparker commented 8 years ago

+1. I've been unable to hand over anything but basic structs containing strings, ints/floats, and bools and no nesting, slices, maps, or arrays. Everything else I've tried in go-qml has worked great though, I feel this would add a lot of functionality. It might currently be possible to publish some json string to QML and unmarshal them there but that seems silly.

cjslep commented 8 years ago

The current workaround is to add go functions that do array accessing or manipulation or storing. These functions can be called from qml and enable slice manipulation via these function calls. It is more verbose than native support, but it works.

On Oct 7, 2015, at 12:44, Hayden Parker notifications@github.com wrote:

+1. I've been unable to hand over anything but basic structs containing strings, ints/floats, and bools and no nesting, slices, maps, or arrays. Everything else I've tried in go-qml has worked great though, I feel this would add a lot of functionality. It might currently be possible to publish some json string to QML and unmarshal them there but that seems silly.

— Reply to this email directly or view it on GitHub.

hkparker commented 8 years ago

What if I wanted to display a list of some struct in QML, would returning a slice from an accessible function work?