QListWidget index of last inserted row
-
Hi,
I have a simple list with plain text entries and I'd like to offer the ability to add, remove end edit entries in that list. For these simple features, I don't really like to create a
QListView
with a complex model. Instead, I'd like to use aQListWidget
.When the user clicks the
Add
-Button, a new list entry is created with a default text. The aim now is, that this recently added item should immediatelly change to edit mode to allow renaming of the item.This is my code:
this->lwNames = new QListWidget; this->lwNames->setSelectionMode(QAbstractItemView::SingleSelection); this->lwNames->setSortingEnabled(false); connect(this->lwNames, &QListWidget::currentRowChanged, [this]() -> void { this->pbRemove->setEnabled(this->lwNames->currentRow() >= 0); this->pbEdit->setEnabled(this->lwNames->currentRow() >= 0); return;}); connect(this->cbSortMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this->cbSortMode, [this]() -> void { if(this->cbSortMode->currentIndex() > 0) this->lwNames->sortItems(this->cbSortMode->currentIndex() == 1 ? Qt::AscendingOrder : Qt::DescendingOrder); this->lwNames->setSortingEnabled(this->cbSortMode->currentIndex() > 0); return;}); connect(this->pbAdd, &QPushButton::clicked, this->lwNames, [this]() -> void { this->lwNames->addItem(">>new item<<"); this->lwNames->item(this->lwNames->count() - 1)->setFlags(this->lwNames->item(this->lwNames->count() - 1)->flags() | Qt::ItemIsEditable); this->lwNames->setCurrentRow(this->lwNames->count() - 1); this->lwNames->editItem(this->lwNames->currentItem()); return;}); connect(this->pbRemove, &QPushButton::clicked, this->lwNames, [this]() -> void { delete this->lwNames->takeItem(this->lwNames->currentRow()); return;}); connect(this->pbEdit, &QPushButton::clicked, this->lwNames, [this]() -> void { this->lwNames->editItem(this->lwNames->currentItem()); return;});
This stuff works well if
No sorting
is selected in the QComboBox (not shown in the code above). But if the user chooses sorting (e. g. ascending order), the recently added item is, due to its default value, automatically reordered elsewhere, so the code above edits the wrong item (it always edits the last item in the list).So, I was looking for a possibility to catch the index to the last row that was inserted. My google research linked me to
QAbstractItemView::rowsInserted(const QModelIndex&, int, int)
, but there is one ugly problem: it is aprotected
member!So my question is: Is there still any way to get this information of the last inserted row by using a QListWidget or do I really have to use a complete Model/View approach with
subclassing QListView
just to get access to this function?Thank you in anticipation!
Binary -
@Binary91-0 said in QListWidget index of last inserted row:
This stuff works well if No sorting is selected in the QComboBox (not shown in the code above). But if the user chooses sorting (e. g. ascending order), the recently added item is, due to its default value, automatically reordered elsewhere, so the code above edits the wrong item (it always edits the last item in the list).
Sadly it's not written in the QListWidget doc but in the other convenience class: QTableWidget
Disable sorting, add item, do your stuff, re-enable sorting. Or use a proper own model.
-
I'm not sure the newly inserted index is the correct one after sorting, but if you only want the index from
QAbstractItemView::rowsInserted
, I think you can get it fromQAbstractItemModel::rowsInserted
.
It is a signal, hence not protected. (Actually theQAbstractItemView::rowsInserted
is usually connected to, or we can say triggered by,QAbstractItemModel::rowsInserted
)
You should be able to get aQAbstractItemModel
pointer from QListWidget::model(). -
Thank you for your fast reply!
@Christian-Ehrlicher Good to know, thank you for this hint.
@Bonnie Oh nice! You are totally right, connecting my lambda to the model'srowsInserted
signal is possible.I'm not sure the newly inserted index is the correct one after sorting
It works fine! I could imagine that internally,
QListWidget's insert
-method checks if sorting is enabled or not and depending on that, the insertion is done. So therowsInserted
signal has the correct range data.If someone is interested in my approach:
connect(this->lwNames->model(), &QAbstractItemModel::rowsInserted, this->lwNames->model(), [this] (const QModelIndex &index, int iStart, int iEnd) -> void { this->lwNames->item(iStart)->setFlags(this->lwNames->item(iStart)->flags() | Qt::ItemIsEditable); this->lwNames->setCurrentRow(iStart); this->lwNames->editItem(this->lwNames->item(iStart)); return;});
I'm interested in any improvement suggestions.
Thank you for your help.
Binary -
@Binary91-0 said in QListWidget index of last inserted row:
I'm interested in any improvement suggestions.
It seems to work but you're relying on Qt internals so it may not work with other Qt versions.
-
@Binary91-0 said in QListWidget index of last inserted row:
I'm interested in any improvement suggestions.
It seems to work but you're relying on Qt internals so it may not work with other Qt versions.
@Christian-Ehrlicher You mean that in future versions, QListWidget may handle this in a different way so it may for example return an invalid or wrong row index for example? So you'd recommend to bether stop sorting for the moment of interaction? As I can't see any disadvantages, I think I'll do that and stop/restart sorting while inserting the row.