QItemSelectionModel::selectedIndexes() 崩溃
Posted
技术标签:
【中文标题】QItemSelectionModel::selectedIndexes() 崩溃【英文标题】:Crash with QItemSelectionModel::selectedIndexes() 【发布时间】:2013-02-27 21:48:49 【问题描述】:我一直在寻找解决这个问题的方法,我开始相信这可能是 Qt 函数本身的一个错误。 问题是,在您调用 QItemSelectionModel::selectedIndexes() 后,当程序尝试破坏此函数返回的 QModelIndexList 时,程序将崩溃。在崩溃之前,您会收到以下调试消息:
调试断言失败! (…) 文件: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c 线路:1419 表达: _pFirstBlock == pHead (…)
这里是最简单的会导致问题的代码,大家可以自己测试一下:
#include <QApplication>
#include <QStringList>
#include <QStringListModel>
#include <QItemSelectionModel>
#include <QModelIndex>
#include <QModelIndexList>
#include <QListView>
#include <QItemSelectionModel>
void doSomethingWithSelection(QItemSelectionModel* selectionmodel);
int main(int argc, char *argv[])
QApplication a(argc, argv);
QStringList list;
list.push_back("1");
list.push_back("2");
list.push_back("3");
list.push_back("4");
QStringListModel model(list);
QListView view;
view.setModel(&model);
view.setSelectionMode(QAbstractItemView::ExtendedSelection);
QItemSelectionModel *selectionmodel = view.selectionModel();
QModelIndex first = model.index(0);
QModelIndex last = model.index(2);
QItemSelection selection(first, last);
selectionmodel->select(selection,QItemSelectionModel::Select);
doSomethingWithSelection(selectionmodel);
view.show();
return a.exec();
void doSomethingWithSelection(QItemSelectionModel* selectionmodel)
QModelIndexList indexlist = selectionmodel->selectedIndexes();
// this is what causes the error. I put this inside a function
// so the error will happen when exiting the function,
// when the program try to destroy the list nodes.
【问题讨论】:
也许您只能在 Qt 循环中使用 QItemSelectionModel。您可以尝试在 a.exec() 之后调用 doSomethingWithSelection 吗? 好吧,我真的不知道你说“仅在 Qt 循环中”是什么意思.. 但是关于在 a.exec() 之后调用,这是不可能的,因为 a.exec( ) 是启动应用程序循环的东西,一切都发生在这个函数内。之后程序返回。 在“Qt 循环”下,我指的是应用程序循环。 【参考方案1】:我有完全相同的问题,只是我使用选定的行而不是选定的索引。当 QModelIndexList 中的内部 QList 尝试从堆中删除索引时,我将其缩小到函数退出。不知道如何解决它,但我读了这篇有趣的帖子here 并想出了这个功能:
QModelIndexList Class::getViewSelection(QAbstractItemView *view , int columnNumber) const
QModelIndexList list;
for (int row = 0; row < view->model()->rowCount(view->rootIndex()); ++row)
QModelIndex index = view->model()->index(row, columnNumber, view->rootIndex());
if (view->selectionModel()->isSelected(index))
list.push_back(index);
return list;
我编写了这个函数来获取选定的行,因此列参数是您想要索引的列。
【讨论】:
【参考方案2】:我在使用 QTreeView
和访问 selectedIndexes()
或 selectionModel()
中的任何内容时遇到了同样的问题。
当我使用正确的 /MD
编译器开关和正确的 Qt
库时,它已修复。
修复崩溃:
使用/MDd
编译您的代码并使用调试Qt libs
链接(例如Qt5Cored.lib
使用/MD
编译您的代码并与发布版Qt libs
链接(例如Qt5Core.lib
)
【讨论】:
我在使用 /MTd 标志的 WEC2013 的 Qt 5.6 调试版本中体验到了这一点。使用 /MT 标志编译的发布版本是稳定的。但是,使用 /MD 标志构建的产品几乎可以在一半时间内启动,这是一个惊喜。【参考方案3】:我设法解决了这个问题,但现在我不明白为什么会这样:(我写这个作为答案希望它可以帮助有同样问题的人)
在我的 Qt 项目中,我使用带有 Microsoft Windows SDK for Windows 7 (7.0.7600.16385.40715) (x86) 的工具包作为编译器。当我将编译器更改为 Microsoft Visual C++ Compiler 10.0 (x86) 时,此代码可以正常工作。
正如我所说,我不知道为什么会这样,如果有人可以向我解释这一点,我会很高兴听到。我什至不知道为什么 Windows SDK 被列为编译器。它不是,是吗?
【讨论】:
我遇到了完全相同的错误,但您的解决方案不适用于我的情况。您知道其他解决方案吗? 同样的问题...我发现的唯一解决方法是创建一个新的 QModelIndexList(如果删除此指针,崩溃会再次出现...)“QModelIndexList *indexes = new QModelIndexList(m_listView-> selectionModel()->selectedIndexes());"以上是关于QItemSelectionModel::selectedIndexes() 崩溃的主要内容,如果未能解决你的问题,请参考以下文章