QModelIndexList из QTreeView, дающего отладочное утверждение

В одном из моих проектов на Qt у меня есть требование выбора нескольких элементов из папки, такой как представление (представление в виде дерева), и заполнение выбранных элементов в другом виджете. Чтобы отобразить доступные элементы для множественного выбора, я использую QTreeView и заполняю иерархию элементов, как показано ниже.

m_StandardModel = new QStandardItemModel ;
QStandardItem *rootNode = m_StandardModel->invisibleRootItem();

//defining a couple of items
QStandardItem *item1 =  new QStandardItem(tr("ITEM1"));
QStandardItem *item2 =  new QStandardItem(tr("ITEM2"));
QStandardItem *item3 =  new QStandardItem(tr("ITEM3"));
QStandardItem *item4 =  new QStandardItem(tr("ITEM4"));

rootNode->appendRow(item1 );
rootNode->appendRow(item2 );
rootNode->appendRow(item3 );
rootNode->appendRow(item4 );

 //register the model
ui->treeView->setModel(m_StandardModel);
ui->treeView->expandAll();

//enabling multiselection behaviour
QItemSelectionModel *selectionModel= ui->treeView->selectionModel();
ui->treeView->setSelectionMode(QAbstractItemView::MultiSelection);

Все в порядке, пока здесь. Я могу отображать свои элементы в виде дерева, а также могу выбирать элементы из нескольких элементов. Проблема возникает, когда я пытаюсь использовать эти несколько выбранных элементов из древовидного представления.

В своем пользовательском интерфейсе я подключил сигнал кнопки clicked() к моему слоту, который обрабатывает итерацию и манипулирование выбранными элементами. Вот вызываемая функция:

//User selects a number of features listed on the left pane and clicks this button to  disable them
void MainWindow::on_pushButton_2_clicked()
{        
    QModelIndexList selectedItems =  ui->treeView->selectionModel()->selectedIndexes();

    QStringList items;

    foreach(QModelIndex index, selectedItems)
    {
        QStandardItemModel* itemModel = dynamic_cast<QStandardItemModel*>(ui->treeView->model());
        if(itemModel)
        {
            QStandardItem* item = itemModel->itemFromIndex(index);
            items<< item->data().toString();
        }
    }
}

Отладка до конца функции идеальна. Но как только я выхожу из этой функции (показано выше), я получаю DEBUG ASSERTION!! как следующее

HEAP[myprog.exe]: Invalid address specified to RtlValidateHeap( 00390000, 01946798 )

Стек вызовов показывает, что это утверждение достигается из-за уничтожения локального списка QModelIndexList, который я создал в функции.

Ниже приведен стек вызовов во время утверждения отладки: введите здесь описание изображения

Любая идея, что мне может не хватать? Я пробовал несколько раз, но так и не смог понять реальную проблему. Есть ли лучший способ сделать то, что делается здесь? Я использую QT 4.8.4 и создаю/отлаживаю свое приложение в конфигурации DEBUG в Windows 7.


person Manmohan Singh    schedule 07.05.2014    source источник
comment
Вы показываете полную функцию void MainWindow::on_pushButton_2_clicked()? Как вы используете элементы (QStringList)? Пожалуйста, покажите полный код.   -  person vahancho    schedule 07.05.2014
comment
@vahancho: функция void MainWindow::on_pushButton_2_clicked() здесь завершена. items - это QStringList, который я использовал, чтобы увидеть, выбираю ли я правильные значения. Я упростил фактическую логику здесь. На самом деле нет никакого утверждения, если я не использую QModelIndexList! Только после того, как я его использую, возникает проблема.   -  person Manmohan Singh    schedule 07.05.2014


Ответы (1)


Я попробовал ваш код в приложении Windows и не вижу вашего поведения, возможно, у вас есть дополнительный код в другой части программы, который генерирует такое поведение. Код, который я протестировал, выглядит следующим образом (я изменил только способ получения данных, а не роль отображения item->data(Qt::DisplayRole).toString()):

CPP-файл:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_StandardModel = new QStandardItemModel ;
    QStandardItem *rootNode = m_StandardModel->invisibleRootItem();

    //defining a couple of items
    QStandardItem *item1 =  new QStandardItem(tr("ITEM1"));
    QStandardItem *item2 =  new QStandardItem(tr("ITEM2"));
    QStandardItem *item3 =  new QStandardItem(tr("ITEM3"));
    QStandardItem *item4 =  new QStandardItem(tr("ITEM4"));

    rootNode->appendRow(item1 );
    rootNode->appendRow(item2 );
    rootNode->appendRow(item3 );
    rootNode->appendRow(item4 );

     //register the model
    ui->treeView->setModel(m_StandardModel);
    ui->treeView->expandAll();

    //enabling multiselection behaviour
    QItemSelectionModel *selectionModel= ui->treeView->selectionModel();
    ui->treeView->setSelectionMode(QAbstractItemView::MultiSelection);

    connect(ui->pushButton,     SIGNAL(clicked()),
            this,               SLOT(on_pushButton_clicked()) );
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked(){
    QModelIndexList selectedItems =  ui->treeView->selectionModel()->selectedIndexes();

       QStringList items;

       foreach(QModelIndex index, selectedItems)
       {
           QStandardItemModel* itemModel = dynamic_cast<QStandardItemModel*>(ui->treeView->model());
           if(itemModel)
           {
               QStandardItem* item = itemModel->itemFromIndex(index);
               items << item->data(Qt::DisplayRole).toString();
           }
       }
}


Заголовочный файл:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStandardItemModel>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QStandardItemModel * m_StandardModel ;
};

#endif // MAINWINDOW_H

Может быть, вы можете опубликовать исходный код дыры, чтобы увидеть, как вы себя ведете.

person Gasteizko    schedule 26.04.2019