QFileDialog作为TableView的编辑器,失去焦点时关闭

3

我有一个关联了QAbstractTableModelQTableView,其中某些列包含目录名称。我想使用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)),这样在将焦点转移到另一个小部件之前必须关闭对话框。


谢谢您的快速回复!我尝试了那个方法,它确实有所帮助,因为它不会将焦点返回到我的应用程序,但是如果另一个应用程序获得了焦点,编辑器仍然会关闭。但是听起来这就是它应该做的事情,所以我只能接受它。 - DirkR
关于 setModelData:我如何知道对话框是通过选择还是取消关闭的?在这两种情况下,setModelData 被调用时传递的值都相同。感到困惑... - DirkR
通过检查 QDialog::result() 返回的内容 - RobbieE
嗯,我在QFileDialog的PyQT文档中没有看到这个,而且如果我在setModelData中打印editor.result(),我总是得到0。我为此打开了一个新问题,谢谢! - DirkR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接