Reputation: 1
I know there are some answers provided regarding the QTabWidget resize (Link 1, Link 2, and others); however, I can't get it working properly in my application.
The idea is to create a window that resizes according to the QTabWidget size. Currently, I have two tabs, and the first one has a smaller size compared with the other one.
When I press the second tab, the window size increases as intended but, if I go back to the first tab, the window doesn't shrink. I tried changing the QSizePolicy of each tab as well as resizing the tab and the window but it doesn't change the outcome.
How can I solve the fact the window doesn't shrink? Here is the code:
import os
import os.path
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QSizePolicy,
QApplication,
QLabel,
QMainWindow,
QTabWidget,
QDesktopWidget,
QRadioButton,
QLineEdit,
QVBoxLayout,
QHBoxLayout,
QGridLayout,
QWidget,
)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupMainUi()
def setupMainUi(self):
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
main_window_layout = QVBoxLayout(self.centralWidget)
self.centralWidget.setLayout(main_window_layout)
self.tabs = QTabWidget()
self.tabs.addTab(self.loadTab1(), "Tab1")
self.tabs.addTab(self.loadTab2(), "Tab2")
self.tabs.currentChanged.connect(self.updateSizes)
self.updateSizes(0)
main_window_layout.addWidget(self.tabs)
def updateSizes(self, index):
for i in range(self.tabs.count()):
if i != index:
self.tabs.widget(i).setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
self.tabs.widget(index).setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
self.tabs.widget(index).resize(self.tabs.widget(index).minimumSizeHint())
self.tabs.widget(index).adjustSize()
self.resize(self.minimumSize())
self.adjustSize()
def loadTab1(self):
self.ticketTab = QWidget()
self.ticketTab.setEnabled(False)
date_layout = QGridLayout()
self.ticket = QLabel("Number:", self)
self.ticket_number = QLineEdit()
self.ticket_number.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
date_layout.addWidget(self.ticket, 0, 0)
date_layout.addWidget(self.ticket_number, 0, 1)
self.ticketTab.setLayout(date_layout)
return self.ticketTab
def loadTab2(self):
self.familyTab = QWidget()
self.familyTab.setEnabled(False)
family_default_layout = QVBoxLayout()
self.family_default_checkbox = QRadioButton("Default")
self.family_default_checkbox.setChecked(True)
self.family_default_checkbox.setLayoutDirection(Qt.RightToLeft)
family_default_layout.addWidget(self.family_default_checkbox, alignment = Qt.AlignRight)
family_layout = QHBoxLayout()
self.family_label = QLabel("Number of Families:", self)
self.family_number = QLineEdit()
self.family_number.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.family_number.textChanged.connect(lambda:self.checkInput(self.family_number))
family_layout.addWidget(self.family_label, alignment=Qt.AlignLeft | Qt.AlignVCenter)
family_layout.addWidget(self.family_number, alignment=Qt.AlignLeft | Qt.AlignVCenter)
family_default_layout.addLayout(family_layout)
temp_family_layout = QHBoxLayout()
self.family_label_1 = QLabel("Number of Families:", self)
self.family_number_1 = QLineEdit()
self.family_number_1.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
temp_family_layout.addWidget(self.family_label_1, alignment=Qt.AlignLeft | Qt.AlignVCenter)
temp_family_layout.addWidget(self.family_number_1, alignment=Qt.AlignLeft | Qt.AlignVCenter)
family_default_layout.addLayout(temp_family_layout)
min_sub_family_layout = QHBoxLayout()
self.min_subfamily_label = QLabel("Minimum Number of SubFamilies:", self)
self.min_subfamily_number = QLineEdit()
self.min_subfamily_number.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
min_sub_family_layout.addWidget(self.min_subfamily_label, alignment=Qt.AlignLeft | Qt.AlignVCenter)
min_sub_family_layout.addWidget(self.min_subfamily_number, alignment=Qt.AlignLeft | Qt.AlignVCenter)
family_default_layout.addLayout(min_sub_family_layout)
max_sub_family_layout = QHBoxLayout()
self.max_subfamily_label = QLabel("Maximum Number of SubFamilies:", self)
self.max_subfamily_number = QLineEdit()
self.max_subfamily_number.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
max_sub_family_layout.addWidget(self.max_subfamily_label, alignment=Qt.AlignLeft | Qt.AlignVCenter)
max_sub_family_layout.addWidget(self.max_subfamily_number, alignment=Qt.AlignLeft | Qt.AlignVCenter)
family_default_layout.addLayout(max_sub_family_layout)
self.familyTab.setLayout(family_default_layout)
return self.familyTab
os.chdir("../..")
app = QApplication(sys.argv)
win = MainWindow()
qr = win.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
win.move(qr.topLeft())
win.move(win.pos().x(), win.pos().y() - 180)
win.show()
sys.exit(app.exec())
Sorry for the simple question. Only recently I have been exploring PyQT.
Upvotes: 0
Views: 1192
Reputation: 48231
QTabWidget is based on QStackedWidget, which always uses the biggest size hint of all pages.
In order to avoid that, you can override both sizeHint
and minimumSizeHint
and ensure that it only returns the current widget hint.
Then, since resizing require some internal event handling, you can ensure that the application does that by calling processEvents()
and then call adjustSize.
class ResizingTabWidget(QTabWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.currentChanged.connect(self.updateGeometry)
def minimumSizeHint(self):
return self.sizeHint()
def sizeHint(self):
current = self.currentWidget()
if not current:
return super().sizeHint()
return current.sizeHint()
class MainWindow(QMainWindow):
# ...
def setupMainUi(self):
# ...
self.tabs = ResizingTabWidget()
# ...
def updateSizes(self):
QApplication.processEvents()
self.adjustSize()
Note that you don't need to call updateSizes
in the __init__
.
Also, be aware that from the UX perspective this is not a very good approach, as UIs that continuously resize themselves are considered annoying by many and often confuse the user.
Upvotes: 1