correctly manage sizeHint for item in delegate with custom editor
-
Hello,
I have a listview with a delegate for a custom editor for managing the items custom data. I simplified this example so the editor for now is two line edits and a push button, so the editors height is bigger than the default items height.I've manage to get a 'sortof' working solution, but I think there is a better way to mange then sizeHint as i'm hard coding it and storing a items editing state on the item data.
-
Is there a better way in the sizeHint to test if a item is currently being edited? I'm having to store a bool and manage that for each item.
-
Is there a way to get an item's minimum size (the size when the listview first creates it), so I dont have to hard code it scale back down after editing.
If there is a better way please let me know to manage a custom editors size. I saw the updateEditorGeometry function aswell, but wasn't sure i needed to implement that
Cheers.
import sys from collections import namedtuple from PySide2 import QtGui, QtCore, QtWidgets from PySide2.QtCore import Qt __custom_roles = dict(title = Qt.UserRole + 1, description = Qt.UserRole + 2, cur_state = Qt.UserRole + 3) CustomRoles = namedtuple('CustomRoles', __custom_roles.keys())(*__custom_roles.values()) class Editor(QtWidgets.QWidget): editingFinished = QtCore.Signal() def __init__(self, parent=None): super(Editor, self).__init__(parent) print('EDITOR CREATED') self.title_edit_le = QtWidgets.QLineEdit() self.description_edit_le = QtWidgets.QLineEdit() self.close_editor_pb = QtWidgets.QPushButton('close editor') v_layout = QtWidgets.QVBoxLayout() v_layout.setContentsMargins(0,0,0,0) v_layout.addWidget(self.title_edit_le) v_layout.addWidget(self.description_edit_le) v_layout.addWidget(self.close_editor_pb) self.setLayout(v_layout) self.close_editor_pb.clicked.connect(self.editingFinished.emit) def get_title(self): return self.title_edit_le.text() def get_description(self): return self.description_edit_le.text() def clear_ui(self): self.title_edit_le.clear() self.description_edit_le.clear() # def sizeHint(self): # """ Tell the caller how big we are. """ # return self.starRating.sizeHint() class ListViewDelegate(QtWidgets.QStyledItemDelegate): def __init__(self, parent=None): super(ListViewDelegate, self).__init__(parent) def sizeHint(self, option, index): if index.data(CustomRoles.cur_state): return QtCore.QSize(100, 77) else: return QtCore.QSize(100, 24) # return option.rect.size() # return QtWidgets.QStyledItemDelegate.sizeHint(self, option, index) def createEditor(self, parent, option, index): print("createEditor") item = index.model().itemFromIndex(index) item.setData(True, CustomRoles.cur_state) editor = Editor(parent) editor.editingFinished.connect(self.commitAndCloseEditor) editor.title_edit_le.setText(index.data(CustomRoles.title)) editor.description_edit_le.setText(index.data(CustomRoles.description)) index.model().layoutChanged.emit() return editor def setModelData(self, editor, model, index): print("setModelData") model.setData(index, editor.get_title(), role=CustomRoles.title) model.setData(index, editor.get_description(), role=CustomRoles.description) model.setData(index, False, role=CustomRoles.cur_state) model.setData(index, editor.get_title(), role=Qt.DisplayRole) def commitAndCloseEditor(self): print('commitAndCloseEditor') editor = self.sender() self.commitData.emit(editor) self.closeEditor.emit(editor, QtWidgets.QStyledItemDelegate.NoHint) self.edit_state = False self.parent().layoutChanged.emit() def print_data(): index = list_view.currentIndex() print('*'*20) print(index.data(QtCore.Qt.DisplayRole)) print(index.data(CustomRoles.title)) print(index.data(CustomRoles.description)) print(index.data(CustomRoles.cur_state)) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() list_view = QtWidgets.QListView() model = QtGui.QStandardItemModel() list_view.setModel(model) list_view.setItemDelegate(ListViewDelegate(model)) list_items = ['zero', 'one', 'two'] for i in list_items: item = QtGui.QStandardItem(i) item.setData(i, CustomRoles.title) item.setData("no comment yet", CustomRoles.description) item.setData(False, CustomRoles.cur_state) model.appendRow(item) lay = QtWidgets.QVBoxLayout() pb = QtWidgets.QPushButton('Print item data') pb.clicked.connect(print_data) lay.addWidget(list_view) lay.addWidget(pb) w.setLayout(lay) w.show() rec = app.exec_() sys.exit(rec)
-