Unknown parent in wxDataViewCtrl

55 views
Skip to first unread message

Pedro Bastos das Neves

unread,
Aug 11, 2021, 3:50:29 PM8/11/21
to wx-users
I've already put this question in wxWidgets forum and a moderator told me to put the question here.
I'm trying to make a custom dialog where I use a wxDataViewCtrl with a custom model deriving from wxDataviewModel folowing the dataview sample. I have a button for adding nodes dynamically to the dataview.
In debug mode, when I do ItemAdded( parent, child ) the code returns the message "assert "parent_node" failed in ItemAdded(): Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel".
The dataview starts only with the root node that is added in the model constructor, so it is known to the model. I can't understand why it complains that the parent is unknown to the model.
At the forum they suggested viewing the source code to try to understand the source of the problem, and I've found it on the dataview.cpp file located on src/gtk folder of the wxWidgets source code.
The ItemAdded method before the assert message calls the wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item ) witch in turn calls wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item ). 
The source code for this method is:
static wxGtkTreeModelNode* 
wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item ) 
{
     if( model == NULL ) 
          return NULL; 
     ItemList list; 
     list.DeleteContents( true ); 
     wxDataViewItem it( item ); 

     while( it.IsOk() ) 
     { 
              wxDataViewItem * pItem = new wxDataViewItem( it ); 
              list.Insert( pItem ); 
              it = model->GetParent( it );
      } 

      wxGtkTreeModelNode * node = treeNode; 
      for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() ) 
      { 
             if( node && node->GetNodes().GetCount() != 0 ) 
            { 
                   int len = node->GetNodes().GetCount(); 
                   wxGtkTreeModelNodes &nodes = node->GetNodes(); 
                   int j = 0; 
                   for( ; j < len; j ++) 
                   { 
                            if( nodes[j]->GetItem() == *(n->GetData())) 
                            { 
                                     node = nodes[j]; 
                                     break; 
                            }
                    } 
                    if( j == len ) 
                    { 
                           return NULL; 
                     } 
              } 
              else 
                    return NULL; 
       } 
       return node; 
}

This code construct a list with the node passed as parent do ItemAdded and all his parents to compare with the root node children. But, as far is my understanding, the for loop for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() ) is only executed once and never repeats itself because when j == len in the first iteration the method returns NULL.
Isn't this a bug? I believe that's because of this behavior that I'm receiving the assert message.

Vadim Zeitlin

unread,
Aug 15, 2021, 9:16:34 AM8/15/21
to wx-u...@googlegroups.com
On Wed, 11 Aug 2021 12:49:56 -0700 (PDT) Pedro Bastos das Neves wrote:

PBdN> I'm trying to make a custom dialog where I use a wxDataViewCtrl with
PBdN> a custom model deriving from wxDataviewModel folowing the dataview
PBdN> sample. I have a button for adding nodes dynamically to the dataview.
PBdN> In debug mode, when I do ItemAdded( parent, child ) the code returns the message "assert "parent_node" failed in ItemAdded(): Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel".
PBdN> The dataview starts only with the root node that is added in the
PBdN> model constructor, so it is known to the model. I can't understand
PBdN> why it complains that the parent is unknown to the model.

Have you checked the value of the "parent"? From your explanation it looks
like you expect it to be equal to the root node, but it clearly isn't. And
if it's not the root node, have you called ItemAdded() for the parent
itself first?

PBdN> At the forum they suggested viewing the source code to try to
PBdN> understand the source of the problem,

Yes, this is always a good idea and one of big advantages of using open
source libraries.

PBdN> The source code for this method is:
PBdN> static wxGtkTreeModelNode*
PBdN> wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item )
PBdN> {
PBdN> if( model == NULL )
PBdN> return NULL;
PBdN> ItemList list;
PBdN> list.DeleteContents( true );
PBdN> wxDataViewItem it( item );
PBdN> while( it.IsOk() )
PBdN> {
PBdN> wxDataViewItem * pItem = new wxDataViewItem( it );
PBdN> list.Insert( pItem );
PBdN> it = model->GetParent( it );
PBdN> }
PBdN> wxGtkTreeModelNode * node = treeNode;
PBdN> for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() )
PBdN> {
PBdN> if( node && node->GetNodes().GetCount() != 0 )
PBdN> {
PBdN> int len = node->GetNodes().GetCount();
PBdN> wxGtkTreeModelNodes &nodes = node->GetNodes();
PBdN> int j = 0;
PBdN> for( ; j < len; j ++)
PBdN> {
PBdN> if( nodes[j]->GetItem() == *(n->GetData()))
PBdN> {
PBdN> node = nodes[j];
PBdN> break;
PBdN> }
PBdN> }
PBdN> if( j == len )
PBdN> {
PBdN> return NULL;
PBdN> }
PBdN> }
PBdN> else
PBdN> return NULL;
PBdN> }
PBdN> return node;
PBdN> }
PBdN> This code construct a list with the node passed as parent do
PBdN> ItemAdded and all his parents to compare with the root node children.
PBdN> But, as far is my understanding, the for loop for(
PBdN> ItemList::compatibility_iterator n = list.GetFirst(); n; n =
PBdN> n->GetNext() ) is only executed once and never repeats itself because
PBdN> when j == len in the first iteration the method returns NULL.

