@Ratzz Sorry i can not check your answer as solved answer, Qt forum has a bug about that. I solved my problem, i've already read the topic that you linked here but after you posted it then a read again and i solved my problem thank you, but even so trying to give more explanatory answers is a good way because i like this forum and i want to see answers from another angles, another perspectives. When i get experienced at Qt i want to give good answers too. :)
And thank you so much Mr. @dheerendra . I think approach with row is a better way but i was need to a quick way so that stackoverflow link helped me about that.
@nebulaekg It wasn't wrong, it was just the easy method. With easy comes very little customization. Now that you want to change it's behavior it becomes much harder. For simple lists you can definitely use the widget but for anything more you want a view/model and then delegates to control display.
Check into it I'm sure you'll find it's not that much harder than the widget and will give you the control you want. :)
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