Using QWidget as a QListView Item
-
I'm currently developing a desktop app using PyQt. As the titles states I'm trying to create a QListView and populate the list using QWidgets as items.
@"""
INPUT: data received from QItemDelegate
OUTPUT: QWidget representation of data
"""
class ListItem(QtGui.QWidget):def __init__(self, *args): QtGui.QWidget.__init__(self, *args) self.ui = Ui_ListItem_widget() self.ui.setupUi(self) self.Name = self.ui.Name_label self.icon = self.ui.icon_label def setData(self, Name, iconDir): # set label text # set icon images
"""
Sends data to QWidget and populates it.INPUT: object
OUTPUT: QWidget populated with object data
"""
class ItemDelegate(QtGui.QItemDelegate):def __init__(self, parent=None, *args): QtGui.QItemDelegate.__init__(self, parent, *args) self._itemWidget = ListItem() # This is where I get stuck. # How would I use QItemDelegate to draw a QWidget as a list item? def paint(self, painter, option, index): painter.save() self._itemWidget.setData(#Data to send goes here) painter.restore()
"""
Model for views.mainwindow._listview
Represents the list as a wholeINPUT: a list of objects
OUTPUT: ListView of objects
"""
class ListModel(QtCore.QAbstractListModel):def __init__(self, objs=[], parent=None): QtCore.QAbstractListModel.__init__(self, parent) self._objs = objs def data(self, index, role): if role == QtCore.Qt.DisplayRole: row = index.row() value = self._objs[row] return value def rowCount(self, parent): return len(self._objs)@
I know this can be done with a QListWidget but I would rather use a MVP approach. The main problem I'm having is drawing the widget using the QItemDelegate. When I run my code I dont get errors but nothing show's on the screen.
I know I have to implement the sizeHint() method and the paint() method but the documentation is confusing when it comes to these two (since they can be used for much more, I find it to be very general)P.S. I can somewhat understand C++ when it comes to Qt so code examples in C++ are fine.
-
your item-delegate's paint method doesn't paint anything.
Should your widgets in the list view provide interaction? Or should they just be painted/rendered (e.g. labels, ...)? -
[quote author="raven-worx" date="1368786757"]your item-delegate's paint method doesn't paint anything.
Should your widgets in the list view provide interaction? Or should they just be painted/rendered (e.g. labels, ...)?[/quote]The ListItems should provide interaction as I plan to add buttons and editors, though for right now I only have mostly a skeleton.
I dont know how to properly implement the paint() method so that I can draw a QWidget using index.data() or by passing index.data to the widget before drawing. -
well when you just paint them there wont be any interaction possible ;)
Your possibilities:
implement "QstyledItemDelegate::createEditor()":http://qt-project.org/doc/qt-4.8/qstyleditemdelegate.html#createEditor and return your widget there and "enable edititing":http://qt-project.org/doc/qt-4.8/qabstractitemview.html#edit on all items in the list-view
use "QAbstractItemView::setIndexWidget()":http://qt-project.org/doc/qt-4.8/qabstractitemview.html#setIndexWidget
Which raises up a question in my mind. Why do you use a QListView in first place? Is your ListView just displaying the widgets and nothing more?
If so you should use a simple QScrollArea and place a simple QWidget inside it. This widget arranges all your widgets with a layout as a "list". -
Thanks for the help! I was reading up in setIndexWidget() earlier but wasnt sure if that was what I wanted.
Also, from what I had read you wouldn't be able to add button signals or editors without using the QListView. I tried using QScrollArea earlier and it didn't seem to have that functionality but I admit I didn't look much into.
I guess I'm just used to always using QListViews and Models at this point :)
Thanks again -
[quote author="cogdissonance" date="1368789964"]Also, from what I had read you wouldn’t be able to add button signals or editors without using the QListView[/quote]
please show me the text where you read that! :)