Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Items in QListView

Tags:

python

pyqt

pyqt4

I'm (very) new to PyQT and QT in general and have to quickly design a user interface that's broadly similar to modern 2-pane mail apps: left a list of mails, right an editor. I'd like to give a little more information than just a String to display in the QListView -- basically the items name in bold text, below two lines with description in a different style, and on the top left a set of tag-like badges. Furthermore, the list will have to update every few seconds or so (likely with only changes to very few items), so I don't want to rewrite the data every time.

From what I read in the various manuals and tutorials, there are different ways of accomplishing that, and I'm unsure what the most commonly used method is (other people will have to work with the code once I drafted the core app) - which objects and methods would you use -- QListView or QListWidget, and then subclassing QAbstractListModel or QStandardItemModel, ...?

like image 833
Manuel Ebert Avatar asked Nov 23 '11 18:11

Manuel Ebert


2 Answers

If you dont want to think about your model, or really share is between views, then a QListWidget is meant for that purpose. You just deal with the List directly and the data is stored in its own underlying model. For a QListWidget, you can use: QListWidget.setItemWidget(QListWidgetItem item, QWidget widget) That would entail you creating your own widget that looks the way you want, having QLabels for your text and pixmap displays. Then you would add them to the QListWidget by doing:

# create item widget
item = QListWidgetItem()
w = CustomItemWidget()
w.setTitle = "Title"
w.setDescription = "Blah blah"
# would have a QPixmap already cached
w.setBadgeImage = preCreatedPixmaps['thisBadge']  
listWidget.insertItem(item)
listWidget.setItemWidget(item, w)

The plus side is that you can control the look of the items pretty simply without having to write a more complicated delegate. The downside to this approach is that you don't really share the model with another view and you have to manage creating widgets when new items need to be added. And this method assumes the widget displays will be static. They dont like to be changed after they are set. It can also be slower if you have thousands of them.

Creating a Delegate for your items in a QListView is a faster approach from a performance standpoint, but a little more technical...

See here for an example (though its in C++ but easy to understand http://www.qtcentre.org/threads/27777-Customize-QListWidgetItem-how-to?p=131746#post131746

Another example in python, though the code has no tab indents: http://www.qtcentre.org/archive/index.php/t-31029.html

like image 90
jdi Avatar answered Oct 12 '22 13:10

jdi


If the users aren't manually changing the data in the list of mails, then you can easily use one of the model classes with a custom QStyledItemDelegate (or QAbstractItemDelegate). Take a look at the example in the QAbstractItemDelegate documentation linked above as well as the Star Delegate example.

If the users do need to change the data inline in the list of mails, and the list of e-mails is sufficiently different from standard widgets, it becomes quite a bit more difficult to make sure the editor looks sufficiently similar to the presentation view. It's not impossible, but that's one of the harder pieces.

You could get away with using a QStandardItemModel. But... I generally recommend creating a domain model with a Qt (in your case, QAbstractListModel) wrapper for anything non-trivial.

like image 25
Kaleb Pederson Avatar answered Oct 12 '22 13:10

Kaleb Pederson