防止QFileDialog中的文件操作,例如复制,查看,删除等

时间:2016-03-23 12:00:28

标签: python windows qt azure qfiledialog

我们正在考虑在Azure服务器上部署PyQt应用程序,该应用程序运行良好,尽管响应用户操作有点慢。

然而,我们遇到了一个问题,即QFileDialog几乎允许任何探索操作:将文件从虚拟机复制到用户的本地驱动器,在“程序文件”中打开文件(86)'在记事本等。

已经考虑过的方法:

  1. 因为python应用程序必须具有读写权限 在' Program Files(x86)'下运行,我们无法使用文件权限 控制访问。

  2. 我们可以将Python变成一个难以理解的.exe,但这可以 仍然可以使用文件对话框中的上下文菜单进行复制。

  3. 我们可以使用文件过滤器然后隐藏它们,所以你只能这样做 看到(并弄乱)相关文件,但用户仍然可以 复制整个目录。

  4. 我们唯一能想到的就是从头开始创建自己的文件对话框,但这非常繁琐。有没有开箱即用的'溶液

3 个答案:

答案 0 :(得分:2)

QFileDialog类已具备此功能:

    dialog = QtGui.QFileDialog()
    dialog.setOption(QtGui.QFileDialog.ReadOnly, True)
    dialog.exec_()

但这似乎只适用于Qt的内置文件对话框。如果使用静态函数打开本机文件对话框,则ReadOnly选项似乎被忽略(尽管我只在Linux上对此进行过测试)。

答案 1 :(得分:1)

查看qtreeview的例子,他们展示了一个文件浏览器,所以我认为实现一个简单的文件系统资源管理器实际上并不是一项大任务。由于QFileSystemModel http://doc.qt.io/qt-5/model-view-programming.html#using-models-and-views

,它非常容易

答案 2 :(得分:1)

根据@ ekhumoro的建议,我实际上做了什么:

from PyQt4 import QtGui
import guidata
import re

class _DirectoryFilterProxyModel(QtGui.QSortFilterProxyModel):
    """ A basic filter to be applied to the file items to be displayed.
     Based on C++ example at:
      https://stackoverflow.com/questions/2101100/qfiledialog-filtering-folders. """

    def __init__(self, ignore_directories=[], *args, **kw):
        """ Constructor
        :param ignore_directories: A list of directories to exclude.  These
        can be regular expressions or straight names. """
        QtGui.QSortFilterProxyModel.__init__(self, *args, **kw)
        self.ignore_directories = ignore_directories

    def filterAcceptsRow(self, sourceRow, sourceParent):
        fileModel = self.sourceModel()
        index0 = fileModel.index(sourceRow, 0, sourceParent)

        if fileModel:
            if fileModel.isDir(index0):
                for directory in self.ignore_directories:
                    if re.match(directory, fileModel.fileName(index0)):
                        return False
                return True
            else:    # For files
                return True
        else:
            return False

并实例化:

app = guidata.qapplication()
dialog = QtGui.QFileDialog()
proxyModel = _DirectoryFilterProxyModel(ignore_directories=["Program Files", "Program Files (x86)", "Windows"])
dialog.setProxyModel(proxyModel)
dialog.setOption(QtGui.QFileDialog.ReadOnly, True)
dialog.setOption(QtGui.QFileDialog.HideNameFilterDetails, True)
dialog.exec_()

感谢@serge_gubenko和@Gayan在页面qfiledialog - Filtering Folders?上提供了C ++实现,我从中得到了上述内容。