0

I'm working on a PyQt5 application where I have a QTabWidget that needs to dynamically add and close tabs based on user interaction. Each tab represents a different section of information (e.g., personal details, contact details, educational details).

I've written the following code to create the tab widget and handle the dynamic addition and closing of tabs:

import sys
from PyQt5.QtWidgets import QWidget,QApplication,QFormLayout,QRadioButton,QTabWidget,QVBoxLayout,QHBoxLayout,\
    QLabel,QPushButton,QLineEdit,QCheckBox

dict_main = {'id':  {'btn1': 'personal_id','btn2':'contact_id','btn3':'eductaional_id'},
             'name':{'btn1': 'personal Details','btn2':'contact_Details','btn3':'eductaional_Details'}}
work_dict = {}

class Contact(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Contact Details")
        self.layout = QFormLayout()
        self.layout.addRow("Name", QLineEdit())
        self.layout.addRow("Address", QLineEdit())
        self.setLayout(self.layout)

class Personal(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Personal Details")
        self.layout = QFormLayout()
        self.sex = QHBoxLayout()
        self.sex.addWidget(QRadioButton("Male"))
        self.sex.addWidget(QRadioButton("Female"))
        self.layout.addRow(QLabel("Sex"), self.sex)
        self.layout.addRow("Date of Birth", QLineEdit())
        self.setLayout(self.layout)

class Educational(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Educational Details")
        self.layout = QHBoxLayout()
        self.layout.addWidget(QLabel("subjects"))
        self.layout.addWidget(QCheckBox("Physics"))
        self.layout.addWidget(QCheckBox("Maths"))
        self.setLayout(self.layout)

class TabWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTabWidget Examples")

        self.contacts = Contact()
        self.personal = Personal()
        self.educational = Educational()

        self.tabwidget_workspace_index = 0
        self.tabwidget_workspace = QTabWidget()
        self.tabwidget_workspace.setObjectName("on_tabwidget_workspace")
        self.tabwidget_workspace.setTabsClosable(True)
        self.tabwidget_workspace.setTabShape(QTabWidget.Rounded)
        self.tabwidget_workspace.setTabPosition(QTabWidget.North)
        self.tabwidget_workspace.setMovable(True)
        self.tabwidget_workspace.tabCloseRequested.connect(self.close_workspace_tab)
        self.tabwidget_workspace.setDocumentMode(True)
        self.tabwidget_workspace.setAutoFillBackground(True)

        self.layout_left = QVBoxLayout()
        self.layout_right = QVBoxLayout()
        self.layout_main = QHBoxLayout()

        self.layout_main.addLayout(self.layout_left)
        self.layout_main.addLayout(self.layout_right)
        self.setLayout(self.layout_main)

        self.layout_right.addWidget(self.tabwidget_workspace)

        for key, values in dict_main.items():
            if key == "name":
                for btn_key, btn_text in values.items():
                    work_dict.update({btn_text:btn_key})
                    button = QPushButton(btn_text, self)
                    button.clicked.connect(self.button_clicked)
                    self.layout_left.addWidget(button)

    def button_clicked(self):
        button = self.sender()
        button_text = button.text()

        if dict_main['id'].get(work_dict.get(button_text)) == "personal_id":
            self.tabwidget_workspace.addTab(self.personal,"Personal")
        elif dict_main['id'].get(work_dict.get(button_text)) == "contact_id":
            self.tabwidget_workspace.addTab(self.contacts, "Contacts")
        elif dict_main['id'].get(work_dict.get(button_text)) == "eductaional_id":
            self.tabwidget_workspace.addTab(self.educational, "Educational")

    def close_workspace_tab(self, index):
        print("close workspace tab", index)
        self.tabwidget_workspace.removeTab(index)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TabWidget()
    ex.show()
    sys.exit(app.exec_())

The code currently adds tabs correctly when the corresponding button is clicked, and I can also close tabs using the tab close button. However, I have a few questions:

  1. How can I ensure that when I click the same button multiple times, the corresponding tab is brought to focus rather than adding a new tab?

  2. Currently, when I close a tab and then try to add another tab using the same button, the program quits unexpectedly. How can I prevent this from happening and continue adding tabs without quitting the program?

I've tried various approaches, including using a dictionary to track the added tab widgets, but I'm having difficulty implementing the desired behavior.

Any insights, suggestions, or alternative approaches would be greatly appreciated. Thank you!

Rithik
  • 39
  • 6
  • Based on your code, I cannot reproduce issue #2. For #1 first check if the widget is part of the tabwidget by calling [`indexOf()`](https://doc.qt.io/qt-5/qtabwidget.html#indexOf): if it returns -1 add it, then just call [`setCurrentWidget()`](https://doc.qt.io/qt-5/qtabwidget.html#setCurrentWidget) in any case. – musicamante Jun 04 '23 at 12:32

0 Answers0