setItemWidget should come with a huge warning about it being the wrong solution in 90% of the cases.
What you need is a QStyledItemDelegate.
use QListWidgetItem::setData to store your text, image and color in 3 different roles (Qt::EditRole, Qt::DecorationRole and Qt::UserRole appear to be the most natural choices)
then subclass QStyledItemDelegate and reimplement paint (you can find Qt's implementation here to use as a starting point)
finally just call QListWidget::setItemDelegate to assign the delegate to the view
Well seems that it needs to emit model's layoutChanged() to do what I need. I created new class which inherits QListWidget and there I connected signal to layoutChanged signal of model() object and it worked.
Finally... After few docs and experiences, I don't know how but I missed the fact that QWidgets are not reentrant (thanks to @kshegunov), and I also missed the fact that signals and slots are made for that.
@SGaist So, thanks for your advices but doing real MVC made my app too complicated for what it does. In a more constructed project, I would do what you suggested. I've simplified mine:
Choose your "root" directory
The Crawler crawls (recursively in Qt::Concurrent) and send a signal when the QFileInfo::fileName().length() is more than x characters
A slot in the MainWidget adds the item in the QListWIdget
That's all for now (auto-rename for later), so few lines of code. Thank you for your advices.
No problem. If you've edited the Qt sources fixing the bug, and have the time, you could also submit that patch through the gerrit code review, although it requires some work to clone/setup the repository.
It is not the iterator that is the problem. From your example:
for ( QList<QListWidgetItem*>::iterator iter = selectedItems().begin(); iter != selectedItems().end(); iter++ )
qDebug() << (*iter)->text();
The functions 'selectedItems().begin()' and 'selectedItems().end()' are the problem. Each time you call 'selectedItems()' a copy of QList<QListWidgetItem*> array is returned. Since you call it twice you have two different copies. The contents of the list may be the same but they are two different lists.
QString input_text(" some text for input ");
QString text = input_text.simplified().trimmed().mid(1);
In order to have the second line work a QString is constructed (and destroyed) for each step as a copy constructor. The QString member 'simplfied()' returns an unnamed instance of a new copy of QString after performing whatever 'simplfied()' does. The member 'trimmed()' is then called from this new QString creating another unnamed instance which finally calls member 'mid(1)'. The final variable 'text' is assigned from the last member function of the unnamed instance of QString. If the last member was '.toInt()' it would return an integer instead (which won't compile unless the assigned variable is changed to an integer (or acceptes an integer as a constructor)).
The output from the above example is "ome text for input" if you are curious.
The member function QListWidget::selectedItems(void) might looks something like this:
QList<QListWidgetItem*> QListWidget::selectedItems(void) const
list.push_back(<figure out what is selected>);
You end up calling this function twice and therefore you have two different lists as you would expect (returned values from the same function will each have a unique instance). Your loop starts on the beginning of the first list and ends on the last item of the second list. It is very likely they are not sitting next to each other in memory so after the first list is traversed you are running over unknown memory (which is where your segfault comes from).
You need to be careful about copy constructors (when they are created). For example, your 'for' loop uses the postfix operator 'iter++'. For simple variables (integers) this is not a problem but if you have a complex iterator calling the postfix version will be expensive at it creates a copy. A better form is to use the prefix operator '++iter' as no copy is created.
Hi when you add "xxxx" to a qlistwidget
you are adding a QListWidgetItem.
While you can subclass QListWidgetItem and make your own
that has signals, it would not do you so much good as
it would never never emit such signal unless you also made it do
so when something happen to it. (overriding some of its functions)
So It all depends what you are trying to do.
If you just want to know its no 1,2,3 etc, even if moved
you can insert that info into the QListWidgetItem using the
void QListWidgetItem::setData(int role, const QVariant & value)
QListWidgetItem * item=new QListWidgetItem("item1") ;
item->setData(Qt::UserRole, 1); // or 2 for item 2 etc
@Chris-Kawa I have fixed it, you're right. it is something else in my code.
i just found and realized it when another part of my program is showing the problem, this time the problem is showing more detailed so i managed to find out.
Then it's just a matter of removing from the list items that are already added. Something like this:
//get the list from somewhere
QStringList fileNames = ...
//remove the temp item you mentioned
//remove the items already in the widget
int numItems = listWidget->count();
for(int i = 0; i < numItems; ++i)
//now that the list is "clean" all there is left to do is add the new items
For checkboxes I think you must have set Qt::ItemIsUserCheckable flag for QListWidgetItem. So there's a way to do so. But for radiobutton theres none and thus have to create the widget explicitly.