from PySide import QtCore, QtGui class QListWidget(QtGui.QListView): item_checked = QtCore.Signal(str, bool) def __init__(self, items=[], parent=None): super(QListWidget, self).__init__(parent) self.item_count = 0 self.renameEnabled = False self.item_list_model = None self.item_selection_model = None self.setDragEnabled(True) self.setDragDropOverwriteMode(False) self.setDragDropMode(QtGui.QAbstractItemView.InternalMove) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.createWidgets() for item in items: self.addItem(item) def createWidgets(self): self.item_list_model = QtGui.QStandardItemModel(self) self.item_list_model.setSortRole(QtCore.Qt.DisplayRole) self.item_list_model.dataChanged.connect(self.handleDataChange) self.setModel(self.item_list_model) self.item_selection_model = self.selectionModel() self.setMinimumHeight(60) self.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)) def handleDataChange(self, *args): item = self.item_list_model.item(args[0].row()) self.item_checked.emit(item.data(QtCore.Qt.DisplayRole), True if item.checkState() == QtCore.Qt.Checked else False) def getSelection(self): try: selection = self.item_selection_model.selection().indexes()[0].row() except IndexError: selection = -1 return selection def removeItem(self, index): self.item_list_model.takeRow(index) self.item_count -= 1 def clear(self): while self.item_count: self.removeItem(0) def addItem(self, mitem, data=None, checked=False): item = QtGui.QStandardItem() item.setData(mitem, QtCore.Qt.DisplayRole) if data is not None: item.setData(data, QtCore.Qt.UserRole) item.setEditable(self.renameEnabled) item.setDropEnabled(False) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setCheckState(QtCore.Qt.Unchecked if not checked else QtCore.Qt.Checked) # Can be used to store data linked to the name # item.setData(customData, QtCore.Qt.UserRole) self.item_list_model.appendRow(item) self.item_count += 1 def addItems(self, items, data=None, checked=None): if checked is None: checked = [False] * len(items) if data is None: data = [None] * len(items) for item, check in zip(items, checked): self.addItem(item, data, checked=check) def setUserSelection(self, index): if self.item_count > 0: self.setCurrentIndex(self.item_list_model.item(index).index()) self.selectedItem = self.getItem(index) def getItems(self): return [self.getItem(i) for i in xrange(0, self.item_count)] def getItem(self, index): item = self.item_list_model.item(index) return (str(item.data(QtCore.Qt.DisplayRole)), str(item.data(QtCore.Qt.UserRole)[0]), True if item.checkState() == QtCore.Qt.Checked else False)