QFileDialog as editor for TableView: how to get result?

微笑、不失礼 提交于 2019-12-08 08:04:14

问题


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.


回答1:


In setModelData, it looks like you could check the editor's result before setting the model's data. By default, the result is QDialog.Rejected, and that should only change if the user actually chooses a file:

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

UPDATE:

After some belated testing, it's obvious that no matter how the file-dialog is run (even with exec), its result 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:

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


来源:https://stackoverflow.com/questions/22868856/qfiledialog-as-editor-for-tableview-how-to-get-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!