python - 右键单击上下文菜单时访问错误的目录
问题描述
当我右键单击树视图中的文件时,上下文菜单及其底层方法起作用。
但是,当我右键单击空白区域并打开上下文菜单时,删除和存档方法将应用于我的工作文件夹本身(即 test_gui.py 文件的存储位置)。
我对在空白处弹出的上下文菜单很好,我只是不希望它在这种情况下能够做任何事情。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import os
import send2trash
import shutil
class Ui_MainWindow(QtWidgets.QWidget):
def setupUi(self, MainWindow):
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
# Treeview model, path should contain files for test purpose
path = r"C:\Test_gui"
self.fileModel = QtWidgets.QFileSystemModel()
self.fileModel.setReadOnly(False)
# Treeview functionality
self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView.setModel(self.fileModel)
self.treeView.setRootIndex(self.fileModel.setRootPath(path))
self.treeView.setGeometry(QtCore.QRect(190, 130, 541, 381))
self.treeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.treeView.customContextMenuRequested.connect(self.openMenu)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
def delete(self, index):
""" Send the selected file to the recycle bin"""
path = self.fileModel.fileInfo(index).absoluteFilePath()
# When context menu is opened (right click) on a file, send2trash
# sends file to the bin. However, if context menu is open on empty
# space, delete method sends my working directory to the bin.
print(os.path.abspath(path))
# send2trash.send2trash(os.path.abspath(path))
def archive(self, index):
"""Move selected file to archive"""
source = self.fileModel.fileInfo(index).absoluteFilePath()
destination = r"C:\Test_gui_archive"
# Same as above, but the archive method sends the working directory
# to archive.
print(os.path.abspath(source))
# shutil.move(os.path.abspath(source), os.path.abspath(destination))
def openMenu(self, position):
"""Setup a context menu to open upon right click."""
index = self.treeView.indexAt(position)
menu = QtWidgets.QMenu(self)
delete_action = menu.addAction("Send to trashbin")
archive_action = menu.addAction("Move to archive")
action = menu.exec_(self.treeView.viewport().mapToGlobal(position))
if action == delete_action:
self.delete(index)
if action == archive_action:
self.archive(index)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
尝试应用此线程中的逻辑,但未成功。建议将不胜感激!
解决方案
要验证您是否在空白空间中,您可以使用索引,因为它是无效的。
据此,您可以做出几个决定:
禁用 QActions:
def openMenu(self, position): """Setup a context menu to open upon right click.""" index = self.treeView.indexAt(position) menu = QtWidgets.QMenu(self) delete_action = menu.addAction("Send to trashbin") archive_action = menu.addAction("Move to archive") for action in (delete_action, archive_action): action.setEnabled(index.isValid()) action = menu.exec_(self.treeView.viewport().mapToGlobal(position)) if action == delete_action: self.delete(index) if action == archive_action: self.archive(index)
或者不显示 QMenu:
def openMenu(self, position): """Setup a context menu to open upon right click.""" index = self.treeView.indexAt(position) if not index.isValid(): return menu = QtWidgets.QMenu(self) delete_action = menu.addAction("Send to trashbin") archive_action = menu.addAction("Move to archive") action = menu.exec_(self.treeView.viewport().mapToGlobal(position)) if action == delete_action: self.delete(index) if action == archive_action: self.archive(index)
注意:我建议您不要修改 Qt Designer 生成的代码,而是实现一个继承自相应小部件的新类并使用初始类来填充它。有关更多信息,请阅读此内容和使用生成的代码。
推荐阅读
- c# - 读取和查找文件中的文本
- javascript - 如何编写一个选择数组中第一个按钮的 for 循环?
- sql - 我可以使用什么 SQL 命令来解决以下难题?
- django - 将两个模型实例组合成一个序列化对象 django rest framework
- kubernetes - kubernetes 将 tty 设置为 false 不能按(我)预期的那样工作
- android - Android 测试 Koin NoBeanDefFoundException
- c++ - 使用 assert vs exit 或反之亦然的优点或含义是什么?
- r - 自定义 bin 并使用 R 查找有多少样本落入 bin
- asp.net-core - 我应该如何从我的控制器到我的界面进行异步调用
- java - 棘手但不难的无限循环练习