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 crashes (ItemSelectionChanged, QSortFilterProxyModel)
QtWS25 Last Chance

QTreeView crashes (ItemSelectionChanged, QSortFilterProxyModel)

Scheduled Pinned Locked Moved Solved General and Desktop
qt c++qtreeviewqitemselectionqsortfilter
8 Posts 5 Posters 837 Views
  • 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.
  • S Offline
    S Offline
    StudentScripter
    wrote on last edited by
    #1

    So i have a qtreeview subclass. Everything worked till i set the proxy filter model. Now it crashes as soon as i click an item in my treeview:

    treeview.cpp:

    
    #include <QApplication>
    #include <QFile>
    #include <QDataStream>
    
    #include <QJsonDocument>
    #include <QJsonObject>
    #include <QJsonArray>
    
    #include <QUndoCommand>
    
    #include <QSortFilterProxyModel>
    
    
    
    
    
    
    ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
        : QTreeView{parent}, scene_durchgereicht(scene)
    {
    
    
    
    
    
    
    
     setStyle(new ViewLayerDropIndicatorStyle(style()));
    
    
     // Ändern Sie den Abstand zwischen den Items und der vertikalen Scrollbar
        setViewportMargins(0, 0, 50, 0); // Passen Sie den rechten Rand (20) an Ihre Anforderungen an
        
    //Versteckt die sinnlose Kopfzeile
        setHeaderHidden(true);
        setRootIsDecorated(true);
        setMouseTracking(true);
    
    
    
    
    
    
    
    mydelegate = new ViewLayerItemDelegate(this);
    
    
    
    model = new ViewLayerStandartItemModel(0,1, this);
    
    
    
    
    
    
    
    this->setModel(model);
    this->setItemDelegate(mydelegate);
    
    
    
    this->setDragDropMode(QAbstractItemView::InternalMove);
    this->setSelectionMode(QAbstractItemView::ExtendedSelection);
    this->setDragEnabled(true);
    this->setAcceptDrops(true);
    this->setDropIndicatorShown(false);
    
    this->setMouseTracking(true);
    
    
    
    proxy = new QSortFilterProxyModel;
    proxy->setSourceModel(model);
    //proxy->setRecursiveFilteringEnabled(true);
    setModel(proxy);
    
    
    
    
    //Gibt das model an die GraphicsScene durch
    scene_durchgereicht->setModel(model);
    
    
    
    
    //Connect um die Textänderung im Delegaten an die Viewlayerlist zu übergeben und von hier aus
    //an ModulImage weiterzuverschicken (siehe Signalmanager Mainwindow.cpp)
    connect(mydelegate, &ViewLayerItemDelegate::SendItemNameChangedToViewLayerList, 
                    this, &ViewLayerList::ReceiveItemNameChangeFromDelegate);
    
    
    
    //Connect um die Textänderung im Delegaten an die Viewlayerlist zu übergeben und von hier aus
    //an ModulImage weiterzuverschicken (siehe Signalmanager Mainwindow.cpp)
    connect(mydelegate, &ViewLayerItemDelegate::SendViewLayerItemEditingFinishedToViewLayerList,
            this, &ViewLayerList::ReceiveDelegatedEditingISFinished);
    
    
    
    connect(scene_durchgereicht, &CustomGraphicsScene::SendSelectionChangedFromSceneToLayerList, this, &ViewLayerList::ReceiveSelectionChangedFromScene);
    
    connect(this, &ViewLayerList::SendGroupSelectionChangeToScene, scene_durchgereicht, &CustomGraphicsScene::ReceiveGroupSelectionChangeFromViewLayerList);
    
    
    connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ViewLayerList::selectionChanged);
    }
    
    
    
    
    
    
    
    //Eine Funktion um von einem QStandardItem aus das dazugehörige GraphicsItem zu bestimmen, gibt ein ResizablePixmapItem zurück
    ResizablePixmapItem* ViewLayerList::FindGraphicsItemFromListItem(QStandardItem *ListItem){
    
    
     QList<QGraphicsItem*> items = scene_durchgereicht->items();
        ResizablePixmapItem* korrespondierendesGraphicsItem = nullptr;
    
    
        for (QGraphicsItem* item : items) {
            // Überprüfen Sie, ob das Item die gleiche Scene ID hat wie das Standard-Item mit der ListID
            if (ResizablePixmapItem* pixmapItem = qgraphicsitem_cast<ResizablePixmapItem*>(item)) {
                if (pixmapItem->getSceneID() == ListItem->data(ViewLayerStandartItemModel::ListIDRole).toInt()) {
                    korrespondierendesGraphicsItem = pixmapItem;
                    break;
                }
            }
        }
    
    
        // Überprüfen Sie, ob das korrespondierende GraphicsItem gefunden wurde, bevor Sie es weitergeben
        if (korrespondierendesGraphicsItem) {
           return korrespondierendesGraphicsItem;
        }
        else {
            // Handle den Fall, wenn das korrespondierende GraphicsItem nicht gefunden wurde
            return nullptr;
    
        }
    
    }
    
    
    
    
    
    
    
    
    
    
    void ViewLayerList::ReceiveSelectionChangedFromScene(const QList<QStandardItem*>& selectedItems)
    {
    
    
        // Zugriff auf das SelectionModel, um ausgewählte Items zu erhalten
        QItemSelectionModel* selectionModel = this->selectionModel();
    
        if (selectionModel) {
            selectionModel->clearSelection();  // Alle vorherigen Auswahl aufheben
    
            // Durchlaufe alle übergebenen QStandardItems
            foreach (QStandardItem* selectedItem, selectedItems) {
                // Überprüfe, ob das Item gültig ist
                if (selectedItem) {
                    // Finde den QModelIndex für das QStandardItem
                    QModelIndex index = model->indexFromItem(selectedItem);
    
                    // Überprüfe, ob der Index gültig ist
                    if (index.isValid()) {
                        // Wähle die Zeile aus
                        selectionModel->select(index, QItemSelectionModel::Select);
                    }
                }
            }
        }
    }
    
    
    
    
    void ViewLayerList::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
    {
    
        //Setzt das selection Change der Scene auf true um Selektionupdates in der Scene zu verhindern
        scene_durchgereicht->isUpdatingSelection = true;
    
        // Zugriff auf das SelectionModel, um ausgewählte Items zu erhalten
        QItemSelectionModel *selectionModel1 = this->selectionModel();
        qDebug() << "SELMODEL1" << selectionModel1;
    
        if (selectionModel1) {
            selectedIndexes.clear();
            scene_durchgereicht->clearSelection();
            //emit scene_durchgereicht->selectionChanged();
            selectedIndexes = selectionModel1->selectedIndexes();
    
            QList<QGraphicsItem*> SelectedGraphicsItemsList;
    
            if(selectedIndexes.count() > 0){
                for (const QModelIndex &index : selectedIndexes) {
    
                    QStandardItem *SelectedItem = model->itemFromIndex(index);
    
                    //Ruft die Funktion zum finden des korrespondierenden GraphicsItems auf
                    ResizablePixmapItem *CorrespondingGraphicsItem = FindGraphicsItemFromListItem(SelectedItem);
                    if (CorrespondingGraphicsItem) {
                        CorrespondingGraphicsItem->setSelected(true);
    
                        SelectedGraphicsItemsList.append(CorrespondingGraphicsItem);
                    }
    
                }
    
            }
    
            //Sendet für das GroupRect die Seleteten Items
            emit SendGroupSelectionChangeToScene(SelectedGraphicsItemsList);
            SelectedGraphicsItemsList.clear();
    
            scene_durchgereicht->update();
    
        }
        update();
    
    
        //Setzt das selection Change der Scene auf falsch um Selektionupdates in der Scene wieder zu erlauben
        scene_durchgereicht->isUpdatingSelection = false;
    }
    
    

    Is it normal that selectionModel selection changed triggers twice on startup of the programm? cause in my case it gives the qDebug() 2 times. When using the debugger it crashes on startup... When i remove the setModel(proxy) everything works fine.

                                                                                                    
                                                                                                    
    1  ViewLayerList::selectionChanged                ViewLayerList.cpp          318 0x7ff703c1e5b2 
    2  QAbstractItemView::setSelectionModel           qabstractitemview.cpp      788 0x7fff0594c366 
    3  QTreeView::setSelectionModel                   qtreeview.cpp              245 0x7fff059c33a9 
    4  QAbstractItemView::setModel                    qabstractitemview.cpp      724 0x7fff0594a2b5 
    5  QTreeView::setModel                            qtreeview.cpp              203 0x7fff059c31ef 
    6  ViewLayerList::ViewLayerList                   ViewLayerList.cpp          73  0x7ff703c1d8b4 
    7  CustomDockableItemList::CustomDockableItemList CustomDockableItemList.cpp 38  0x7ff703c07f9f 
    8  MainWindow::MainWindow                         MainWindow.cpp             138 0x7ff703c05a3e 
    9  qMain                                          main.cpp                   8   0x7ff703c04616 
    10 qtEntryPoint                                   qtentrypoint_win.cpp       50  0x7ff703c2c092 
    11 __tmainCRTStartup                                                             0x7ff703c01395 
    12 WinMainCRTStartup                                                             0x7ff703c014c6 
    
    
    Christian EhrlicherC D 2 Replies Last reply
    0
    • S StudentScripter

      @DerReisende The second one is a qsortfilterproxy model so first i have to retrieve the real model in order to instantiate and than set the filter model. Or how am i supposed to to do that?

      EDIT: Well the problem seems to be that the filter proxy overrides my model and therefore everywhere when i used my model as reference before its now all wrong??? Is this normal

      For example here it gives me: "EditedListItem 0x0 model ViewLayerStandartItemModel(0x1b6999e6440) indexAtMosue QModelIndex(0,0,0x1b6999d6e30,QSortFilterProxyModel(0x1b6999e65e0))"

      //Erhält Live Buchstabe für Buchstabe ein Update von dem Delegaten
      void ViewLayerList::ReceiveItemNameChangeFromDelegate(const QString &Name)
      {
      
          QStandardItem *EditedListItem = model->itemFromIndex(indexAtMouse);
          qDebug() << "EditedListItem" << EditedListItem << "model" << model << "indexAtMosue" << indexAtMouse;
      
      
      D Offline
      D Offline
      DerReisende
      wrote on last edited by
      #6

      @StudentScripter There is no need for the first setModel call. You instantiate your model, then you create the proxy model and set your original model as the source model. Then you use the proxy in your tree. Since you now know your are using a proxy model you cannot directly use the model indices as the are proxy related, not source model related. As @SGaist wrote you have to use mapToSource for getting the correct content.
      The documentation is quite good on that and I strongly suggest you study the within mentioned basic examples how proxy models work. That helped me a lot using the sort filter model in my app.
      Aside from that on YouTube there is KDAB Qt Widgets and More. They have some videos about QTreeView and how to use QSortFilterProxyModels which are really worth watching.

      1 Reply Last reply
      0
      • S StudentScripter

        So i have a qtreeview subclass. Everything worked till i set the proxy filter model. Now it crashes as soon as i click an item in my treeview:

        treeview.cpp:

        
        #include <QApplication>
        #include <QFile>
        #include <QDataStream>
        
        #include <QJsonDocument>
        #include <QJsonObject>
        #include <QJsonArray>
        
        #include <QUndoCommand>
        
        #include <QSortFilterProxyModel>
        
        
        
        
        
        
        ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
            : QTreeView{parent}, scene_durchgereicht(scene)
        {
        
        
        
        
        
        
        
         setStyle(new ViewLayerDropIndicatorStyle(style()));
        
        
         // Ändern Sie den Abstand zwischen den Items und der vertikalen Scrollbar
            setViewportMargins(0, 0, 50, 0); // Passen Sie den rechten Rand (20) an Ihre Anforderungen an
            
        //Versteckt die sinnlose Kopfzeile
            setHeaderHidden(true);
            setRootIsDecorated(true);
            setMouseTracking(true);
        
        
        
        
        
        
        
        mydelegate = new ViewLayerItemDelegate(this);
        
        
        
        model = new ViewLayerStandartItemModel(0,1, this);
        
        
        
        
        
        
        
        this->setModel(model);
        this->setItemDelegate(mydelegate);
        
        
        
        this->setDragDropMode(QAbstractItemView::InternalMove);
        this->setSelectionMode(QAbstractItemView::ExtendedSelection);
        this->setDragEnabled(true);
        this->setAcceptDrops(true);
        this->setDropIndicatorShown(false);
        
        this->setMouseTracking(true);
        
        
        
        proxy = new QSortFilterProxyModel;
        proxy->setSourceModel(model);
        //proxy->setRecursiveFilteringEnabled(true);
        setModel(proxy);
        
        
        
        
        //Gibt das model an die GraphicsScene durch
        scene_durchgereicht->setModel(model);
        
        
        
        
        //Connect um die Textänderung im Delegaten an die Viewlayerlist zu übergeben und von hier aus
        //an ModulImage weiterzuverschicken (siehe Signalmanager Mainwindow.cpp)
        connect(mydelegate, &ViewLayerItemDelegate::SendItemNameChangedToViewLayerList, 
                        this, &ViewLayerList::ReceiveItemNameChangeFromDelegate);
        
        
        
        //Connect um die Textänderung im Delegaten an die Viewlayerlist zu übergeben und von hier aus
        //an ModulImage weiterzuverschicken (siehe Signalmanager Mainwindow.cpp)
        connect(mydelegate, &ViewLayerItemDelegate::SendViewLayerItemEditingFinishedToViewLayerList,
                this, &ViewLayerList::ReceiveDelegatedEditingISFinished);
        
        
        
        connect(scene_durchgereicht, &CustomGraphicsScene::SendSelectionChangedFromSceneToLayerList, this, &ViewLayerList::ReceiveSelectionChangedFromScene);
        
        connect(this, &ViewLayerList::SendGroupSelectionChangeToScene, scene_durchgereicht, &CustomGraphicsScene::ReceiveGroupSelectionChangeFromViewLayerList);
        
        
        connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ViewLayerList::selectionChanged);
        }
        
        
        
        
        
        
        
        //Eine Funktion um von einem QStandardItem aus das dazugehörige GraphicsItem zu bestimmen, gibt ein ResizablePixmapItem zurück
        ResizablePixmapItem* ViewLayerList::FindGraphicsItemFromListItem(QStandardItem *ListItem){
        
        
         QList<QGraphicsItem*> items = scene_durchgereicht->items();
            ResizablePixmapItem* korrespondierendesGraphicsItem = nullptr;
        
        
            for (QGraphicsItem* item : items) {
                // Überprüfen Sie, ob das Item die gleiche Scene ID hat wie das Standard-Item mit der ListID
                if (ResizablePixmapItem* pixmapItem = qgraphicsitem_cast<ResizablePixmapItem*>(item)) {
                    if (pixmapItem->getSceneID() == ListItem->data(ViewLayerStandartItemModel::ListIDRole).toInt()) {
                        korrespondierendesGraphicsItem = pixmapItem;
                        break;
                    }
                }
            }
        
        
            // Überprüfen Sie, ob das korrespondierende GraphicsItem gefunden wurde, bevor Sie es weitergeben
            if (korrespondierendesGraphicsItem) {
               return korrespondierendesGraphicsItem;
            }
            else {
                // Handle den Fall, wenn das korrespondierende GraphicsItem nicht gefunden wurde
                return nullptr;
        
            }
        
        }
        
        
        
        
        
        
        
        
        
        
        void ViewLayerList::ReceiveSelectionChangedFromScene(const QList<QStandardItem*>& selectedItems)
        {
        
        
            // Zugriff auf das SelectionModel, um ausgewählte Items zu erhalten
            QItemSelectionModel* selectionModel = this->selectionModel();
        
            if (selectionModel) {
                selectionModel->clearSelection();  // Alle vorherigen Auswahl aufheben
        
                // Durchlaufe alle übergebenen QStandardItems
                foreach (QStandardItem* selectedItem, selectedItems) {
                    // Überprüfe, ob das Item gültig ist
                    if (selectedItem) {
                        // Finde den QModelIndex für das QStandardItem
                        QModelIndex index = model->indexFromItem(selectedItem);
        
                        // Überprüfe, ob der Index gültig ist
                        if (index.isValid()) {
                            // Wähle die Zeile aus
                            selectionModel->select(index, QItemSelectionModel::Select);
                        }
                    }
                }
            }
        }
        
        
        
        
        void ViewLayerList::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
        {
        
            //Setzt das selection Change der Scene auf true um Selektionupdates in der Scene zu verhindern
            scene_durchgereicht->isUpdatingSelection = true;
        
            // Zugriff auf das SelectionModel, um ausgewählte Items zu erhalten
            QItemSelectionModel *selectionModel1 = this->selectionModel();
            qDebug() << "SELMODEL1" << selectionModel1;
        
            if (selectionModel1) {
                selectedIndexes.clear();
                scene_durchgereicht->clearSelection();
                //emit scene_durchgereicht->selectionChanged();
                selectedIndexes = selectionModel1->selectedIndexes();
        
                QList<QGraphicsItem*> SelectedGraphicsItemsList;
        
                if(selectedIndexes.count() > 0){
                    for (const QModelIndex &index : selectedIndexes) {
        
                        QStandardItem *SelectedItem = model->itemFromIndex(index);
        
                        //Ruft die Funktion zum finden des korrespondierenden GraphicsItems auf
                        ResizablePixmapItem *CorrespondingGraphicsItem = FindGraphicsItemFromListItem(SelectedItem);
                        if (CorrespondingGraphicsItem) {
                            CorrespondingGraphicsItem->setSelected(true);
        
                            SelectedGraphicsItemsList.append(CorrespondingGraphicsItem);
                        }
        
                    }
        
                }
        
                //Sendet für das GroupRect die Seleteten Items
                emit SendGroupSelectionChangeToScene(SelectedGraphicsItemsList);
                SelectedGraphicsItemsList.clear();
        
                scene_durchgereicht->update();
        
            }
            update();
        
        
            //Setzt das selection Change der Scene auf falsch um Selektionupdates in der Scene wieder zu erlauben
            scene_durchgereicht->isUpdatingSelection = false;
        }
        
        

        Is it normal that selectionModel selection changed triggers twice on startup of the programm? cause in my case it gives the qDebug() 2 times. When using the debugger it crashes on startup... When i remove the setModel(proxy) everything works fine.

                                                                                                        
                                                                                                        
        1  ViewLayerList::selectionChanged                ViewLayerList.cpp          318 0x7ff703c1e5b2 
        2  QAbstractItemView::setSelectionModel           qabstractitemview.cpp      788 0x7fff0594c366 
        3  QTreeView::setSelectionModel                   qtreeview.cpp              245 0x7fff059c33a9 
        4  QAbstractItemView::setModel                    qabstractitemview.cpp      724 0x7fff0594a2b5 
        5  QTreeView::setModel                            qtreeview.cpp              203 0x7fff059c31ef 
        6  ViewLayerList::ViewLayerList                   ViewLayerList.cpp          73  0x7ff703c1d8b4 
        7  CustomDockableItemList::CustomDockableItemList CustomDockableItemList.cpp 38  0x7ff703c07f9f 
        8  MainWindow::MainWindow                         MainWindow.cpp             138 0x7ff703c05a3e 
        9  qMain                                          main.cpp                   8   0x7ff703c04616 
        10 qtEntryPoint                                   qtentrypoint_win.cpp       50  0x7ff703c2c092 
        11 __tmainCRTStartup                                                             0x7ff703c01395 
        12 WinMainCRTStartup                                                             0x7ff703c014c6 
        
        
        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @StudentScripter said in QTreeView crashes (ItemSelectionChanged, QSortFilterProxyModel):

        1 ViewLayerList::selectionChanged ViewLayerList.cpp 318 0x7ff703c1e5b2

        It is crashing in your code so you should fix your code.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        1
        • S StudentScripter

          So i have a qtreeview subclass. Everything worked till i set the proxy filter model. Now it crashes as soon as i click an item in my treeview:

          treeview.cpp:

          
          #include <QApplication>
          #include <QFile>
          #include <QDataStream>
          
          #include <QJsonDocument>
          #include <QJsonObject>
          #include <QJsonArray>
          
          #include <QUndoCommand>
          
          #include <QSortFilterProxyModel>
          
          
          
          
          
          
          ViewLayerList::ViewLayerList(CustomGraphicsScene *scene, QWidget *parent)
              : QTreeView{parent}, scene_durchgereicht(scene)
          {
          
          
          
          
          
          
          
           setStyle(new ViewLayerDropIndicatorStyle(style()));
          
          
           // Ändern Sie den Abstand zwischen den Items und der vertikalen Scrollbar
              setViewportMargins(0, 0, 50, 0); // Passen Sie den rechten Rand (20) an Ihre Anforderungen an
              
          //Versteckt die sinnlose Kopfzeile
              setHeaderHidden(true);
              setRootIsDecorated(true);
              setMouseTracking(true);
          
          
          
          
          
          
          
          mydelegate = new ViewLayerItemDelegate(this);
          
          
          
          model = new ViewLayerStandartItemModel(0,1, this);
          
          
          
          
          
          
          
          this->setModel(model);
          this->setItemDelegate(mydelegate);
          
          
          
          this->setDragDropMode(QAbstractItemView::InternalMove);
          this->setSelectionMode(QAbstractItemView::ExtendedSelection);
          this->setDragEnabled(true);
          this->setAcceptDrops(true);
          this->setDropIndicatorShown(false);
          
          this->setMouseTracking(true);
          
          
          
          proxy = new QSortFilterProxyModel;
          proxy->setSourceModel(model);
          //proxy->setRecursiveFilteringEnabled(true);
          setModel(proxy);
          
          
          
          
          //Gibt das model an die GraphicsScene durch
          scene_durchgereicht->setModel(model);
          
          
          
          
          //Connect um die Textänderung im Delegaten an die Viewlayerlist zu übergeben und von hier aus
          //an ModulImage weiterzuverschicken (siehe Signalmanager Mainwindow.cpp)
          connect(mydelegate, &ViewLayerItemDelegate::SendItemNameChangedToViewLayerList, 
                          this, &ViewLayerList::ReceiveItemNameChangeFromDelegate);
          
          
          
          //Connect um die Textänderung im Delegaten an die Viewlayerlist zu übergeben und von hier aus
          //an ModulImage weiterzuverschicken (siehe Signalmanager Mainwindow.cpp)
          connect(mydelegate, &ViewLayerItemDelegate::SendViewLayerItemEditingFinishedToViewLayerList,
                  this, &ViewLayerList::ReceiveDelegatedEditingISFinished);
          
          
          
          connect(scene_durchgereicht, &CustomGraphicsScene::SendSelectionChangedFromSceneToLayerList, this, &ViewLayerList::ReceiveSelectionChangedFromScene);
          
          connect(this, &ViewLayerList::SendGroupSelectionChangeToScene, scene_durchgereicht, &CustomGraphicsScene::ReceiveGroupSelectionChangeFromViewLayerList);
          
          
          connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ViewLayerList::selectionChanged);
          }
          
          
          
          
          
          
          
          //Eine Funktion um von einem QStandardItem aus das dazugehörige GraphicsItem zu bestimmen, gibt ein ResizablePixmapItem zurück
          ResizablePixmapItem* ViewLayerList::FindGraphicsItemFromListItem(QStandardItem *ListItem){
          
          
           QList<QGraphicsItem*> items = scene_durchgereicht->items();
              ResizablePixmapItem* korrespondierendesGraphicsItem = nullptr;
          
          
              for (QGraphicsItem* item : items) {
                  // Überprüfen Sie, ob das Item die gleiche Scene ID hat wie das Standard-Item mit der ListID
                  if (ResizablePixmapItem* pixmapItem = qgraphicsitem_cast<ResizablePixmapItem*>(item)) {
                      if (pixmapItem->getSceneID() == ListItem->data(ViewLayerStandartItemModel::ListIDRole).toInt()) {
                          korrespondierendesGraphicsItem = pixmapItem;
                          break;
                      }
                  }
              }
          
          
              // Überprüfen Sie, ob das korrespondierende GraphicsItem gefunden wurde, bevor Sie es weitergeben
              if (korrespondierendesGraphicsItem) {
                 return korrespondierendesGraphicsItem;
              }
              else {
                  // Handle den Fall, wenn das korrespondierende GraphicsItem nicht gefunden wurde
                  return nullptr;
          
              }
          
          }
          
          
          
          
          
          
          
          
          
          
          void ViewLayerList::ReceiveSelectionChangedFromScene(const QList<QStandardItem*>& selectedItems)
          {
          
          
              // Zugriff auf das SelectionModel, um ausgewählte Items zu erhalten
              QItemSelectionModel* selectionModel = this->selectionModel();
          
              if (selectionModel) {
                  selectionModel->clearSelection();  // Alle vorherigen Auswahl aufheben
          
                  // Durchlaufe alle übergebenen QStandardItems
                  foreach (QStandardItem* selectedItem, selectedItems) {
                      // Überprüfe, ob das Item gültig ist
                      if (selectedItem) {
                          // Finde den QModelIndex für das QStandardItem
                          QModelIndex index = model->indexFromItem(selectedItem);
          
                          // Überprüfe, ob der Index gültig ist
                          if (index.isValid()) {
                              // Wähle die Zeile aus
                              selectionModel->select(index, QItemSelectionModel::Select);
                          }
                      }
                  }
              }
          }
          
          
          
          
          void ViewLayerList::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
          {
          
              //Setzt das selection Change der Scene auf true um Selektionupdates in der Scene zu verhindern
              scene_durchgereicht->isUpdatingSelection = true;
          
              // Zugriff auf das SelectionModel, um ausgewählte Items zu erhalten
              QItemSelectionModel *selectionModel1 = this->selectionModel();
              qDebug() << "SELMODEL1" << selectionModel1;
          
              if (selectionModel1) {
                  selectedIndexes.clear();
                  scene_durchgereicht->clearSelection();
                  //emit scene_durchgereicht->selectionChanged();
                  selectedIndexes = selectionModel1->selectedIndexes();
          
                  QList<QGraphicsItem*> SelectedGraphicsItemsList;
          
                  if(selectedIndexes.count() > 0){
                      for (const QModelIndex &index : selectedIndexes) {
          
                          QStandardItem *SelectedItem = model->itemFromIndex(index);
          
                          //Ruft die Funktion zum finden des korrespondierenden GraphicsItems auf
                          ResizablePixmapItem *CorrespondingGraphicsItem = FindGraphicsItemFromListItem(SelectedItem);
                          if (CorrespondingGraphicsItem) {
                              CorrespondingGraphicsItem->setSelected(true);
          
                              SelectedGraphicsItemsList.append(CorrespondingGraphicsItem);
                          }
          
                      }
          
                  }
          
                  //Sendet für das GroupRect die Seleteten Items
                  emit SendGroupSelectionChangeToScene(SelectedGraphicsItemsList);
                  SelectedGraphicsItemsList.clear();
          
                  scene_durchgereicht->update();
          
              }
              update();
          
          
              //Setzt das selection Change der Scene auf falsch um Selektionupdates in der Scene wieder zu erlauben
              scene_durchgereicht->isUpdatingSelection = false;
          }
          
          

          Is it normal that selectionModel selection changed triggers twice on startup of the programm? cause in my case it gives the qDebug() 2 times. When using the debugger it crashes on startup... When i remove the setModel(proxy) everything works fine.

                                                                                                          
                                                                                                          
          1  ViewLayerList::selectionChanged                ViewLayerList.cpp          318 0x7ff703c1e5b2 
          2  QAbstractItemView::setSelectionModel           qabstractitemview.cpp      788 0x7fff0594c366 
          3  QTreeView::setSelectionModel                   qtreeview.cpp              245 0x7fff059c33a9 
          4  QAbstractItemView::setModel                    qabstractitemview.cpp      724 0x7fff0594a2b5 
          5  QTreeView::setModel                            qtreeview.cpp              203 0x7fff059c31ef 
          6  ViewLayerList::ViewLayerList                   ViewLayerList.cpp          73  0x7ff703c1d8b4 
          7  CustomDockableItemList::CustomDockableItemList CustomDockableItemList.cpp 38  0x7ff703c07f9f 
          8  MainWindow::MainWindow                         MainWindow.cpp             138 0x7ff703c05a3e 
          9  qMain                                          main.cpp                   8   0x7ff703c04616 
          10 qtEntryPoint                                   qtentrypoint_win.cpp       50  0x7ff703c2c092 
          11 __tmainCRTStartup                                                             0x7ff703c01395 
          12 WinMainCRTStartup                                                             0x7ff703c014c6 
          
          
          D Offline
          D Offline
          DerReisende
          wrote on last edited by
          #3

          @StudentScripter why setModel(model) and then later setModel(proxy)? And are you sure your ViewLayerStandartItemModel ist working correctly? You can use QAbstractItemModelTester during runtime to see if you have basic problems in your model.

          S 1 Reply Last reply
          1
          • D DerReisende

            @StudentScripter why setModel(model) and then later setModel(proxy)? And are you sure your ViewLayerStandartItemModel ist working correctly? You can use QAbstractItemModelTester during runtime to see if you have basic problems in your model.

            S Offline
            S Offline
            StudentScripter
            wrote on last edited by StudentScripter
            #4

            @DerReisende The second one is a qsortfilterproxy model so first i have to retrieve the real model in order to instantiate and than set the filter model. Or how am i supposed to to do that?

            EDIT: Well the problem seems to be that the filter proxy overrides my model and therefore everywhere when i used my model as reference before its now all wrong??? Is this normal

            For example here it gives me: "EditedListItem 0x0 model ViewLayerStandartItemModel(0x1b6999e6440) indexAtMosue QModelIndex(0,0,0x1b6999d6e30,QSortFilterProxyModel(0x1b6999e65e0))"

            //Erhält Live Buchstabe für Buchstabe ein Update von dem Delegaten
            void ViewLayerList::ReceiveItemNameChangeFromDelegate(const QString &Name)
            {
            
                QStandardItem *EditedListItem = model->itemFromIndex(indexAtMouse);
                qDebug() << "EditedListItem" << EditedListItem << "model" << model << "indexAtMosue" << indexAtMouse;
            
            
            SGaistS D JonBJ 3 Replies Last reply
            0
            • S StudentScripter

              @DerReisende The second one is a qsortfilterproxy model so first i have to retrieve the real model in order to instantiate and than set the filter model. Or how am i supposed to to do that?

              EDIT: Well the problem seems to be that the filter proxy overrides my model and therefore everywhere when i used my model as reference before its now all wrong??? Is this normal

              For example here it gives me: "EditedListItem 0x0 model ViewLayerStandartItemModel(0x1b6999e6440) indexAtMosue QModelIndex(0,0,0x1b6999d6e30,QSortFilterProxyModel(0x1b6999e65e0))"

              //Erhält Live Buchstabe für Buchstabe ein Update von dem Delegaten
              void ViewLayerList::ReceiveItemNameChangeFromDelegate(const QString &Name)
              {
              
                  QStandardItem *EditedListItem = model->itemFromIndex(indexAtMouse);
                  qDebug() << "EditedListItem" << EditedListItem << "model" << model << "indexAtMosue" << indexAtMouse;
              
              
              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #5

              @StudentScripter Hi,

              That's normal, when you call setModel(proxy); your view will replace its current model with the proxy model. Calling setModel multiple times does not "stack" them.

              You want to check mapToSource to get the proxied model's model index.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              3
              • S StudentScripter

                @DerReisende The second one is a qsortfilterproxy model so first i have to retrieve the real model in order to instantiate and than set the filter model. Or how am i supposed to to do that?

                EDIT: Well the problem seems to be that the filter proxy overrides my model and therefore everywhere when i used my model as reference before its now all wrong??? Is this normal

                For example here it gives me: "EditedListItem 0x0 model ViewLayerStandartItemModel(0x1b6999e6440) indexAtMosue QModelIndex(0,0,0x1b6999d6e30,QSortFilterProxyModel(0x1b6999e65e0))"

                //Erhält Live Buchstabe für Buchstabe ein Update von dem Delegaten
                void ViewLayerList::ReceiveItemNameChangeFromDelegate(const QString &Name)
                {
                
                    QStandardItem *EditedListItem = model->itemFromIndex(indexAtMouse);
                    qDebug() << "EditedListItem" << EditedListItem << "model" << model << "indexAtMosue" << indexAtMouse;
                
                
                D Offline
                D Offline
                DerReisende
                wrote on last edited by
                #6

                @StudentScripter There is no need for the first setModel call. You instantiate your model, then you create the proxy model and set your original model as the source model. Then you use the proxy in your tree. Since you now know your are using a proxy model you cannot directly use the model indices as the are proxy related, not source model related. As @SGaist wrote you have to use mapToSource for getting the correct content.
                The documentation is quite good on that and I strongly suggest you study the within mentioned basic examples how proxy models work. That helped me a lot using the sort filter model in my app.
                Aside from that on YouTube there is KDAB Qt Widgets and More. They have some videos about QTreeView and how to use QSortFilterProxyModels which are really worth watching.

                1 Reply Last reply
                0
                • S StudentScripter

                  @DerReisende The second one is a qsortfilterproxy model so first i have to retrieve the real model in order to instantiate and than set the filter model. Or how am i supposed to to do that?

                  EDIT: Well the problem seems to be that the filter proxy overrides my model and therefore everywhere when i used my model as reference before its now all wrong??? Is this normal

                  For example here it gives me: "EditedListItem 0x0 model ViewLayerStandartItemModel(0x1b6999e6440) indexAtMosue QModelIndex(0,0,0x1b6999d6e30,QSortFilterProxyModel(0x1b6999e65e0))"

                  //Erhält Live Buchstabe für Buchstabe ein Update von dem Delegaten
                  void ViewLayerList::ReceiveItemNameChangeFromDelegate(const QString &Name)
                  {
                  
                      QStandardItem *EditedListItem = model->itemFromIndex(indexAtMouse);
                      qDebug() << "EditedListItem" << EditedListItem << "model" << model << "indexAtMosue" << indexAtMouse;
                  
                  
                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #7

                  @StudentScripter said in QTreeView crashes (ItemSelectionChanged, QSortFilterProxyModel):

                  and therefore everywhere when i used my model as reference before its now all wrong??

                  The answer is "some calls will now be wrong, some will still work, depends on the call". You probably do need to look through all your existing code to decide on a case-by-case basis.

                  You need to be aware that your view is now attached to the proxy model, not (directly) to the source model. The problem here is that the output shows your indexAtMouse is an index into the QSortFilterProxyModel but model->itemFromIndex (where model is the source model) needs the index to be in the same model as model. Hence the need to mapToSource()in this case.

                  However, for example proxyModel->data(proxyModelIndex) will work as it used to when your model was only the source model, prior to you introducing the proxy model on top. If it's a proxy model the proxy's code will do the mapping to source for you, and return the source model's data.

                  This is because QSFPM reimplements certain virtual methods to pass them through to base calls with needed mappings to/from source. You gather this by looking at e.g. https://doc.qt.io/qt-6/qsortfilterproxymodel.html#reimplemented-public-functions. You may also need to look at the base https://doc.qt.io/qt-6/qabstractproxymodel.html. Between the two of them you see that data() is reimplemented, so your original code works even if you call it on the proxy model. But you don't see that the proxy in any way reimplements QStandardItemModel::itemFromIndex() (it's not virtual, and it only belongs to QStandardItemModel which is not the type for a QSFPM). So that means you need to deal with mapping to/from source/proxy in your code.

                  Hopefully this clarifies what you need to think about.

                  S 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @StudentScripter said in QTreeView crashes (ItemSelectionChanged, QSortFilterProxyModel):

                    and therefore everywhere when i used my model as reference before its now all wrong??

                    The answer is "some calls will now be wrong, some will still work, depends on the call". You probably do need to look through all your existing code to decide on a case-by-case basis.

                    You need to be aware that your view is now attached to the proxy model, not (directly) to the source model. The problem here is that the output shows your indexAtMouse is an index into the QSortFilterProxyModel but model->itemFromIndex (where model is the source model) needs the index to be in the same model as model. Hence the need to mapToSource()in this case.

                    However, for example proxyModel->data(proxyModelIndex) will work as it used to when your model was only the source model, prior to you introducing the proxy model on top. If it's a proxy model the proxy's code will do the mapping to source for you, and return the source model's data.

                    This is because QSFPM reimplements certain virtual methods to pass them through to base calls with needed mappings to/from source. You gather this by looking at e.g. https://doc.qt.io/qt-6/qsortfilterproxymodel.html#reimplemented-public-functions. You may also need to look at the base https://doc.qt.io/qt-6/qabstractproxymodel.html. Between the two of them you see that data() is reimplemented, so your original code works even if you call it on the proxy model. But you don't see that the proxy in any way reimplements QStandardItemModel::itemFromIndex() (it's not virtual, and it only belongs to QStandardItemModel which is not the type for a QSFPM). So that means you need to deal with mapping to/from source/proxy in your code.

                    Hopefully this clarifies what you need to think about.

                    S Offline
                    S Offline
                    StudentScripter
                    wrote on last edited by
                    #8

                    @JonB @SGaist @DerReisende Thank you all very much. Thats kinda tedious to do but guess thats how it is. Appreciate all your help and indeed mapFrom and mapToSource are what fixes my issue. :D Y'all have a nice day.

                    1 Reply Last reply
                    0
                    • S StudentScripter has marked this topic as solved on

                    • Login

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