QFileDialog 作为 TableView 的编辑器失去焦点时关闭
我有一个 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()
的调用,启动时非常小(这让失去焦点的情况更容易发生)。我该如何改变对话框的大小呢?
1 个回答
4
这是正常的行为。
标准视图并不是小部件的容器,每个单元格都是在需要的时候才绘制出来的。用于编辑的小部件只有在触发编辑时才会被创建,并且会覆盖在视图上。然后会调用代理来创建合适的编辑小部件,并将单元格的位置和大小作为参数传入。
视图会保留编辑器小部件的所有权,因为一旦失去焦点,你显然就无法再进行编辑,所以视图会删除这个编辑器。
如果你在setModelData
函数中没有返回任何东西,模型就不会被更新。说模型被恢复到原始数据是不正确的,因为它根本没有被改变过。
我建议你尝试将QFileDialog
设置为模态打开(editor.setModal(true)
),这样对话框必须关闭后,焦点才能转移到其他小部件上。