如何将 QWidget 与 QItemDelegate 和 QTableView 一起使用
How to use QWidget with QItemDelegate and QTableView
双击 QTableView
中的项目会弹出 QWidget
,它是由 QItemDelegate
的 createEditor()
方法创建的。
问题是 QWidget
从 QTableView window 偏移并且它漂浮在桌面上的某个地方(在我桌面的角落)。如何确保 createEditor
方法创建的 QWidget
正确定位?
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_()
执行此操作的正确方法是重新实现委托的 updateEditorGeometry 方法,这将允许您以任何您喜欢的方式自定义编辑器的几何形状。您的编辑和代表 类 将简化为:
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())
双击 QTableView
中的项目会弹出 QWidget
,它是由 QItemDelegate
的 createEditor()
方法创建的。
问题是 QWidget
从 QTableView window 偏移并且它漂浮在桌面上的某个地方(在我桌面的角落)。如何确保 createEditor
方法创建的 QWidget
正确定位?
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_()
执行此操作的正确方法是重新实现委托的 updateEditorGeometry 方法,这将允许您以任何您喜欢的方式自定义编辑器的几何形状。您的编辑和代表 类 将简化为:
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())