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. QComboBox editor showPopup incorrect placment of listview
Qt 6.11 is out! See what's new in the release blog

QComboBox editor showPopup incorrect placment of listview

Scheduled Pinned Locked Moved Unsolved Qt for Python
3 Posts 2 Posters 1.7k 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
    #1

    I have a custom delegate that has a QComboBox as an editor for a tableview. I would like the ComboBox to auto expand and show the list view when the user double clicks the cell. Currently its double click to initiate the editor and then another click to expand to show the pop up.

    I found the ComboBox has a .showPopup(), but when I use this, it provides the behavior of only using two clicks to expand the editor BUT always places the popup under the first cell upon the first edit event of the cell.

    Is the creatEditor() the wrong place to call the showPopup? Or should I use some signal or editHint instead? Feels like Qt doesn't have all the information it needs and places the popup under the first cell

    On windows 10, Qt 5.13

    from PySide2 import QtGui, QtCore, QtWidgets
    import sys
    
    
    class CustomTableDelegate(QtWidgets.QStyledItemDelegate):
    
        def __init__(self, parent=None):
            super(CustomTableDelegate, self).__init__(parent)
    
        def createEditor(self, parent, option, index):
            """Create the ComboBox editor view."""
            if index.column() == 0:
                editor = QtWidgets.QComboBox(parent)
                editor.addItems(['v001', 'v002', 'v003'])
                # !! this causes the pop up in incorrect place
                editor.showPopup()
                editor.activated.connect(self.commitAndCloseEditor)
                return editor
    
        def setEditorData(self, editor, index):
            """Set the ComboBox's current index."""
            value = index.data(QtCore.Qt.DisplayRole)
            i = editor.findText(value)
            if i == -1:
                i = 0
            editor.setCurrentIndex(i)
    
        def commitAndCloseEditor(self):
            editor = self.sender()
            self.commitData.emit(editor)
            self.closeEditor.emit(editor, QtWidgets.QStyledItemDelegate.NoHint)
    
        def setModelData(self, editor, model, index):
            """Set the table's model's data when finished editing."""
            value = editor.currentText()
            model.setData(index, value)
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication([])
        data = [["v001", "stuff", "fixing source", '2020-01-14', ''],
                ["v002", "more stuff", "currently broken", '2020-06-30', ''],
                ["v003", "too much stuff", "scaling issues", '2020-02-08', ''],
                ["v088", "still missing stuff", "not coment", '2020-11-13', ''], ]
    
        table_view = QtWidgets.QTableView()
        table_view.setItemDelegate(CustomTableDelegate(table_view))
        model = QtGui.QStandardItemModel()
        model.setHorizontalHeaderLabels(['version', 'file', 'comment', 'date', ''])
        table_view.setModel(model)
        for r in range(len(data)):
            for c in range(5):
                model.setItem(r, c, QtGui.QStandardItem(data[r][c]))
        table_view.show()
        sys.exit(app.exec_())
    
    1 Reply Last reply
    0
    • alomA Offline
      alomA Offline
      alom
      wrote on last edited by alom
      #2

      @Denni-0
      Sorry does your code have the event to trigger the dropdow instead of the .showPopup?

      Also you decorated the commitAndCloseEditor(), what is the purpose of that? and did you mean to use "@Slot" instead? I thought @pyqtslot is a pyqt5 decorator.
      https://www.learnpyqt.com/blog/pyqt5-vs-pyside2/

      Cheers

      1 Reply Last reply
      0
      • alomA Offline
        alomA Offline
        alom
        wrote on last edited by
        #3

        no worries,

        So I was able to try an event filter and test if a HoverEnter event happened, Then trigger the show pop up. Seems to solve the placement issue, not sure if this is the proper way of handling this,but gets the job done so far.

        from PySide2 import QtGui, QtCore, QtWidgets
        import sys
        
        
        class CustomTableDelegate(QtWidgets.QStyledItemDelegate):
        
            def __init__(self, parent=None):
                super(CustomTableDelegate, self).__init__(parent)
        
            def createEditor(self, parent, option, index):
                """Create the ComboBox editor view."""
                if index.column() == 0:
                    editor = QtWidgets.QComboBox(parent)
                    editor.addItems(['v001', 'v002', 'v003'])
                    editor.installEventFilter(self)
                    editor.activated.connect(self.commitAndCloseEditor)
                    return editor
        
            def setEditorData(self, editor, index):
                """Set the ComboBox's current index."""
                value = index.data(QtCore.Qt.DisplayRole)
                i = editor.findText(value)
                if i == -1:
                    i = 0
                editor.setCurrentIndex(i)
        
            def commitAndCloseEditor(self):
                editor = self.sender()
                self.commitData.emit(editor)
                self.closeEditor.emit(editor, QtWidgets.QStyledItemDelegate.NoHint)
        
            def setModelData(self, editor, model, index):
                """Set the table's model's data when finished editing."""
                value = editor.currentText()
                model.setData(index, value)
        
            def eventFilter(self, p_object, event):
                if event.type() == QtCore.QEvent.Type.HoverEnter:
                    p_object.showPopup()
                    return True
                else:
                    return False
        if __name__ == '__main__':
            app = QtWidgets.QApplication([])
            data = [["v001", "stuff", "fixing source", '2020-01-14', ''],
                    ["v002", "more stuff", "currently broken", '2020-06-30', ''],
                    ["v003", "too much stuff", "scaling issues", '2020-02-08', ''],
                    ["v088", "still missing stuff", "not coment", '2020-11-13', ''], ]
        
            table_view = QtWidgets.QTableView()
            table_view.setItemDelegate(CustomTableDelegate(table_view))
            model = QtGui.QStandardItemModel()
            model.setHorizontalHeaderLabels(['version', 'file', 'comment', 'date', ''])
            table_view.setModel(model)
            for r in range(len(data)):
                for c in range(5):
                    model.setItem(r, c, QtGui.QStandardItem(data[r][c]))
            table_view.show()
            sys.exit(app.exec_())
        
        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