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
Forum Updated to NodeBB v4.3 + New Features

correctly manage sizeHint for item in delegate with custom editor

Scheduled Pinned Locked Moved Unsolved Qt for Python
1 Posts 2 Posters 545 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.
  • A Offline
    A Offline
    alom
    wrote on 7 Mar 2020, 21:13 last edited by alom 3 Jul 2020, 22:57
    #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

    1/1

    7 Mar 2020, 21:13

    • Login

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