How do I "move" an item from one QListWidget to another?



  • I have two QListWidget lists, leftList and rightList.

    leftList is populated something like this:

    @// labelList is a QStringList
    foreach (QString label, labelList)
    {
    ui->leftList->addItem(label);
    }@

    I then have a button which is intended to move the selected item in the leftList to the rightList:

    This code IMHO should work but does nothing:

    @void ListManager::on_addButton_clicked()
    {
    QListWidgetItem *widget = ui->leftList->currentItem();
    ui->leftList->removeItemWidget(widget);
    ui->rightList->addItem(widget);
    }@

    However this code works, but is messy and also takeItem(), according to the documentation, doesn't garbage collect the removed item:

    @void ListManager::on_addButton_clicked()
    {
    QListWidgetItem *widget = ui->leftList->currentItem();
    int currentRow = ui->leftList->currentRow();
    ui->rightList->addItem(widget->text());
    ui->leftList->takeItem(currentRow);
    }@



  • @
    void ListManager::on_addButton_clicked()
    {
    QListWidgetItem *widget = ui->leftList->currentItem();
    ui->leftList->removeItemWidget(widget);
    ui->rightList->addItem(widget);
    }@

    Are you sure the widget is not null?
    You said that do nothing, so the item not delete in the leftlist?



  • I had trouble with removeItemWidget too. Use takeItem.



  • If I look at "removeItemWidget":http://doc.trolltech.com/4.7/qlistwidget.html#removeItemWidget it is not stated, whether the item is deleted or not. If you look at the code of QListWidget:

    @
    inline void QListWidget::removeItemWidget(QListWidgetItem *aItem)
    { setItemWidget(aItem, 0); }
    @
    So the meaning for mee looks more than removing an edit widget from an item than removing the item itself. (I think, that's why it's called removeItem Widget).



  • I have checked in the book (C++ GUI Programming with Qt 4) as I have remembered they had similar example. The code there looks like this:

    @void ProjectDialog::moveCurrentItem(ProjectListWidget *source,
    ProjectListWidget *target)
    {
    if (source->currentItem()) {
    QListWidgetItem *newItem = source->currentItem()->clone();
    target->addItem(newItem);
    target->setCurrentItem(newItem);
    delete source->currentItem();
    }
    }
    @



  • That looks much better, thanks for the research VCscala :-)



  • Meantime I was thinking about if it is more easier to prepare a QStringListModel and use a QListView. In this case you can do the moving on the model level.



  • Thas even better I think. But sometimes, model view is a bit oversized...



  • QListWidget is inherited from QListView (similar what we discussed "here":http://developer.qt.nokia.com/forums/viewthread/2524/ about QTableWidget and QTableView), so in every case you have the model, but with Q*Widget classes it is somehow hidden.



  • That's correct, behind the Q*Widgets, there is a QStandardItemModel. But as you have no influence on the model, some things (from my point of view) are more complicated than with model - view (but I'm used to create models).

    But if you look at simple displaying situations, it's more effort needed to create a model than to use a Q*Widget, that's what I meant. But if you need editable view, I would always suggest to go the model - view thing, especially as you have more control over the data.



  • takeWidgetItem only removes the widget of the item which was set with setWidgetItem before. It does not remove the QListWidgetItem itself from the view; this is achieved with takeItem.

    You can safely transfer a QListWidgetItem from on list widget to another:

    @
    void ListManager::on_addButton_clicked()
    {
    if( ui->leftList->count() == 0 )
    // nothing to transfer...
    return;

    QListWidgetItem *widget = ui->leftList->takeItem( ui->leftList->currentRow() );
      ui->rightList->addItem(widget);
    }
    @

    This obviously works only with single selection mode of the list widget. For a multi-item selection mode you will have to do some more work.



  • Thanks Volker. This works and is reasonably "clean" code.

    I still feel the more obvious "remove from left/add to right" approach should work.

    Researching the model-view alternative is on my to-do list ;o)



  • Oh, you still do remove from the left and add to the right. The only difference is that you save yourself from creating a new item with new for the right view and delete item left over from the left view. Instead you just recycle the old one.



  • That sounds like a better alternative than recreate it, gives less memory fragmentation... :-)



  • [quote author="Gerolf" date="1292773031"]That sounds like a better alternative than recreate it, gives less memory fragmentation... :-)[/quote]

    If you do care about memory framgentation Qt is the wrong toolkit for you :)



  • Not always. If you need a UI toolkit that is perhaps cross platform, what else to use? wxWidgets? it's different, but better? I think no. And you can reduce the fragemntation but just don't use some things. The software we are creating is running 24/7 normally. So you should look at such things a bit, and where you can prevent, you should...



  • I successfully used the same "takeItem()" idea to remove an item from the right list and reinsert it at an index one above or one below its old location (ie to reprioritise the item in the list).



  • Perhaps the biggest hole in the Qt environment is the lack of integrated analysis tools, eg for memory leaks, performance analysis. The only option AFAIK is Valgrind.



  • For linux, you use valgrin, for windows, I know no free solution, only commercial ones.
    But for those tools, ther are already threads "here":http://developer.qt.nokia.com/forums/viewthread/2248 and "here":https://developer.qt.nokia.com/forums/viewthread/1924



  • We had a thread "here":http://developer.qt.nokia.com/forums/viewthread/1924 which had discussed the such tools.

    (Sorry for spaming, I was to slow and meantime Gerolf answered the question)



  • [quote author="Jonathan" date="1292788447"]Perhaps the biggest hole in the Qt environment is the lack of integrated analysis tools, eg for memory leaks, performance analysis. The only option AFAIK is Valgrind.[/quote]

    Analysis tools are highly platform dependent, so it would be hard to provide this in a platform independent manner and quality like the Qt libs. I personally am convinced, that it is also out of scope for a toolkit.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.