View Full Version : QTableWidget+QTableWidgetItem trouble
Fastman
7th November 2007, 14:51
code(QT 4.3.1):
void HSM::setTable()
{
ui.tableWidget->setRowCount(30);
ui.tableWidget->setColumnCount(10);
ui.tableWidget->setHorizontalHeaderLabels(
QStringList() << tr("Task")
<< tr("Time")
<< tr("Group")
<< tr("Object")
<< tr("File")
<< tr("ID_OBJ")
<< tr("State")
<< tr("Prc")
<< tr("ID_SYS")
<< tr("RootPath"));
Items = new QTableWidgetItem(tr("Task"),QTableWidgetItem::Type);
Items->setIcon(QIcon(QPixmap(":/HSM/Resources/Add.png")));
ui.tableWidget->resizeRowsToContents();
ui.tableWidget->resizeColumnsToContents();
}
void HSM::setTableData()
{
for (int row = 0 ; row < ui.tableWidget->rowCount() ;++row)
{
ui.tableWidget->setItem(row,0,Items);
}
ui.tableWidget->resizeRowsToContents();
ui.tableWidget->resizeColumnsToContents();
}
All well works but at closing the app the mistake jumps out.
The mistake occurs here:
d:\qt4\src\gui\itemviews\qtablewidget.cpp
void QTableModel::clearContents()
{
for (int i = 0; i < tableItems.count(); ++i) {
if (tableItems.at(i)) {
tableItems.at(i)->view = 0;
delete tableItems.at(i); <--ERROR
tableItems[i] = 0;
}
}
reset();
}
and tableItems.count() = 300. (10*30 ????)
but i'am have only 30 items !!!
Where at me a mistake. Also what it is necessary to make to correct a code?
jpn
7th November 2007, 15:02
Yes, you do actually have 30*10=300 items. The mistake is that you set the same single item into every cell. You should create a separate item into each cell:
void HSM::setTableData()
{
for (int row = 0 ; row < ui.tableWidget->rowCount() ;++row)
{
QTableWidgetItem* item = new QTableWidgetItem(tr("Task"));
item->setIcon(QIcon(QPixmap(":/HSM/Resources/Add.png")));
ui.tableWidget->setItem(row,0,item);
}
ui.tableWidget->resizeRowsToContents();
ui.tableWidget->resizeColumnsToContents();
}
Fastman
7th November 2007, 15:07
i'am stupid :)
Thx !
Fastman
9th November 2007, 09:42
Yes, you do actually have 30*10=300 items. The mistake is that you set the same single item into every cell. You should create a separate item into each cell:
void HSM::setTableData()
{
for (int row = 0 ; row < ui.tableWidget->rowCount() ;++row)
{
QTableWidgetItem* item = new QTableWidgetItem(tr("Task"));
item->setIcon(QIcon(QPixmap(":/HSM/Resources/Add.png")));
ui.tableWidget->setItem(row,0,item);
}
ui.tableWidget->resizeRowsToContents();
ui.tableWidget->resizeColumnsToContents();
}
Whether there will be memory leak if function setTableData () is caused in me each 5 seconds for display of changes in the table?
jpn
9th November 2007, 09:49
No, that shouldn't leak memory since QTableWidget deletes the old item if you set a new item into cell. But you definitely don't want to re-create all the items every time in setTableData(). Create the items once in constructor or so, and just set the data in setTableData():
QTableWidgetItem* item = ui.tableWidget->item(row, col);
item->setSomething(...);
Fastman
9th November 2007, 10:41
No, that shouldn't leak memory since QTableWidget deletes the old item if you set a new item into cell. But you definitely don't want to re-create all the items every time in setTableData(). Create the items once in constructor or so, and just set the data in setTableData():
QTableWidgetItem* item = ui.tableWidget->item(row, col);
item->setSomething(...);
Hmm... not work :(
class HSM : public QDialog
{
Q_OBJECT
...
...
...
private:
QTableWidgetItem* itemArchive;
QTableWidgetItem* itemRestore;
QTableWidgetItem* itemDelete;
...
...
...
HSM::HSM(QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags)
{
...
...
...
itemArchive = new QTableWidgetItem(tr("Archive"));
itemRestore = new QTableWidgetItem(tr("Restore"));
itemDelete = new QTableWidgetItem(tr("Delete"));
...
...
...
void HSM::setTableData()
{
sTskInfoGUI sTaskGUI;
db_work db;
sTaskGUI = db.GetTaskToGUI();
db.CloseDB();
for (int row = 0 ; row < sTaskGUI.nCmd.size() ;++row)
{
if (sTaskGUI.nCmd.at(row) == 1)
{
itemArchive = ui.tableWidget->item(row,0);
itemArchive->setIcon(QIcon(QPixmap(":/HSM/Resources/archive.png")));
itemArchive->setBackground(QColor::fromRgb(200,255,104,100));
//ui.tableWidget->setItem(row,0,itemArchive);
}
if (sTaskGUI.nCmd.at(row) == 2)
{
itemRestore = ui.tableWidget->item(row,0);
itemRestore->setIcon(QIcon(QPixmap(":/HSM/Resources/restore.png")));
itemRestore->setBackground(QColor::fromRgb(115,150,255,100));
//ui.tableWidget->setItem(row,0,itemRestore);
}
if (sTaskGUI.nCmd.at(row) == 3)
{
itemDelete = ui.tableWidget->item(row,0);
itemDelete->setIcon(QIcon(QPixmap(":/HSM/Resources/del.png")));
itemDelete->setBackground(QColor::fromRgb(255,100,120,100));
//ui.tableWidget->setItem(row,0,itemDelete);
}
...
...
...
Exception in code :
d:\qt4\src\gui\itemviews\qtablewidget.cpp
inline void QTableWidgetItem::setIcon(const QIcon &aicon)
{ setData(Qt::DecorationRole, aicon); }
jpn
9th November 2007, 10:49
QTableWidget::item() returns 0 which means there is no item in such cell and so you are dereferencing a null pointer. Did you actually call QTableWidget::setItem() anywhere?
itemArchive = new QTableWidgetItem(tr("Archive"));
itemRestore = new QTableWidgetItem(tr("Restore"));
itemDelete = new QTableWidgetItem(tr("Delete"));
ui.tableWidget->setItem(0,0,itemArchive); // <--
ui.tableWidget->setItem(1,0,itemRestore); // <--
ui.tableWidget->setItem(2,0,itemDelete); // <--
Fastman
9th November 2007, 11:28
QTableWidget::item() returns 0 which means there is no item in such cell and so you are dereferencing a null pointer. Did you actually call QTableWidget::setItem() anywhere?
itemArchive = new QTableWidgetItem(tr("Archive"));
itemRestore = new QTableWidgetItem(tr("Restore"));
itemDelete = new QTableWidgetItem(tr("Delete"));
ui.tableWidget->setItem(0,0,itemArchive); // <--
ui.tableWidget->setItem(1,0,itemRestore); // <--
ui.tableWidget->setItem(2,0,itemDelete); // <--
no effect :(
Exception in code :
d:\qt4\src\gui\itemviews\qtablewidget.cpp
inline void QTableWidgetItem::setIcon(const QIcon &aicon){ setData(Qt::DecorationRole, aicon); }
jpn
9th November 2007, 11:48
There are 3 places in your code in which you pick an item at certain cell:
...
itemArchive = ui.tableWidget->item(row,0);
...
itemRestore = ui.tableWidget->item(row,0);
...
itemRestore = ui.tableWidget->item(row,0);
...
On the other hand, you have created an item only into cells (0,0), (1,0) and (2,0). If "row" is anything else than 0-2, you'll get a crash. This is most likely the case of yours.
Fastman
9th November 2007, 13:18
Ok :) Thx for you help :)
jpn
9th November 2007, 17:42
Let me correct one thing. I just re-read my previous message and I want to make sure I don't get misundestood. Of course, calling QTableWidget::item() with any possible parameters doesn't cause a crash:
QTableWidgetItem* item = tableWidget->item(1234, 5678);
But the point is that in case no item exists in such cell, QTableWidget::item() returns 0. Then, dereferencing a null pointer is what causes the crash:
item->setSomething();
Fastman
9th November 2007, 18:06
How to make so that last column it was leveled by a right edge of the table ?
void HSM::setTableData()
{
sTskInfoGUI sTaskGUI;
db_work db;
sTaskGUI = db.GetTaskToGUI();
db.CloseDB();...
...
...
itemRootPatch->setText(sTaskGUI.cRootPath.at(row));
ui.tableWidget->setItem(row,9,itemRootPatch);
}
ui.tableWidget->resizeRowsToContents();
ui.tableWidget->resizeColumnsToContents();
}
Here so my form looks.
jpn
9th November 2007, 18:24
You can either use QHeaderView::setResizeMode() and pass QHeaderView::Stretch:
ui.tableWidget->horizontalHeader()->setResizeMode(10, QHeaderView::Stretch);
Or you can use a "shortcut" (which QTreeView uses by default):
ui.tableWidget->horizontalHeader()->setStretchLastSection(true);
Fastman
10th November 2007, 12:19
many Thx ! :)
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.