Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. correctly manage sizeHint for item in delegate with custom editor
Qt 6.11 is out! See what's new in the release blog

correctly manage sizeHint for item in delegate with custom editor

Scheduled Pinned Locked Moved Unsolved Qt for Python
1 Posts 2 Posters 723 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • alomA Offline
    alomA Offline
    alom
    wrote on last edited by alom
    #1

    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.

    1. 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.

    2. 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)
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved