Удаление динамически созданных элементов Qmenu

DB to C #

EnumDisplayStatus status = (EnumDisplayStatus)int.Parse(GetValueFromDb());

C # в DB

string dbStatus = ((int)status).ToString();
1
задан eyllanesc 14 July 2018 в 01:58
поделиться

2 ответа

Я думаю, что структура данных, которую вы используете, неверна, потому что, когда я исполняю ваш код, она генерирует в два раза больше QAction s, я предлагаю структуру, где ключи - это имя QAction и значение списка данных:

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

Для построения начальной конфигурации используйте следующий скрипт:

create_settings.py

from PyQt5 import QtCore

if __name__ == '__main__':
    settings = QtCore.QSettings('test_org', 'my_app')
    d = {}
    for i in range(5):
        key = "item{}".format(i)
        value = ["itemdata{}{}".format(i, j) for j in range(3)]
        d[key] = value
    settings.setValue('menu_items', d)
    print(d)
    settings.sync()

С другой стороны Я думаю, что виджет, который вы хотите обработать уничтожением QAction s, должен взять на себя соответствующий QMenu, как показано ниже:

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_())
2
ответ дан eyllanesc 17 August 2018 в 12:06
поделиться
  • 1
    Я только что опубликовал свой ответ, но я займу несколько минут, чтобы пройти через ваши. – Richard 14 July 2018 в 01:34
  • 2
    @Richard Как отмечено в комментариях, ваш метод может завершиться неудачей. – eyllanesc 14 July 2018 в 01:36
  • 3
    Да, я понимаю, что я не был уверен, что кто-то собирается ответить и отправил мой ответ, как через 9 секунд после вас. Я ценю вашу помощь, и сейчас я проверю ваш ответ. – Richard 14 July 2018 в 01:38
  • 4
    @Richard ждать 2 часа - это короткое время, чтобы думать, что никто не ответит, с другой стороны, публикация ответа всегда хороша, но также лучше указать ограничения, чтобы тот, кто хочет использовать ваше решение, будет знать, что может потерпеть неудачу. Если мой ответ поможет вам, не забудьте отметить его как правильно :) – eyllanesc 14 July 2018 в 01:41
  • 5
    Спасибо за помощь, Гораздо лучший ответ, чем мой. – Richard 14 July 2018 в 01:50

Я понял. Я не уверен в лучшем способе, но я сделал это с использованием имен объектов. В MainWindow я устанавливаю objectNames в self.action, используя первый элемент каждого списка в списке списков внутри цикла for следующим образом:

self.action.setObjectName(item[0])

Затем я создал эту функцию в классе MainWindow:

def remove_menu_item(self, value):
    self.add_menu.removeAction(self.findChild(QAction, value))

Затем я добавил следующее:

w.remove_menu_item(item.text())

К функции remove в классе List, чтобы получить тот же самый первый элемент в списке списков, который теперь является objectName для QActions.

0
ответ дан Richard 17 August 2018 в 12:06
поделиться
  • 1
    использование вашего метода может завершиться неудачно, например, когда у вас есть QMenu, у которого есть QAction с тем же текстом, что и другой QAction, принадлежащий другому QMenu. – eyllanesc 14 July 2018 в 01:35
Другие вопросы по тегам:

Похожие вопросы: