我有QTableView
个关联QAbstractTableModel
,其中包含某些列中的目录名称。我想使用QFileDialog
作为编辑器来更改这些列。这有点不寻常,因为编辑器不会在表格单元格内(没有足够的空间)。
我使用QStyledItemDelegate
:
class DirectorySelectionDelegate(QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = QFileDialog(parent)
editor.setFileMode(QFileDialog.Directory)
editor.resize(400, 400)
return editor
def setEditorData(self, editor, index):
val = index.model().data(index, Qt.DisplayRole)
fs = val.rsplit(os.path.sep, 1)
if len(fs) == 2:
bdir, vdir = fs
else:
bdir = "."
vdir = fs[0]
editor.setDirectory(bdir)
editor.selectFile(vdir)
def setModelData(self, editor, model, index):
model.setData(index, editor.selectedFiles())
当双击单元格时,它会启动QFileDialog
,我可以选择我想要的目录,然后选择它在模型中设置。
但是,如果由于某种原因QFileDialog
失去焦点,它将被关闭,并且数据将设置为原始值。我希望在用户单击“取消”或“选择”之前打开对话框,但我找不到这样做的方法。
加分问题:由于某种原因,对话框会忽略resize()
来电并启动非常小(这使得失去焦点的可能性更大)。如何更改对话框的大小?
答案 0 :(得分:3)
这是预期的行为。
标准视图不是小部件的容器,必要时会绘制每个单元格。只有在生成编辑触发器时,才会创建用于编辑的窗口小部件并将其叠加在视图顶部。然后调用委托创建适当的编辑小部件,并将单元格的位置和大小作为参数传入。
视图保留编辑器小部件的所有权,因为每当焦点丢失时,您显然无法再编辑,因此视图会删除编辑器。
如果您未在setModelData
函数中传回任何内容,则不会更新模型。说模型被设置回原始数据是不正确的,因为它从一开始就不会被改变。
我建议您尝试将QFileDialog
设置为以模态方式打开(editor.setModal(true)
),以便在将焦点转移到另一个小部件之前必须关闭对话框。