Elfayer
Elfayer

Reputation: 4561

Qt4 - How to add a row in a QTableWidget when sorting is enable?

I have a QTableWidget with which I can add rows by pushing a button. The problem is that I have _table->setSortingEnabled(true);, and when I'll insert a new row, I won't know where it is. Because since I have set the table sortable, when I add a row, this row will move to it's position (depending on which column is sorted). How can I know which one it is then?

Example with one column (Name) sorted by alphabetical order:

Name |
------
abc
toto
zozo

If I now add a row like follow :

int newRow = _table->rowCount();

_table->insertRow(newRow);

QTableWidgetItem *item1 = new QTableWidgetItem;
item1->setText("boom");
_table->setItem(newRow, 0, item1);

The row will go between 'abc' and 'toto'.

Name |
------
abc
     <<< boom
toto
zozo

Here it'll work properly, but I have multiple columns and if now I try for example:

QTableWidgetItem *item2 = new QTableWidgetItem;
item1->setText("45");
_table->setItem(newRow, 1, item2);

The value that'll change is the value of the second column of 'zozo' and not the one I want, 'boom'.

I tried to explain with an example the problem, I hope it helped. So how can I add a new row, set it's text for each of its column if I have the sorting enable on my QTableWidget ?

Edit : Answer from nonexplosive (in the comments) :

Just need to do like follow for the second QWidgetItem :

QTableWidgetItem *item2 = new QTableWidgetItem;
item1->setText("45");
_table->setItem(item1->row(), 1, item2); // change newRow by item1->row()

Upvotes: 2

Views: 5082

Answers (3)

Steve Lorimer
Steve Lorimer

Reputation: 28659

First you need to insert a new row using rowCount

int row = table->rowCount();
table->insertRow(row);

Then for the first QTableWidgetItem you need to call QTableWidget::setItem(row, item) with the rowCount

table->setItem(row, item);

For subsequent QTableWidgetItems, you use QTableWidgetItem::row() from the first QTableWidgetItem, which may have moved due to sorting

table->setItem(first_item->row, item);

Here is an example of calling QTableWidget::setItem(row, item) from within a loop, where you use row when index == 0 and item[0] when index != 0:

void App::onAddRow()
{
    std::vector<QTableWidgetItem*> items;

    items.push_back(new QTableWidgetItem("foo"));
    items.push_back(new QTableWidgetItem("bar"));
    items.push_back(new QTableWidgetItem("baz"));
    items.push_back(new QTableWidgetItem("bang"));

    int row = table->rowCount();
    table->insertRow(row);

    for (size_t i = 0; i < items.size(); ++i)
    {
        table->setItem(i == 0 ? row : items[0]->row(), i, items[i]);
    }
}

Upvotes: 0

jayatubi
jayatubi

Reputation: 2202

You may need to disable sorting, via setSortingEnabled(false), before inserting and re-enable it after you finish.

Upvotes: 2

Aleksandar
Aleksandar

Reputation: 3661

Create hidden column that will contain id of every row, so when you add row just use void QTableWidget scrollToItem (const QTableWidgetItem *item , QAbstractItemView::ScrollHint hint=EnsureVisible ) to scroll table to that row.

Scrolls the view if necessary to ensure that the item is visible. The hint parameter specifies more precisely where the item should be located after the operation.

Once you have row id, you can also change color of the new row (cell by cell) with void QTableWidgetItem::setBackground ( const QBrush & brush ) until next new row is added.

Doing both of those suggestions will ensure that newly added row is visible to you.

Upvotes: 1

Related Questions