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:
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?
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!