QFileDialog作为TableView的编辑器:如何获取结果?
我在一个 QTableView
中使用 QFileDialog
来编辑某些列。这基本上是可以工作的(虽然有一些焦点问题,具体可以看 这里):
class DirectorySelectionDelegate(QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = QFileDialog(parent)
editor.setFileMode(QFileDialog.Directory)
editor.setModal(True)
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()[0])
def updateEditorGeometry(self, editor, option, index):
r = option.rect
r.setHeight(600)
r.setWidth(600)
editor.setGeometry(r)
但是,当编辑器关闭时,我找不到方法来区分是点击了 选择
还是 取消
(或者是失去焦点),因为 setEditorData
函数在所有情况下都会被调用。我也看不到如何从 QFileDialog
中获取作为 editor
的结果,所有我能找到的例子都使用了 exec_
的返回值,而我没有办法访问这个值。
1 个回答
2
在 setModelData
这个地方,你可以在设置模型数据之前,先检查一下编辑器的 结果。默认情况下,结果是 QDialog.Rejected
,这只有在用户真的选择了一个文件时才会改变。
def setModelData(self, editor, model, index):
if editor.result() == QtGui.QDialog.Accepted:
model.setData(index, editor.selectedFiles()[0])
更新:
经过一些后续测试,很明显无论文件对话框是怎么运行的(即使是用 exec
),在代理编辑器的上下文中,它的 result
永远不会被正确重置。所以我们需要一点间接的方法。根据 QFileDialog.filesSelected 的文档,这个信号只会在对话框被接受时发送(即使没有选择任何文件)。所以我们可以利用这个机制来强制得到正确的对话框结果,像这样:
class DirectorySelectionDelegate(QtGui.QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = QtGui.QFileDialog(parent)
editor.filesSelected.connect(
lambda: editor.setResult(QtGui.QDialog.Accepted))
...
def setModelData(self, editor, model, index):
print(editor.result())
if editor.result() == QtGui.QDialog.Accepted:
model.setData(index, editor.selectedFiles()[0])