Results 1 to 7 of 7

Thread: QStandardItem::appendRow() segfaults

  1. #1
    Join Date
    Aug 2013
    Posts
    32
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QStandardItem::appendRow() segfaults

    I've been traking this for hours. It must be something simple, it always is. But right now I can't see it.

    I am following the http://qt-project.org/doc/qt-4.8/modelview.html]Model/View tutorial and QStandardItemModel class reference, but can't get this to work.

    I have a QStandardItemModel derivative class, in the constructor I initialize the model and a root node:

    Qt Code:
    1. FtpFileSystemModel::FtpFileSystemModel(QObject *parent) :
    2. {
    3. ftp = new QFtp;
    4. remote_file_list = new QList<QStandardItem*>;
    5. root_item = invisibleRootItem();
    6. root_item->setData("/");
    7. ......
    To copy to clipboard, switch view to plain text mode 

    But when I try to append a row it segfaults.

    Qt Code:
    1. void FtpFileSystemModel::slot_list_info(QUrlInfo url_info)
    2. {
    3. QStandardItem *item = new QStandardItem(url_info.name());
    4. root_item->appendRow(item); // <<<<------HERE IT SEGFAULTS!!!!!!
    5.  
    6. for(int i = 0; i < remote_file_list->count(); i++)
    7. qDebug() << Q_FUNC_INFO << QString("row %1, data()='%2'").arg(item->index().row()).arg(item->data().toString());
    8. }
    To copy to clipboard, switch view to plain text mode 

    This slot is called when a QFtp member runs list(), and it's purpose is to fill the model with info from the files in the ftp repo.

    According to the debug info, there are two rows, I guess one is created by invisibleRootItem() and the other by my setData("/") sentence.

    I am sure this is probably due to the fact that I don't completely understand how this model works. But I guess that's for another thread. I would be grateful if anyone can give me a hint on what could be causing this.

    Thanks beforehand.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,067
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QStandardItem::appendRow() segfaults

    Where is "root_item" defined? Is it a member variable of the class, or is it a local variable defined in the constructor code you haven't shown us? If you've mistakenly defined it in both places, then the one in the constructor hides the member variable, so the assignment to invisibleRootItem() will be lost as soon as the constructor exits.

  3. #3
    Join Date
    Aug 2013
    Posts
    32
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QStandardItem::appendRow() segfaults

    Thanks for the response.

    The item is initialized using this line in the constructor, as shown in my first post.

    Qt Code:
    1. root_item = invisibleRootItem();
    To copy to clipboard, switch view to plain text mode 

    At least that's what I think, since invisibleRootItem() seems to return a QStandardItem pointer. In any case, if the problem was that root_item is not initialized, the program would crash much earlier, at the next line, when I use setData() on it.

    In any case, I am revising all of this. I managed to get this "someshow" working yesterday, very late (which is why I didn't write back here). But now I get a hierarchy that's different of what I thought it would be.

    This models is aimed at representing a remote fs (via [q]ftp) in the fashion of QFileSystemModel for local fs's. But instead of getting something like

    Qt Code:
    1. filename size permissions
    2. filename size permissions
    3. filename size permissions
    4. filename size permissions
    To copy to clipboard, switch view to plain text mode 

    I was getting something more like:

    Qt Code:
    1. filename
    2. - size
    3. - permissions
    4. filename
    5. - size
    6. - permissions
    7. filename
    8. - size
    9. - permissions
    To copy to clipboard, switch view to plain text mode 

    Or something like that. Can't really remember. I really don't get the hang of how trees are handled in Qt.

    Before anyone says it: yes, I know I could use a QWidgetTree along with QWidgetTreeItem(s). But I definitely want to implement this in a model fashion, so that I can implement filtering and reuse the view for the directory tree and for the file listing, just like I do with QFileSystemModel.

    Again, thank you for taking the time to answer.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,067
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QStandardItem::appendRow() segfaults

    The item is initialized using this line in the constructor, as shown in my first post.
    I didn't ask where it is initialized, I asked where it was defined. If you accidentally defined the variable "root_item" as both a local variable in the constructor and as a member variable in your class, then the local definition hides the class definition, so you aren't initializing the class variable as you think.

    The other possibility is that by the time your code gets to the part where you are trying to add the new item, you have managed to corrupt the memory where root_item points so it is now pointing at garbage. If you change your code to this:

    Qt Code:
    1. void FtpFileSystemModel::slot_list_info(QUrlInfo url_info)
    2. {
    3. QStandardItem *item = new QStandardItem(url_info.name());
    4. root_item = invisibleRootItem(); <<<--- new code
    5. root_item->appendRow(item); // <<<<------HERE IT SEGFAULTS!!!!!!
    6.  
    7. for(int i = 0; i < remote_file_list->count(); i++)
    8. qDebug() << Q_FUNC_INFO << QString("row %1, data()='%2'").arg(item->index().row()).arg(item->data().toString());
    9. }
    To copy to clipboard, switch view to plain text mode 

    Does it still segfault? If it does, then you've probably trashed the memory where your FtpFileSystemModel instance lives.

    One other possibility: Are you creating this FtpFileSystemModel instance on the heap (with "FtpFileSystemModel * myModel = new FtpFileSystemModel;") or are you creating it on the stack in some method ("FtpFileSystemModel myModel;")? If you are doing it the second way, then the instance has probably gone out of scope and was destroyed before the code gets to your slot. (Although destruction is supposed to disconnect signals and slots).

  5. #5
    Join Date
    Aug 2013
    Posts
    32
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QStandardItem::appendRow() segfaults

    Quote Originally Posted by d_stranz View Post
    I didn't ask where it is initialized, I asked where it was defined. If you accidentally defined the variable "root_item" as both a local variable in the constructor and as a member variable in your class, then the local definition hides the class definition, so you aren't initializing the class variable as you think.
    Sorry, I forgot to answer that.

    The root_item is declared in the class header file. Then, initialized in the constructor.

    There's no local variable with the same name, so no obfuscation.

    The code has changed quite a bit, though, and now it has some other problems. I think I must really take a crash course about trees in Qt before making more noise here. There's surely some basic thing I am misunderstanding here, since everything I do only makes things worse and worse. I have read the model/view tuto, the QStandardItem[Model] manuals, the QAbstractItemModel manual, a lot of web pages, and even the sections about tree models in three different books and I can't really get the hang of it. It really doesn't matter if I use QStandardItemModel or QAbstractItemModel.

    I am pretty sure the (big) problem is in my understanding of the mechanism or index() and parent() methods, in either class, and how it all glues together. I am also sure that that segfault had something to do with that. Probably I ended up with a broken tree that failed in a colorful way.

    I have implemented all the imaginable trees in C and C++, Java and some other languages, but Qt is, for some reason, giving me a headache.

    But enough of crying for now :P

    I beg you pardon for wasting your time this way. Please, ignore this thread for now. I have some research to do, and, no doubt, I will come back to answer my own question. I am missing something really fundamental here...

    Nonetheless, thank you !!

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,067
    Thanks
    233
    Thanked 649 Times in 639 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: QStandardItem::appendRow() segfaults

    Well, generally the easiest way to implement a model to be used by a QTreeView is to implement an external, standalone data structure that contains the data you want to map to the model, using a plain old C++ data class / structure. Each of the items you want to place in the tree model contains a pointer to some node in this data tree. Thus, your model's parent() method will retrieve the pointer to the corresponding data node, go up a level in the data tree to its parent, then creates (using createIndex) a new QModelIndex where the row is the parent's index in its parent's (i.e. the grandparent of the current node) child list and the column is always zero. Set the internal data pointer of the new model index to the value of the parent node pointer and you're done.

    Likewise, the index() method calls createIndex() with the row and column number requested, and assigns the data tree pointer to the index's internal pointer.

    If you aren't getting a three-membered list (file, size, permission), then you are either 1) returning the wrong columnCount() for the node in the tree or 2) inserting the size and position as children of the file item (maybe by setting their parent() incorrectly in the model).

  7. #7
    Join Date
    Aug 2013
    Posts
    32
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QStandardItem::appendRow() segfaults

    Quote Originally Posted by d_stranz View Post
    Well, generally the easiest way to implement a model to be used by a QTreeView is to implement an external, standalone data structure that contains the data you want to map to the model, using a plain old C++ data class / structure. Each of the items you want to place in the tree model contains a pointer to some node in this data tree. Thus, your model's parent() method will retrieve the pointer to the corresponding data node, go up a level in the data tree to its parent, then creates (using createIndex) a new QModelIndex where the row is the parent's index in its parent's (i.e. the grandparent of the current node) child list and the column is always zero. Set the internal data pointer of the new model index to the value of the parent node pointer and you're done.

    Likewise, the index() method calls createIndex() with the row and column number requested, and assigns the data tree pointer to the index's internal pointer.

    If you aren't getting a three-membered list (file, size, permission), then you are either 1) returning the wrong columnCount() for the node in the tree or 2) inserting the size and position as children of the file item (maybe by setting their parent() incorrectly in the model).
    Thank you so much. That was really helpful.

    At the end of the day, a tree is just a tree, but I guess my previous experience with other languages played a trick or two on me this time, instead of being of help. That and the fact that QModelIndex() drives me to panic since I landed into the Qt view/model stuff as a whole some months ago :P

    Right now, the code is in a state that I get output from the class into the view. That's a good starting point. I am not completely reliant about my index() and parent() method, but I am in the right track, at last.

    In the right side of the image you can see the FtpFileSystemModel in action. Right now it can only show files. Hopefully it will learn to do some more stuff, given enough time

    20140522.180439.jpg

    Again, thank you

Similar Threads

  1. QSqlDatabase::open Segfaults
    By rich.remer in forum Qt Programming
    Replies: 3
    Last Post: 30th June 2010, 16:32
  2. Replies: 4
    Last Post: 16th August 2008, 02:42
  3. How to catch segfaults?
    By Daliphant in forum Newbie
    Replies: 4
    Last Post: 3rd July 2008, 14:17
  4. Anyone an idea why this code segfaults?
    By Kumosan in forum Qt Programming
    Replies: 4
    Last Post: 28th April 2007, 05:53
  5. http trouble again, segfaults when no internet
    By Bojan in forum Qt Programming
    Replies: 6
    Last Post: 18th January 2006, 20:25

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.