I'm using a QFileDialog
as the editor for some columns in a QTableView
. This basically works (modulo some focus issues, see here):
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)
However, when the editor is closed I don't see a way to differentiate between Choose
and Cancel
(or lost focus), the setEditorData
function is called in all cases. I don't see a way to get the result from QFileDialog
that I get as editor
, all examples I can find use the return value from exec_
, which I don't have access to.
In
setModelData
, it looks like you could check the editor's result before setting the model's data. By default, the result isQDialog.Rejected
, and that should only change if the user actually chooses a file:UPDATE:
After some belated testing, it's obvious that no matter how the file-dialog is run (even with
exec
), itsresult
will never get properly reset in the context of a delegate editor. So a little indirection is needed. According to the docs for QFileDialog.filesSelected, this signal will always and only be sent when the dialog is accepted (even if there are no selected files). So we can use this mechanism to force the correct dialog result, like this: