При щелчке правой кнопкой мыши по контекстному меню открывается неправильный каталог - PullRequest
0 голосов
/ 20 февраля 2020

Когда я щелкаю правой кнопкой мыши по файлу в древовидном представлении, контекстное меню и его основные методы работают.

Однако, когда я щелкаю правой кнопкой мыши по пустому пространству и открывается контекстное меню, к моей рабочей папке применяются методы удаления и архивирования. сам (т.е. где хранится файл 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_())

Попытался применить logi c из этого потока , но не удалось. Совет будет высоко ценится!

1 Ответ

1 голос
/ 21 февраля 2020

Чтобы убедиться, что вы находитесь в пустом пространстве, вы можете использовать индекс, так как он будет недействительным.

В соответствии с этим вы можете принять несколько решений:

  • Отключить 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, но реализовать новый класс, который наследуется от соответствующего виджета, и использовать начальный класс для его заполнения. Для получения дополнительной информации прочитайте это и Использование сгенерированного кода .

...