QFileDialog作为TableView的编辑器:如何获得结果?

时间:2014-04-04 17:05:35

标签: python qt pyqt qtableview qfiledialog

我使用QFileDialog作为QTableView中某些列的编辑器。这基本上有效(模糊一些焦点问题,见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)

然而,当编辑器关闭时,我看不到区分ChooseCancel(或失去焦点)的方法,所有setEditorData函数都被调用案例。我没有看到从QFileDialog获得editor的结果的方法,我可以找到的所有示例都使用exec_的返回值,我不会这样做。 ; t可以访问。

1 个答案:

答案 0 :(得分:2)

setModelData中,您可以在设置模型数据之前检查编辑器的result。默认情况下,结果为QDialog.Rejected,只有在用户实际选择文件时才会更改:

    def setModelData(self, editor, model, index):
        if editor.result() == QtGui.QDialog.Accepted:
            model.setData(index, editor.selectedFiles()[0])   

<强>更新

经过一些迟来的测试后,很明显无论文件对话框如何运行(即使使用exec),它的result也永远不会在委托编辑器的上下文中正确重置。所以需要一点间接。根据{{​​3}}的文档,只有在接受对话框时才会发送此信号(即使没有选定的文件)。所以我们可以使用这种机制来强制正确的对话结果,如下所示:

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])