右键单击上下文菜单时访问了错误的目录
Wrong directory being accessed upon right click for context menu
当我在树视图中右键单击文件时,上下文菜单及其底层方法起作用。
但是,当我右键单击空白 space 并打开上下文菜单时,删除和存档方法适用于我的工作文件夹本身(即存储 test_gui.py 文件的位置)。
我不介意弹出空的上下文菜单 space,我只是不希望它在那种情况下能够执行任何操作。
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_())
试图应用来自 线程的逻辑,但未成功。非常感谢您的建议!
要验证您是否处于空状态 space 您可以使用索引,因为它无效。
根据这个你可以做出几个决定:
禁用 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")
<b>for action in (delete_action, archive_action):
action.setEnabled(index.isValid())</b>
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)
<b>if not index.isValid():
return</b>
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生成的代码,而是实现一个新的class继承自合适的widget并使用初始 class 来填充它。有关详细信息,请阅读 and Using the Generated Code.
当我在树视图中右键单击文件时,上下文菜单及其底层方法起作用。
但是,当我右键单击空白 space 并打开上下文菜单时,删除和存档方法适用于我的工作文件夹本身(即存储 test_gui.py 文件的位置)。
我不介意弹出空的上下文菜单 space,我只是不希望它在那种情况下能够执行任何操作。
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_())
试图应用来自
要验证您是否处于空状态 space 您可以使用索引,因为它无效。
根据这个你可以做出几个决定:
禁用 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") <b>for action in (delete_action, archive_action): action.setEnabled(index.isValid())</b> 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) <b>if not index.isValid(): return</b> 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生成的代码,而是实现一个新的class继承自合适的widget并使用初始 class 来填充它。有关详细信息,请阅读