2

Doble-clicking the item in QTableView brings up the QWidget which is created by QItemDelegates createEditor() method. The problem is that the QWidget is offset from the QTableView window and it is floating somewhere on a desktop (at the corner of the my desktop). How to make sure the QWidget created by createEditor method is properly positioned?

enter image description here

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

app = QApplication([])


class PopupView(QWidget):
    def __init__(self, parent=None):
        super(PopupView, self).__init__(parent)
        self.setWindowFlags(Qt.Popup)
        self.move(QCursor.pos())
        self.show()


class ItemDelegate(QItemDelegate):
    def __init__(self, parent):
        QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        return PopupView(parent)


class Model(QAbstractTableModel):
    def __init__(self):
        QAbstractTableModel.__init__(self)
        self.items = [[1, 'one', 'ONE'], [2, 'two', 'TWO'], [3, 'three', 'THREE']]

    def flags(self, index):
        return Qt.ItemIsEnabled | Qt.ItemIsEditable

    def rowCount(self, parent=QModelIndex()):
        return 3

    def columnCount(self, parent=QModelIndex()):
        return 3

    def data(self, index, role):
        if not index.isValid():
            return

        if role in [Qt.DisplayRole, Qt.EditRole]:
            return self.items[index.row()][index.column()]


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.clipboard = QApplication.clipboard()
        mainWidget = QWidget()
        self.setCentralWidget(mainWidget)
        mainWidget.setLayout(QVBoxLayout())

        view = QTableView()
        view.setModel(Model())
        view.setItemDelegate(ItemDelegate(view))
        self.layout().addWidget(view)


view = MainWindow()
view.show()
app.exec_()
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
alphanumeric
  • 17,967
  • 64
  • 244
  • 392

1 Answers1

1

The correct way to do this is to re-implement the delegate's updateEditorGeometry method, which will allow you to customise the geometry of the editor in whatever way you like. Your editor and delegate classes would then simplify to this:

class PopupView(QWidget):
    def __init__(self, parent=None):
        super(PopupView, self).__init__(parent)
        self.setWindowFlags(Qt.Popup)

class ItemDelegate(QItemDelegate):
    def __init__(self, parent):
        super(ItemDelegate, self).__init__(parent)

    def createEditor(self, parent, option, index):
        return PopupView(parent)

    def updateEditorGeometry(self, editor, option, index):
        editor.move(QCursor.pos())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336