It only does this if it doesn't find the parent at this level. For the
search to succeed, it must find all elements of the path to the item.

PBdN> Isn't this a bug? I believe that's because of this behavior that I'm
PBdN> receiving the assert message.

No, or at least I don't see any bug here. If you still think there is a
problem in wxGTK itself, please try reproducing it in the dataview sample
with the minimal modifications and post a patch showing the problem.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

YuSanka

unread,
Aug 16, 2021, 2:41:00 AM8/16/21
to wx-u...@googlegroups.com
Hello, 
I believe that you should override the IsContaner() function for your model class. IsContainer() should return true for Parent Item Under GTK.
We had the same problem in PrusaSlicer ;)
Best regards,
Oleksandra Iushchenko

ср, 11 авг. 2021 г. в 21:50, Pedro Bastos das Neves <bastosd...@gmail.com>:
--
Please read https://www.wxwidgets.org/support/mlhowto.htm before posting.
---
You received this message because you are subscribed to the Google Groups "wx-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wx-users+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wx-users/3fc27288-4da7-4686-ae00-313e2fd5cdbdn%40googlegroups.com.

Pedro Bastos das Neves

unread,
Aug 17, 2021, 11:12:09 AM8/17/21
to wx-users
Thank you all for your answers.
The problem occurs after click a button to add a child and the selected item is not a container node. If I click on add button and have selected an container node all works fine.
I can change the selected item to be a container, the method IsContainer() returns true, but the ItemChanged  is not sufficient to inform the model that the selected item is now a container because when I run the method ItemAdded passing the selected item as parent the error message appears.
If I run ItemAdded() where the parent parameter is the parent of the selected item and item as the selected item the selected item is added to the dataview one more time.
What I have to do that I'm missing? The dataview sample only add a node to a container node and have no example of transforming a non container node to a container node.

Vadim Zeitlin

unread,
Aug 17, 2021, 6:16:43 PM8/17/21
to wx-u...@googlegroups.com
On Tue, 17 Aug 2021 08:12:09 -0700 (PDT) Pedro Bastos das Neves wrote:

PBdN> The problem occurs after click a button to add a child and the selected
PBdN> item is not a container node. If I click on add button and have selected an
PBdN> container node all works fine.
PBdN> I can change the selected item to be a container, the method IsContainer()
PBdN> returns true, but the ItemChanged is not sufficient to inform the model
PBdN> that the selected item is now a container because when I run the method
PBdN> ItemAdded passing the selected item as parent the error message appears.
PBdN> If I run ItemAdded() where the parent parameter is the parent of the
PBdN> selected item and item as the selected item the selected item is added to
PBdN> the dataview one more time.
PBdN> What I have to do that I'm missing? The dataview sample only add a node to
PBdN> a container node and have no example of transforming a non container node
PBdN> to a container node.

I am not sure if the native GTK control supports this, but it should
always be possible to recreate this node, shouldn't it?

Pedro Bastos das Neves

unread,
Aug 18, 2021, 5:24:35 PM8/18/21
to wx-users
VZ> I am not sure if the native GTK control supports this, but it should
VZ> always be possible to recreate this node, shouldn't it?

In a lack of a better solution, that's the road I need to follow...
But I think that this is a feature that the model should have, or I'm seeing it wrong?

Vadim Zeitlin

unread,
Aug 19, 2021, 8:41:20 AM8/19/21
to wx-u...@googlegroups.com
On Wed, 18 Aug 2021 14:24:35 -0700 (PDT) Pedro Bastos das Neves wrote:

PBdN> VZ> I am not sure if the native GTK control supports this, but it should
PBdN> VZ> always be possible to recreate this node, shouldn't it?
PBdN>
PBdN> In a lack of a better solution, that's the road I need to follow...
PBdN> But I think that this is a feature that the model should have, or I'm
PBdN> seeing it wrong?

If GTK really doesn't support this, there is not much we can do. Of
course, it's also possible that it does support it, but we just don't know
how to do it, in which case it should be possible to implement support for
this, but somebody would need to look into it and, especially as long as
there is a not too horrible workaround available, this doesn't seem to be
very high priority to me, so I don't plan to do it myself. But any
contributions would be welcome, as always, of course.
Reply all
Reply to author
Forward
0 new messages