Richard
Richard

Reputation: 555

Update PyQt menu

I am trying to dynamically update a menu with new items when I add new items via the form into Qsettings. For example, if you open my code and click the button and then click "new" it will open a QLineEdit with a button. When the button is clicked the list data gets stored via Qsettings.
I'd like to be able to update the menu somehow to show the items without restarting. I tried some things like calling repaint and update in a few areas with no luck.
Here is my code, I slimmed it down the best that I could for the example.

import functools
import sys
from PyQt5 import QtCore
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QPushButton, QHBoxLayout, \
    QVBoxLayout, QLineEdit,QApplication, QWidgetAction, QTextBrowser, QAction, QMenu

class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.layout = QHBoxLayout()
        self.menu_action = QAction(QIcon("icon.png"),"New", self)
        self.menu_btn = QPushButton()
        self.menu = MyMenu("Menu", self.menu_btn)
        self.add_menu = self.menu.addMenu(QIcon("icon.png"), "Menu")
        self.add_menu.addAction(self.menu_action)
        self.menu_btn.setMenu(self.menu)
        self.textBox = QTextBrowser(self)
        action = QWidgetAction(self.menu_btn)
        action.setDefaultWidget(self.textBox)
        self.menu_btn.menu().addAction(action)

        settings = QtCore.QSettings('test_org', 'my_app')
        self.new_items = settings.value('new_item', [])
        print('%s' % self.new_items)

        for item in self.new_items:
            self.create_action = QAction(QIcon("icon.png"), item[0], self)
            self.create_action.setData(item)
            self.add_menu.addAction(self.create_action)
            self.create_action.triggered.connect(functools.partial(self.menu_clicked, self.create_action))

        self.layout.addWidget(self.menu_btn)
        self.setLayout(self.layout)
        self.menu_action.triggered.connect(self.open_window)

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

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

class Create_Menu_Item(QWidget):
    def __init__(self, parent=None):
        super(Create_Menu_Item, self).__init__(parent)
        self.resize(200, 195)
        self.layout = QVBoxLayout()
        self.form = QLineEdit()
        self.btn = QPushButton()
        self.layout.addWidget(self.form)
        self.layout.addWidget(self.btn)
        self.btn.clicked.connect(self.save_new_item)
        self.setLayout(self.layout)

    def save_new_item(self):
        settings = QtCore.QSettings('test_org', 'my_app')
        self.new_item = settings.value('new_item', [])
        self.new_item.append([self.form.text()])
        settings.setValue('new_item', self.new_item)
        print(self.new_item)
        print('saved!')

class MyMenu(QMenu):
    def event(self,event):
        if event.type() == QtCore.QEvent.Show:
            self.move(self.parent().mapToGlobal(QtCore.QPoint(0,0))-QtCore.QPoint(0,self.height()))
        return super(MyMenu,self).event(event)

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

Anyone have any ideas? Thanks.

Upvotes: 2

Views: 707

Answers (1)

johnashu
johnashu

Reputation: 2211

You can create a for loop to access the list.

Bare in mind it is a list of lists so a nested for loop is neccessary

def save_new_item(self):
    settings = QtCore.QSettings('test_org', 'my_app')
    self.new_item = settings.value('new_item', [])
    self.new_item.append([self.form.text()])
    settings.setValue('new_item', self.new_item)
    print(self.new_item)
    print('saved!')

    # Add new menu items..
    for x in self.new_item:
        for y in x:
            print(y)

The above will keep adding the WHOLE list of items every time you add a new item..

To just add the newest item, this is all you need (the last item added to the list)

 w.add_menu.addAction(self.new_item[0][-1])

so

def save_new_item(self):
    settings = QtCore.QSettings('test_org', 'my_app')
    self.new_item = settings.value('new_item', [])
    self.new_item.append([self.form.text()])
    settings.setValue('new_item', self.new_item)
    print(self.new_item)
    print('saved!')

    #ADD last item in the list        
    w.add_menu.addAction(self.new_item[0][-1])

Upvotes: 1

Related Questions