删除动态创建的Qmenu项

2024-04-26 07:02:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Qmenu,我是通过加载一个带有Qsettings的列表来创建的,我试图通过在QListQWidget中加载列表并删除所选的项来从菜单中删除项。目前我可以删除列表小部件中的菜单项,它也会从qsettings中删除它们,但我无法想出如何在不重新启动的情况下从菜单中删除菜单项。我尝试过各种方法,如移除等,但都没能解决。
这是我的代码:

import functools
import sys
from PyQt5 import QtCore
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, \
    QApplication, QAction, QMenu, QListWidgetItem, \
    QListWidget, QGridLayout

class MainWindow(QWidget):
    settings = QtCore.QSettings('test_org', 'my_app')
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.layout = QHBoxLayout()
        self.menu_btn = QPushButton()
        self.menu = QMenu()
        self.add_menu = self.menu.addMenu("Menu")
        self.menu_btn.setMenu(self.menu)
        self.open_list_btn = QPushButton('open list')

        self.load_items = self.settings.value('menu_items', [])
        for item in self.load_items:
            self.action = QAction(item[0], self)
            self.action.setData(item)
            self.add_menu.addAction(self.action)
            self.action.triggered.connect(functools.partial(self.menu_clicked, self.action))

        self.layout.addWidget(self.menu_btn)
        self.layout.addWidget(self.open_list_btn)
        self.setLayout(self.layout)
        self.open_list_btn.clicked.connect(self.open_window)

    def open_window(self):
        self.create_menu_item = List()
        self.create_menu_item.show()

    def menu_clicked(self, item):
        itmData = item.data()
        print(itmData)

class List(QWidget):
    settings = QtCore.QSettings('test_org', 'my_app')
    def __init__(self, parent=None):
        super(List, self).__init__(parent)
        self.menu_items = self.settings.value('menu_items', [])
        self.layout = QGridLayout()
        self.list = QListWidget()
        self.remove_btn = QPushButton('Remove')
        self.layout.addWidget(self.list, 1, 1, 1, 1)
        self.layout.addWidget(self.remove_btn, 2, 1, 1, 1)
        self.setLayout(self.layout)
        self.remove_btn.clicked.connect(self.remove_items)

        for item in self.menu_items:
            self.item = QListWidgetItem()
            self.item.setText(str(item[0]))
            self.list.addItem(self.item)

    def remove_items(self):
        self.menu_items = self.settings.value('menu_items', [])
        del self.menu_items[self.list.currentRow()]
        self.settings.setValue('menu_items', self.menu_items)
        listItems = self.list.selectedItems()
        if not listItems: return
        for item in listItems:
            self.list.takeItem(self.list.row(item))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec_()

有人有什么想法吗?在

编辑:

这是QSettings中列表的结构。我用这个加载菜单,用这个加载QlistWidget。当我为QListWidget删除这些项目时,我试图让菜单删除这些项目。在

^{pr2}$

Tags: importself列表settingsdef菜单itemsaction
2条回答

我弄明白了。我不确定更好的方法,但我用对象名来做。
在主窗口中,我使用for循环中列表中每个列表的第一项将objectNames设置为self.action,如下所示:

self.action.setObjectName(item[0])

然后我在MainWindow类中创建了这个函数:

^{pr2}$

然后我加了一句:

w.remove_menu_item(item.text())

到List类中的remove函数,以获取列表列表中相同的第一项,该项现在是QActions的objectName。在

我认为您使用的数据结构是不正确的,因为当我执行代码时,它生成的QAction是两倍,我建议的结构是一个字典,其中键是QAction的名称和数据列表的值:

{
 'item0': ['itemdata00', 'itemdata01', 'itemdata02'],
 'item1': ['itemdata10', 'itemdata11', 'itemdata12'],
  ...
}

要构建初始配置,请使用以下脚本:

创建_设置.py

^{pr2}$

另一方面,我认为您想要处理QActions销毁的小部件应该接管相应的{},如下所示:

import sys
from PyQt5 import QtCore, QtWidgets

class MainWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        layout = QtWidgets.QHBoxLayout(self)

        menu_btn = QtWidgets.QPushButton()
        open_list_btn = QtWidgets.QPushButton('open list')
        layout.addWidget(menu_btn)
        layout.addWidget(open_list_btn)

        menu = QtWidgets.QMenu()
        menu_btn.setMenu(menu)

        self.menu_manager = MenuManager("menu_items", "Menu")
        menu.addMenu(self.menu_manager.menu)
        self.menu_manager.menu.triggered.connect(self.menu_clicked)
        open_list_btn.clicked.connect(self.menu_manager.show)

    def menu_clicked(self, action):
        itmData = action.data()
        print(itmData)


class MenuManager(QtWidgets.QWidget):
    def __init__(self, key, menuname, parent=None):
        super(MenuManager, self).__init__(parent)
        self.settings = QtCore.QSettings('test_org', 'my_app')
        self.key = key

        self.layout = QtWidgets.QVBoxLayout(self)
        self.listWidget = QtWidgets.QListWidget()
        self.remove_btn = QtWidgets.QPushButton('Remove')
        self.layout.addWidget(self.listWidget)
        self.layout.addWidget(self.remove_btn)
        self.remove_btn.clicked.connect(self.remove_items)

        self.menu = QtWidgets.QMenu(menuname)

        load_items = self.settings.value(self.key, [])
        for name, itemdata in load_items.items():
            action = QtWidgets.QAction(name, self.menu)
            action.setData(itemdata)
            self.menu.addAction(action)

            item = QtWidgets.QListWidgetItem(name)
            item.setData(QtCore.Qt.UserRole, action)
            self.listWidget.addItem(item)

    def remove_items(self):
        for item in self.listWidget.selectedItems():
            it = self.listWidget.takeItem(self.listWidget.row(item))
            action = it.data(QtCore.Qt.UserRole)
            self.menu.removeAction(action)
        self.sync_data()

    def sync_data(self):
        save_items = {}
        for i in range(self.listWidget.count()):
            it = self.listWidget.item(i)
            action = it.data(QtCore.Qt.UserRole)
            save_items[it.text()] = action.data()

        self.settings.setValue(self.key, save_items)
        self.settings.sync()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

相关问题 更多 >