QTableView 的 QItemDelegate 编辑器上的自定义小部件
Custom widget on QItemDelegate editor for QTableView
我有一个 QTableView
显示来自自定义模型的数据。每个单元格上的版本都有一个 QItemDelegate
。视图的一列有一个自定义小部件,由 QLineEdit
和 QCheckBox
组成。当我单击此列的单元格时,会显示编辑器并且它可以工作,但它不适合 table 单元格。而且,当我放大一行并单击单元格时,我可以看到小部件后面的单元格的数据。
有没有一种方法可以让我的小部件在视图上像 QItemDelegate
的普通编辑小部件一样工作?即创建时它使用单元格的所有垂直 space?
这是我的小部件(简体):
class MyWidget(QtGui.QWidget):
def __init__(self, parent = None):
super(MyWidget, self).__init__(parent)
self.lineEdit = QtGui.QLineEdit(parent)
self.checkBox = QtGui.QCheckBox(parent)
self.checkBox.setChecked(False)
self.gridLayout = QtGui.QGridLayout(self)
self.gridLayout.setSpacing(3)
self.gridLayout.addWidget(self.lineEdit, 0, 0)
self.gridLayout.addWidget(self.checkBox, 0, 1)
我的代表(简体):
class MyDelegate(QtGui.QItemDelegate):
def __init__(self, parent = None):
super(MyDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
return MyWidget(parent)
def setModelData(self, editor, model, index):
pass
def setEditorData(self, editor, model, index):
pass
有许多不同的问题:
默认情况下 QLineEdit
的垂直尺寸策略是固定的,因此它不会展开以填充可用空间 space。
布局有一个默认的内容边距(即填充),这可能会限制所包含的小部件的大小。
默认情况下,QWidget
不会自动绘制自己的背景,因此单元格的数据可能在下方可见。
如果小部件在单元格中占据全部 space,将无法再显示单元格被选中。
所有这些问题都可以通过以下方式解决:
class MyWidget(QtGui.QWidget):
def __init__(self, parent = None):
super(MyWidget, self).__init__(parent)
# create an inner widget
widget = QtGui.QWidget(self)
# disable widget transparency
widget.setAutoFillBackground(True)
# allow the line-edit to fully expand
self.lineEdit = QtGui.QLineEdit(widget)
self.lineEdit.setSizePolicy(QtGui.QSizePolicy(
QtGui.QSizePolicy.MinimumExpanding,
QtGui.QSizePolicy.MinimumExpanding))
self.checkBox = QtGui.QCheckBox(widget)
self.checkBox.setChecked(False)
# trim space on right side of checkbox
self.checkBox.setText('')
hbox = QtGui.QHBoxLayout(widget)
# remove the inner margin
hbox.setContentsMargins(0, 0, 0, 0)
hbox.setSpacing(3)
hbox.addWidget(self.lineEdit)
hbox.addWidget(self.checkBox)
layout = QtGui.QVBoxLayout(self)
# set the selection rectangle width
layout.setContentsMargins(2, 2, 2, 2)
layout.addWidget(widget)
看起来像这样:
我有一个 QTableView
显示来自自定义模型的数据。每个单元格上的版本都有一个 QItemDelegate
。视图的一列有一个自定义小部件,由 QLineEdit
和 QCheckBox
组成。当我单击此列的单元格时,会显示编辑器并且它可以工作,但它不适合 table 单元格。而且,当我放大一行并单击单元格时,我可以看到小部件后面的单元格的数据。
有没有一种方法可以让我的小部件在视图上像 QItemDelegate
的普通编辑小部件一样工作?即创建时它使用单元格的所有垂直 space?
这是我的小部件(简体):
class MyWidget(QtGui.QWidget):
def __init__(self, parent = None):
super(MyWidget, self).__init__(parent)
self.lineEdit = QtGui.QLineEdit(parent)
self.checkBox = QtGui.QCheckBox(parent)
self.checkBox.setChecked(False)
self.gridLayout = QtGui.QGridLayout(self)
self.gridLayout.setSpacing(3)
self.gridLayout.addWidget(self.lineEdit, 0, 0)
self.gridLayout.addWidget(self.checkBox, 0, 1)
我的代表(简体):
class MyDelegate(QtGui.QItemDelegate):
def __init__(self, parent = None):
super(MyDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
return MyWidget(parent)
def setModelData(self, editor, model, index):
pass
def setEditorData(self, editor, model, index):
pass
有许多不同的问题:
默认情况下
QLineEdit
的垂直尺寸策略是固定的,因此它不会展开以填充可用空间 space。布局有一个默认的内容边距(即填充),这可能会限制所包含的小部件的大小。
默认情况下,
QWidget
不会自动绘制自己的背景,因此单元格的数据可能在下方可见。如果小部件在单元格中占据全部 space,将无法再显示单元格被选中。
所有这些问题都可以通过以下方式解决:
class MyWidget(QtGui.QWidget):
def __init__(self, parent = None):
super(MyWidget, self).__init__(parent)
# create an inner widget
widget = QtGui.QWidget(self)
# disable widget transparency
widget.setAutoFillBackground(True)
# allow the line-edit to fully expand
self.lineEdit = QtGui.QLineEdit(widget)
self.lineEdit.setSizePolicy(QtGui.QSizePolicy(
QtGui.QSizePolicy.MinimumExpanding,
QtGui.QSizePolicy.MinimumExpanding))
self.checkBox = QtGui.QCheckBox(widget)
self.checkBox.setChecked(False)
# trim space on right side of checkbox
self.checkBox.setText('')
hbox = QtGui.QHBoxLayout(widget)
# remove the inner margin
hbox.setContentsMargins(0, 0, 0, 0)
hbox.setSpacing(3)
hbox.addWidget(self.lineEdit)
hbox.addWidget(self.checkBox)
layout = QtGui.QVBoxLayout(self)
# set the selection rectangle width
layout.setContentsMargins(2, 2, 2, 2)
layout.addWidget(widget)
看起来像这样: