Python 防止QFileDialog中的文件操作,如复制、查看、删除等
我们正在考虑在Azure服务器上部署PyQt应用程序,该应用程序运行良好,尽管对用户操作的响应有点慢 但是,我们有一个问题,那就是QFileDialog几乎允许任何探索操作:将文件从虚拟机复制到用户的本地驱动器,在记事本的“Program Files(x86)”中打开文件,等等 已经考虑的办法:Python 防止QFileDialog中的文件操作,如复制、查看、删除等,python,windows,qt,azure,qfiledialog,Python,Windows,Qt,Azure,Qfiledialog,我们正在考虑在Azure服务器上部署PyQt应用程序,该应用程序运行良好,尽管对用户操作的响应有点慢 但是,我们有一个问题,那就是QFileDialog几乎允许任何探索操作:将文件从虚拟机复制到用户的本地驱动器,在记事本的“Program Files(x86)”中打开文件,等等 已经考虑的办法: 因为python应用程序必须具有对的读写权限 在“程序文件(x86)”下运行,我们无法使用文件权限 控制访问 我们可以将Python转换为难以理解的.exe,但这可能 仍然可以使用“文件”对话框中的关联
我们唯一能想到的就是从头开始创建我们自己的文件对话框,但这非常繁琐。有什么现成的解决方案吗?看看qtreeview的示例,它们显示了一个文件资源管理器,所以我认为实现一个简单的文件系统资源管理器实际上不是一个大任务。多亏了QFileSystemModel,这非常容易。看看qtreeview的示例,它们显示了一个文件资源管理器,所以我认为实现一个简单的文件系统资源管理器实际上不是一个大任务。由于QFileSystemModel的缘故,
QFileDialog
类已经具备了以下功能:
dialog = QtGui.QFileDialog()
dialog.setOption(QtGui.QFileDialog.ReadOnly, True)
dialog.exec_()
不过,这似乎只适用于Qt的内置文件对话框。如果使用静态函数打开本机文件对话框,
ReadOnly
选项似乎会被忽略(不过,我只在Linux上测试了此选项)。QFileDialog类已经具有此功能:
dialog = QtGui.QFileDialog()
dialog.setOption(QtGui.QFileDialog.ReadOnly, True)
dialog.exec_()
不过,这似乎只适用于Qt的内置文件对话框。如果使用静态函数打开本机文件对话框,
ReadOnly
选项似乎会被忽略(不过我只是在Linux上测试过这个选项)。以下是我根据@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_()
P>我感谢页面上的@ SerguGubNoKo和@ GayAn,提供了C++实现,从中我得到了上面的内容。 < P>这是我实际做的,基于@ EkHuoRo的建议:
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_()
我感谢页面上的@ SerguGubNoKo和@ GayAn,提供C++实现,第一个猜测:创建您自己的类,该类是从QFileDialog派生的,并覆盖右键单击事件以不执行任何操作。或者使用QWidgets:
setContextMenuPolicy
并将策略设置为Qt::NoContextMenu
我认为这是不切实际的,因为我正在使用PyQt绑定。我必须去C++ QT代码并编辑它吗?我的C++已经足够好了,但是我必须重建和重新包装所有东西,不是吗?对不起-最后一个评论是一致的!setContextMenuPolicy听起来很有希望,但想必Ctrl+C&Ctrl+V也必须被禁用。有类似的命令吗?关于PyQt:没有问题。只需在网上搜索教程。它在Python中运行良好。关于Ctrl+V:这是一个新问题,请打开一个新问题,这样答案就不会混淆。我通常建议您仔细阅读QFileDialog的文档,包括所有成员的列表,包括继承的成员
页面。第一个猜测:创建从QFileDialog派生的您自己的类,并重写右键单击事件以不执行任何操作。或者使用QWidgets:setContextMenuPolicy
并将策略设置为Qt::NoContextMenu
我认为这是不切实际的,因为我正在使用PyQt绑定。我必须去C++ QT代码并编辑它吗?我的C++已经足够好了,但是我必须重建和重新包装所有东西,不是吗?对不起-最后一个评论是一致的!setContextMenuPolicy听起来很有希望,但想必Ctrl+C&Ctrl+V也必须被禁用。有类似的命令吗?关于PyQt:没有问题。只需在网上搜索教程。它在Python中运行良好。关于Ctrl+V:这是一个新问题,请打开一个新问题,这样答案就不会混淆。我通常会建议您仔细阅读QFileDialog的文档,包括所有成员的列表,包括继承的成员
页面。谢谢,@ekhumoro(再次!)-这似乎会使Ctrl+C&Ctrl+V以及上下文菜单(在我正在使用的Windows上)无效。谢谢,@ekhumoro(再次!)-这似乎会使Ctrl+C&Ctrl+V以及上下文菜单无效(在Windows上,我正在使用)。谢谢,@bobzer。我想我会把这个作为后备计划,因为上面的Ekhumaro的回答似乎可以完成这项工作。这种方法对我有两个好处:1)我绝对100%相信对话框没有“后门”,2)如果我自己创建了对话框,我甚至可以在我不想看到的文件夹(例如C:\Program Files(x86))中停止它。@MikeSadler。我认为Qt已经涵盖了您的所有用例。你可以用。谢谢,@bobzer。我想我会把这个作为后备计划,因为上面的Ekhumaro的回答似乎可以完成这项工作。这种方法对我有两个好处:1)我绝对100%相信对话框没有“后门”,2)如果我自己创建了对话框,我甚至可以在我不想看到的文件夹(例如C:\Program Files(x86))中停止它。@MikeSadler。我认为Qt已经涵盖了您的所有用例。您可以通过以下方式实现(2)。