How to populate/store new items for different tabs


#1

Hi all, I am trying to achieve a right-mouse click menu where if User choose to add in new items, these new items will be populated right under the ‘Add New Item’…

The design is something as follows:

|  Add New Item   |
-------------------
|   New Item 01   |
|   New Item 02   |
-------------------
| Default Item 01 |

If the QMenu is ‘new’, by default it will looks somethings like this:

|  Add New Item   |
-------------------
| Default Item 01 |

In my current code, as I am integrating this with the tabs, I am having issues where:

  • unable to store the different new created items per tab, currently all tabs are using the same QMenu
  • default items are getting populated more than once per right-mouse click

This is my code:

class TabBar(QtGui.QTabBar):
    def __init__(self, parent=None):
        super(TabBar, self).__init__(parent)

        self.qmenu = QtGui.QMenu()
        self.setExpanding(False)

        add_item_action = QtGui.QAction('Add new item', self,
            triggered=self.add_new_item)
        self.qmenu.addAction(add_item_action)
        self.qmenu.addSeparator()

        self.separator =  self.qmenu.addSeparator()

    def tabSizeHint(self, index):
        return super(TabBar, self).tabSizeHint(index)

    def mousePressEvent(self, event):
        index = self.tabAt(event.pos())
        if event.button() == QtCore.Qt.RightButton:
            self._showContextMenu(event.pos(), index)
        else:
            super(TabBar, self).mousePressEvent(event)

    def _showContextMenu(self, position, index):
        # Default items
        def_item_01 = self.qmenu.addAction("Default Item A")
        def_item_02 = self.qmenu.addAction("Default Item B")

        global_position = self.mapToGlobal(self.pos())
        self.qmenu.exec_(QtCore.QPoint(
            global_position.x() - self.pos().x() + position.x(),
            global_position.y() - self.pos().y() + position.y()
        ))


    @QtCore.Slot()
    def add_new_item(self):
        new_item_name, ok = QtGui.QInputDialog.getText(
            self,
            "name of item",
            "Name of new item : "
        )
        if ok:
            new_action = QtGui.QAction(new_item_name, self.qmenu, checkable=True)
            self.qmenu.insertAction(self.separator, new_action)


class TabWidget(QtGui.QTabWidget):
    def __init__(self, parent=None):
        super(TabWidget, self).__init__(parent)
        self.setTabBar(TabBar(self))

    def resizeEvent(self, event):
        self.tabBar().setMinimumWidth(self.width())
        super(TabWidget, self).resizeEvent(event)


class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.tabs = TabWidget(self)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.tabs)

        some_tabs = ['TabA', 'TabB', 'TabC', 'TabD']
        for my_tab in some_tabs:
            self.tabs.addTab(QtGui.QWidget(self), my_tab)

Appreciate in advance for any insights!