Solved No simple QListWidget "items()" member?
-
I am using
QListWidget
. (My observation might also concern theQListView
orQAbstractItemView
it's derived from, or possibly other multi-item-widget-types.)There are a couple of member methods which return a
QList<QListWidgetItem *>
---selectedItems()
,findItems()
, and a protecteditems(const QMimeData *data) const
--- but no simple, plainitems()
which just returns a list/collection of all the items.I use Python/PyQt, but I think the issue is the same in C++. I find this irritating for iterating:
for (int row = 0; row < listWidget.count(); row++) { QListWidgetItem *item = listWidget.itemAt(row); ... }
when I'd like to use a Python
for item in listWidget.items()
, and there's no member to pass to other code for just the items (without the widget).Given the usually comprehensive set of Qt methods/members, why is this absent, am I the only person who finds this lacking? Or, am I perchance supposed to get all the items some other way...?
-
Not as concise as an
items()
method but does this work for you:for (auto item : listWidget.findItems("*", Qt::MatchWildcard){ //do something with each item }
-
@mchinand
Sorry --- and I don't want to sound rude/ungrateful, I don't mean it like that --- it may work, but doing a "findItems
-with-wildcard-match-method" is not what I had in mind/acceptable when what I want is just the list of items it contains. I have no desire to have code which inspects the items. Its lack seems like a surprisingly inconvenient omission to me. -
That's understandable. You can subclass QListWidget and add your own methods.
-
Why you want a List of that Items? The QListWidget is a List of Items. If you want a second List just copy QListWidget in another QListWidget. Sorry but i dont get it maybe
-
An API that returns all items of a model would be asking for trouble. With
QListView
andQAbstractItemView
this is a very very bad idea. In your particular case it might be fine, but imagine a model connecting to a remote database with millions of items (GBs of transfer). A single call toitems()
could grind it to a halt or even crash it. Also there are "infinite" models that generate more and more data (see canFetchMore() method). In this case the whole set might not even be known at any given time.
ForQListWidget
this would also be a heavy performance hit. Imagine a list of few thousands elements - generating that list (allocating and populating the list) every time someone callsitems()
would be terrible for performance.
selectedItems
andfindItems
are fine(ish), because they are designed to return a small subset of the whole thing. Even with them, if you use them naively you can kill performance. -
@Fuel
Becauseitems()
is a perfectly obvious method to supply with aQListWidget
, or indeed any widget which encapsulates a list of items. There is no need for behind-the-scenes code to inspect each item to see if its text matches a wildcard in order to just return the list of items.If that is what is on offer, I will accept I don't have an
items()
method and just iterate viarow
index as I am already.I don't wish to get into a disagreement with anyone about their opinion versus mine, I was just surprised that nobody else wanted this method years ago.
-
@Chris-Kawa said in No simple QListWidget "items()" member?:
An API that returns all items of a model would be asking for trouble. With
QListView
andQAbstractItemView
this is a very very bad idea. In your particular case it might be fine, but imagine a model connecting to a remote database with millions of items (GBs of transfer). A single call toitems()
could grind it to a halt or even crash it. Also there are "infinite" models that generate more and more data (see canFetchMore() method). In this case the whole set might not even be known at any given time.
ForQListWidget
this would also be a heavy performance hit. Imagine a list of few thousands elements - generating that list (allocating and populating the list) every time someone callsitems()
would be terrible for performance.
selectedItems
andfindItems
are fine(ish), because they are designed to return a small subset of the whole thing. Even with them, if you use them naively you can kill performance.That makes Sense.
-
@Chris-Kawa
OK, at least your explanation makes sense to me.Yes, because it's a
QListWidget
--- a list of a few items to pick from --- they are in-memory for me. I had not thought about attaching it to a database.I also take your point about
selectedItems
/findItems
being intended "to return a small subset" (though not forfindItems("*", Qt::MatchWildcard)
)!I come from a .NET background. I have written a Qt-equivalent
CheckBoxList
. The .NETCheckBoxList
,RadioButtonList
and other such controls all have anItems[]
member of the items. Of course, there are not intended to be 1,000 items, and the architecture is quite different, in that you populate the list, not have a dynamic hook to an on-going database query.I appreciate the explanation, and understand that I am not missing some method I was unaware of now.
Thank you.
-
Iterating over an entire list is not something you should be doing often (again - performance considerations). Depending on what you're actually doing in that loop you may consider adding a specialized method for that on the model.
Iterating like you did in the example is the safest (performance wise) API that can be made, because it's your responsibility to judge how much is too much. As for the .NET equivalents... well, that's the contrast with c++. Here you don't pay for what you don't use.If you find yourself doing that often you can consider creating a helper class that will give you begin/end iterators so that you can write something like:
for (QListWidgetItem* item : wrapper(listWidget)) { //do something with item }
-
@Chris-Kawa said in No simple QListWidget "items()" member?:
If you find yourself doing that often you can consider creating a helper class that will give you begin/end iterators so that you can write something like:
for (QListWidgetItem* item : wrapper(listWidget)) { //do something with item }
Unfortunately, in addition to being a Qt newcomer, I am having to program in Python, which is equally new to me. So my chances of figuring "begin/end iterators" code in Python are probably limited... :) I wish I could have my C# back ;-)
-
items()
is a terrible API, and if you miss it I'd say it's a withdrawal syndrome ;) C# is just giving you (syntactic) sugar and hiding the big performance cost. Yeah, to some ignorance is bliss, but don't you rather be able to decide for yourself what you want to pay? C++ lets you do that, but, as with all decision making, it's a little bit more work. As for Python... well, it's another sugar pill :P -
items() is a terrible API
No, it isn't. I asked (or was thinking of) in the context of a control like a checkbox list or a radiobutton list. These are obviously intended to have a "limited" number of items, in the same sense as you pointed out for, say,
selectedItems()
. Like 10, or 20. And the model is pre-populated.Now that you have explained how the Qt model-view architecture which
QListWidget
is using can be tied to a database or dynamic generation of items I ahve said I do see the point of why it is not suitable in that context.BTW, I believe I see that the same principle applies to
QComboBox
--- there is noitems()
collection/list --- so I also see this is consistent across Qt widgets. -
items() is a terrible API
No, it isn't
Right. In specific cases it might be benign. I should rather have said it would be a terrible API in a generic class, like QListWidget.
Easy enough to add it in a derived (specialized for your case) class. -
@Chris-Kawa
Yes, thanks, I get that now. As I said, until you explained I had not been thinking in terms of the genericicity(?) of the Qt model-view architecture for these widgets. It's a different approach from .NET, for me.P.S.
OOI, I just looked a MFC CComboBox class (https://msdn.microsoft.com/en-us/library/12h9x0ch.aspx) and I see that like Qt it does not have aGetItems()
(in fact, it does not even seem to have aGetItem(index)
from what I can see, which is bit worrying, at least Qt hasitemText(index)
!) So I am beginning to see that ASP.NET (it's that, rather than C# itself, which is providing access to the "Items" collection), which I have grown used to, has been allowing me to program more conveniently than I had appreciated, and I love it even more ;-) (But Qt is good too!)