Access violation: QTreeWidgetItem

Started by
6 comments, last by .chicken 9 years, 7 months ago

Hello again!

I'm creating a QTreeWidgetItem in my application, and from there I want to extract data on the push of a button to create a custom object.

Adding stuff to my TreeWidget works just fine:


	QTreeWidgetItem* item;
	if (!hasRoot) {
		item = new QTreeWidgetItem();
		tree->addTopLevelItem(item);
		effectiveStacks = stacks->value();
	}
	else {
		item = new QTreeWidgetItem();
		tree->selectedItems()[0]->addChild(item);
		tree->selectedItems()[0]->setExpanded(true);
	}
	
	item->setText(0, actionBox->currentText());
	item->setText(1, playerBox->currentText());
	item->setText(2, QString::number(sbCIPSpin->value()));
	item->setText(3, QString::number(bbCIPSpin->value()));
	item->setText(4, boardEdit->text());
	item->setText(5, QString::number(effectiveStacks));
	item->setText(6, QString::number(counter));

Now, when I want to iterate over the items and extract data, but even when I try to do something as simple as:


QTreeWidgetItemIterator iter(tree);
	
	QString text = (*iter)->text(3);

I get an access violation inside qtreewidget.h in the text(int column) method. I really tried everything and I believe I'm messing up pointers, since I'm really inexperienced with them.

Could someone explain to me, what is going on here?

Thanks in advance.

Advertisement

Are you sure the iterator is valid when you dereference it?


QTreeWidgetItemIterator iter(tree);
    if (*iter)
      QString text = (*iter)->text(3);

Qt indicates the end of an iteration (or an empty range) by having the iterator become invalid, as in a dereference operation evaluates to false.

Stephen M. Webb
Professional Free Software Developer

Well I havent even done anything with the iterator before I call the


(*iter)->text(3);

So I don't understand why it isn't valid. I might consider implementing the if-clause, but that won't help if I canÄt get ANY data out of it then :/

Your code looks okay. Can you post a minimal program that exhibits the issue (just the MainWindow.cpp will do).

Not sure how to provide a minimal program, because of all the dependencies. I'll try to explain where I use the function in more detail those, hope that helps:

I got my main class called "Equilibrizer", which has a Pointer to my DecisionTreeWidget.


class Equilibrizer : public QMainWindow
...
private:
   DecisionTreeWidget* tree_w;

The tree_w is initialized in the constructor of Equilibrizer. Now on the click of a button, the method where I get the error is called.


DecisionTree decTree(tree_w->getDecTree());

Right now, getDecTree() looks like the following:


DecisionTree DecisionTreeWidget::getDecTree() {
	
/* Here I just tried different things in hopes of avoiding that error, nothing worked so far */
	QTreeWidgetItemIterator iter(tree);
	QString text = (*iter)->text(3);
	std::cout << tree->topLevelItem(0)->text(1).toStdString() << std::endl;
/*********/

	holdemBoard b;
	string2board(tree->topLevelItem(0)->text(4).toStdString(), &b);
	DecisionTree result(effectiveStacks, DecisionPt(string2player(tree->topLevelItem(0)->text(1).toStdString()),
		tree->topLevelItem(0)->text(2).toFloat(),
		tree->topLevelItem(0)->text(3).toFloat(),
		EquityArray(b),
		string2action(tree->topLevelItem(0)->text(0).toStdString())));

	for(int i=1; i<tree->topLevelItemCount(); i++) {
		string2board(tree->topLevelItem(i)->text(4).toStdString(), &b);
		result.addDecPt(DecisionPt(string2player(tree->topLevelItem(i)->text(1).toStdString()),
			tree->topLevelItem(i)->text(2).toFloat(),
			tree->topLevelItem(i)->text(3).toFloat(),
			EquityArray(b),
			string2action(tree->topLevelItem(i)->text(0).toStdString())),
			tree->topLevelItem(i)->text(6).toInt());
	}
	return result;
}

So, it doesn't matter if I use the Iterator, or call the topLevelItem directly, everything gives me the same access violation error.

Lastly, this is the way I add content to the tree, which (at least from the looks of it) works fine.


void DecisionTreeWidget::addChild() {
	QTreeWidgetItem* item;
	if (!hasRoot) {
		item = new QTreeWidgetItem();
		tree->addTopLevelItem(item);
		effectiveStacks = stacks->value();
	}
	else {
		item = new QTreeWidgetItem();
		tree->selectedItems()[0]->addChild(item);
		tree->selectedItems()[0]->setExpanded(true);
	}
	
	item->setText(0, actionBox->currentText());
	item->setText(1, playerBox->currentText());
	item->setText(2, QString::number(sbCIPSpin->value()));
	item->setText(3, QString::number(bbCIPSpin->value()));
	item->setText(4, boardEdit->text());
	item->setText(5, QString::number(effectiveStacks));
	item->setText(6, QString::number(counter));

	tree->setItemSelected(item, true);
	tree->setItemSelected(item->parent(), false);

	hasRoot = true;
	counter++;
}
Sorry, never mind.

Not enough info to diagnose here.

Usually I've used QTreeWidgetItemIterator like this without any problems:


QTreeWidgetItemIterator it(treeWidget);
while(*it)
{
    (*it)->something();
    ++it;
}

Are you deleting them items somewhere in your code? Remember that QTreeWidgetItems are not QObjects and one must safely delete (remember to set to null) them manually. Your hasRoot logic seems a bit odd. QTreeWidget has a default invisible root item (QTreeWidget::invisibleRootItem()) by default to which all top-level items are added.

Edit: Oh my god...while I initialized the right widget, I added the wrong one to my layout, thats why I got the errors. Sorry for troubling you guys with that :/ Thanks for all the replies!

This topic is closed to new replies.

Advertisement