Dynamically replacing listview models

1,511 views
Skip to first unread message

Zev Goldstein

unread,
Mar 27, 2014, 1:26:29 AM3/27/14
to go-...@googlegroups.com
I'd like to be able to switch the model driving a listview after the listview has been created.  I ran into some issues, so I started playing with your delegate example. This was my first attempt.  I added a modelcontainer that holds a slice of models and a reference to the current active model.  After a few seconds, i create a second model and try to replace the first model.  Unfortunately, when I do that, the list view stops updating until I swap back to the original model.  I thought I might just need to trigger a qml update, but adding qml.Changed(container, &container.CurrentModel) after the swap causes a panic with the message "provided field is not a member of the given value".  I tried again without the deference and still got the same panic.  I'm generally confused by that panic message.  container.CurrentModel most certainly looks like a member of container from where I'm sitting.

I was able to get the behavior I was looking for in a 2nd revision that involves a lot of ugly object copying.  That version is here, but I'm not a big fan of this approach.  Not only is it less readable, but it involves the active model getting temporarily out of sync with its corresponding record in the model list.

Should I go forward and apply this object copying logic to my actual app, or is there a better way to go about this?

Gustavo Niemeyer

unread,
Mar 27, 2014, 2:12:17 AM3/27/14
to Zev Goldstein, Go QML
Hi Zev,

On Thu, Mar 27, 2014 at 2:26 AM, Zev Goldstein <zev.go...@gmail.com> wrote:
> need to trigger a qml update, but adding qml.Changed(container,
> &container.CurrentModel) after the swap causes a panic with the message
> "provided field is not a member of the given value". I tried again without
> the deference and still got the same panic. I'm generally confused by that
> panic message. container.CurrentModel most certainly looks like a member of
> container from where I'm sitting.

Can you provide a small example that shows this problem? I'd be happy
to look at it.


gustavo @ http://niemeyer.net

Zev Goldstein

unread,
Mar 27, 2014, 2:56:55 AM3/27/14
to Gustavo Niemeyer, Go QML
Here's the version that crashes.  It's nearly identical to my first attempt from the previous post.  I just added the qml.Changed() calls.  

It looks like it happens any time you pass a pointer member to qml.Changed.  I was able to recreate the same panic with a much simpler change to your example: https://github.com/psywolf/qml/commit/b6405b7aac4defe44e7d634c1a393d7086538fa7

-Zev

Gustavo Niemeyer

unread,
Mar 27, 2014, 9:54:18 AM3/27/14
to Zev Goldstein, Go QML
There was a bug in qml.Changed indeed, when working with pointer
fields. This has been tested and fixed:

https://github.com/go-qml/qml/commit/91d0a938

Thanks for the report.
--

gustavo @ http://niemeyer.net

David Marceau

unread,
Mar 29, 2014, 5:29:47 PM3/29/14
to go-...@googlegroups.com
http://blog.labix.org/2014/03/21/arbitrary-qt-extensions-with-go-qml

You did a register for Token to convertToken.
Where did the convertToken get called? There was no mention about where
convertToken is called anywhere in the article.

Thanks in advance,
David Marceau

Zev Goldstein

unread,
Mar 30, 2014, 12:57:28 AM3/30/14
to go-...@googlegroups.com, Zev Goldstein
That did the trick.  Thanks for the quick turn around!

Gustavo Niemeyer

unread,
Mar 30, 2014, 5:28:33 PM3/30/14
to David Marceau, Go QML
It is mentioned in the article:

"""
There's one more point worth observing in this logic: the token value
received as a parameter in credentialsFound was already converted into
the local Token type. In most cases, this is unnecessary as the
parameter is directly useful as a qml.Object or as another native type
(int, etc), but in this case UbuntuOne::Token is a plain C++ type that
does not inherit from QObject, so the default signal parameter that
would arrive in the Go method has only a type name and the value
address.

Instead of taking the plain value, it is turned into a more useful one
by registering a converter with the qml package:
"""

So it gets called internally when a "Token" type is going from QML
into Go land, and this is used in the article when the
credentialsFound signal is emitted and caught from Go.

Does that make sense?
> --
> You received this message because you are subscribed to the Google Groups "go-qml" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to go-qml+un...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

David Marceau

unread,
Mar 30, 2014, 9:07:02 PM3/30/14
to go-...@googlegroups.com

On 03/30/2014 05:28 PM, Gustavo Niemeyer wrote:
> It is mentioned in the article:
>
> """
> There's one more point worth observing in this logic: the token value
> received as a parameter in credentialsFound was already converted into
> the local Token type. In most cases, this is unnecessary as the
> parameter is directly useful as a qml.Object or as another native type
> (int, etc), but in this case UbuntuOne::Token is a plain C++ type that
> does not inherit from QObject, so the default signal parameter that
> would arrive in the Go method has only a type name and the value
> address.
>
> Instead of taking the plain value, it is turned into a more useful one
> by registering a converter with the qml package:
> """
>
> So it gets called internally when a "Token" type is going from QML
> into Go land, and this is used in the article when the
> credentialsFound signal is emitted and caught from Go.
>
> Does that make sense?
Understood, convertToken gets automagically called
and your explanation clarifies that it is go-qml magic(qt signal with
go-qml callback) rather than go magic(something implicit between c++ and
golang within the golang build/runtime environment). I will have to
examine the go-qml sources more closely.

Thanks.

Cheers,
David
Reply all
Reply to author
Forward
0 new messages