PDA

View Full Version : Remove ownership of QTableWidgetitem from Qtablewidget



deepal_de
5th May 2011, 07:21
Hello,


QList<QTableWidgetItem*> pItemlst = ui->tableWidget->findItems(stext, Qt::MatchContains);

QString stext = search string;

this gives me a list of "QTableWidgetItem*" which have the text "stext". now i need to clear all the items in "tableWidget" and insert only the items in "pItemlst".

When i try to insert give this error
"QTableWidget: cannot insert an item that is already owned by another QTableWidget"

All the "QTableWidgetItem*" items in pItemlst are owned by "tableWidget"...
how can i remove the ownership of those items???\

thank you

ChrisW67
5th May 2011, 07:35
Firstly, how are you going to empty your table widget? If you call clear() to empty your QTableWidget then all the owned items are deleted. This means all your pItemList pointers will be invalid.

To get the QTableWidgetItems out of the QTableWidget and break the ownership then you need to use QTableWidget::takeItem().

deepal_de
5th May 2011, 10:29
thanks for the reply.....

then i have to user a "for" loop to go through each item in my "tableWidget" and crosscheck it with my "pItemlst" know?
the problem is i have about 5000 records to search.

this is a search function that runs on "QlineEdit text change event",
so i was thinking a way to avoid searching all the records since it will take a long time to search and the UI will not respond during this time.

I did consider using a thread.
Q1) is there any other way than thread??

Q2) Is there a way to break the ownership of the QTableWidget and keep the pointers in "pItemlst" intact?

ChrisW67
6th May 2011, 00:48
then i have to user a "for" loop to go through each item in my "tableWidget" and crosscheck it with my "pItemlst" know?
the problem is i have about 5000 records to search.

Don't worry about this too much. How do you think findItems() does it?



this is a search function that runs on "QlineEdit text change event",
so i was thinking a way to avoid searching all the records since it will take a long time to search and the UI will not respond during this time.

Sounds like you are trying to implement a completer. Have you considered QCompleter?

Have you considered using QTableView with a separate data model fed through a QSortFilterProxyModel?

With your QTableWidget approach: Have you considered what happens when the user shortens the string that is being searched for?


I did consider using a thread.
Q1) is there any other way than thread??

See above. Don't complicate things with threads unless you must.



Q2) Is there a way to break the ownership of the QTableWidget and keep the pointers in "pItemlst" intact?
How about:


QList<QTableWidgetItem*> pItemlst = ui->tableWidget->findItems(stext, Qt::MatchContains);
for (int i =0; i < pItemList.count(); ++i) {
QTableWidgetItem* p = pItemlst.at(i);
pItemList[i] = ui->tableWidget->takeItem(p->row(), p->column());
}
// now your list contains the same pointers but owns the items - don't forget to delete our reparent them.
/// You can clear() the table widget.

deepal_de
7th May 2011, 05:32
Thanks....

and a little follow up question...

"ui->tableWidget->takeItem" copy the item in the Qtablewidget to a new pointer right???
in other words...



QTableWidgetItem* pItem = ui->tableWidget->takeItem(p->row(), p->column());

is this same as


QTableWidgetItem* pItem = new QTableWidgetItem*;
pItem->setText( ui->tableWidget->takeItem(p->row(), p->column())->text() );
pItem->setCheckState( ui->tableWidget->takeItem(p->row(), p->column())->text()->checkState() );

does this two have a big difference?? or is it like the same thing....

ChrisW67
7th May 2011, 06:36
Please use
tags around code

No. The first option unparents the item and gives you a pointer to it. There is no copy. After this it is yours to do with as you please.

Your second option fails for several reasons:


QTableWidgetItem* pItem = new QTableWidgetItem*;
// ^^^ will not compile, but you intend to allocate a new item on the heap

pItem->setText( ui->tableWidget->takeItem(p->row(), p->column())->text() );
// ^^^ Copy the text of item pointed to by p into new item.
// Remove item pointed to by p from table.

pItem->setCheckState( ui->tableWidget->takeItem(p->row(), p->column())->text()->checkState() );
// ^^^ Intended to copy the check state of the item pointed at by p: fails
// The row and column of p no longer return the original values because
// *p is no longer in the table. They return -1 and takeItem(-1, -1) returns 0.
// You will get a segfault because you attempt to dereference that null pointer.

In the end you have removed the item from the table, created a corrupt copy, and crashed the program. If you really want to create another copy of the item then use the QTableWidgetItem copy constructor and leave the original in the table.