Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTreeView displays one top level item and wrong children
Qt 6.11 is out! See what's new in the release blog

QTreeView displays one top level item and wrong children

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 2.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Boumbles
    wrote on last edited by
    #1

    This problem might be a little bit too involved for here but here goes.

    We're moving some code to Qt5.1 (currently it uses VCL) and would like to use a QTreeView for displaying one of the data structures.

    The data structure is a kind of stack where each item in the stack has a number of items in it. These items have no children. I've modified the stack data structure to be our model. Looks kind of like this

    |StackEntry1

    • -itemA
    • -itemB
      |StackEntry0
      --itemX
      --itemY
      --itemZ

    The data structure itself appears to be quite solid. Children are pointing to the right parent objects and vise versa. However, when I connect the model to the view there is some odd behavior.

    At load everythign is fine, the first thing pushed onto the stack appears in the view, all its children are there.

    |StackEntry0
    --itemX
    --itemY
    However, once I push anything else onto the stack, the view displays the new item's name as the top item, and displays the original item's children underneath.

    |StackEntry1
    --itemX
    --itemY

    I'm also noticing that

    data() never gets called on StackEntry0 once we add StackEntry1

    rowcount() only counts the two StackEntries once when I try expanding StackEntry1

    Below is the code for the QTreeView methods. The objects in the stack are ModeStackMenuEntry. The StackEntryNs above are of type Mode and the ItemN are of type ModeEntry

    @QModelIndex ModeStack::index(int row, int column, QModelIndex const &parent) const {
    ModeStackMenuEntry parent_entry = NULL;
    Mode parent_mode = NULL;
    ModeEntry child_entry = NULL;
    if (!parent.isValid()) {//juts get top level Mode
    parent_mode = const_cast<Mode
    >(ModeAt(row));
    if (!parent_mode) return QModelIndex();
    QString foo = parent_mode->GetName();
    return createIndex(row, column, parent_mode);
    }
    parent_entry = static_cast<ModeStackMenuEntry
    >(parent.internalPointer());
    parent_mode = dynamic_cast<Mode
    >(parent_entry);

    if (parent_mode) {
        std::string goober = parent_mode->GetName().toUtf8().data();
        char g = goober[0];
        if (row < parent_mode->count())
            child_entry = &parent_mode->GetEntry(row);
    } else {
        return QModelIndex();
    }
    if (child_entry) {
        return createIndex(row, column, child_entry);
    }
    return QModelIndex();
    

    }
    QModelIndex ModeStack::parent(QModelIndex const &index) const {
    if (!index.isValid())
    return QModelIndex();

    ModeStackMenuEntry *row_ptr = static_cast<ModeStackMenuEntry*>(index.internalPointer());
    Mode *item = NULL, *item_parent = NULL; ModeEntry *entry = NULL;
    item = dynamic_cast<Mode*>(row_ptr);
    if (item) {
        return QModelIndex();
    } else {
        entry = dynamic_cast<ModeEntry*>(row_ptr);
        if (entry) {
            return createIndex(StackIndex(*entry->parent()), 0, entry->parent());
        }
    }
    
    return createIndex(item_parent->GetModeEntryIndex(*entry), 0, item_parent);
    

    }
    int ModeStack::rowCount(QModelIndex const &parent) const {
    int ret = 0;
    ModeStackMenuEntry* item = NULL;
    if (parent.column() > 0)
    ret = 0;
    else if (!parent.isValid())
    ret = StackDepth();
    else {
    item = static_cast<ModeStackMenuEntry*>(parent.internalPointer());
    ret = item->count();
    }
    return ret;
    }
    int ModeStack::columnCount( QModelIndex const &parent) const {
    EntryType type = GetEntryType(parent);
    if (type == EntryType::ModeEntry)
    return 1;
    return 2;
    }
    QVariant ModeStack::data(QModelIndex const &index, int role) const {
    if (role != Qt::DisplayRole)
    return QVariant();
    if (!index.isValid())
    return QVariant();
    ModeStackMenuEntry item = static_cast<ModeStackMenuEntry>(index.internalPointer());
    return item->GetText(index.column());
    }

    bool ModeStack::hasChildren(QModelIndex const &parent) const {
    bool b = false;
    b = rowCount(parent) > 0;

    return b;
    

    }@

    1 Reply Last reply
    0
    • B Offline
      B Offline
      Boumbles
      wrote on last edited by
      #2

      An interesting development. I was thinking maybe the life of the QModelIndexes was somewhat, borked.

      We're using a stack here, so What is at Index 0 in the beginning, ends up being moved to Index 1 when a new item is put in. I theorized that maybe this was messing up the QModelIndexes.

      I tried turning out Stack into a simple List. Instead of being put on tpo, the new items get put at the end. Now intead of getting a second item, i get nothign new in the model. However, rowCoutn is still returning 2 when it checks the Model. Odd.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        Boumbles
        wrote on last edited by
        #3

        Ok so i've got it 'working' now. However, i'm skeptical.

        By adding a line
        @emit(layoutChanged())@

        in my model whenever I add or remove something from the stack, everything updates properly. Is this good practice?

        1 Reply Last reply
        0
        • P Offline
          P Offline
          poorBob
          wrote on last edited by
          #4

          How do You add/remove items from this stack?

          Did You read "this":https://qt-project.org/doc/qt-4.8/model-view-programming.html#inserting-and-removing-rows? This should explain hot to insert/remove rows from/to Your model.

          Hope this will help You,

          Robert

          1 Reply Last reply
          0
          • B Offline
            B Offline
            Boumbles
            wrote on last edited by
            #5

            Hi Robert,

            Right now there are simply some Push/Pop methods in the class that handle adding/removing data.

            I suspect that the information you linked will solve our problems but this will require some serious refactoring to get working. Once that's finished I will post back.

            1 Reply Last reply
            0
            • P Offline
              P Offline
              poorBob
              wrote on last edited by
              #6

              If You have any doubts just write them down. I will try to help You :).

              Robert

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved