pythonpyqtpyqt5qtabwidgetqsplitter

QTabWidget insert a QSplitter can't switch when the splitter disabled


I insert a QFrame and QTabWidget in the QSplitter. And I wanna forbidden to adjust the size of elements in QSplitter. So I call method of 'setDisabled' in QSplitter. It's useful for disabling resizing the elements. But I also can't switch tab of QTabWidget. Who can give me some suggestions? Thanks very much......

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QSplitter, QHBoxLayout, QFrame, QTabWidget
from PyQt5.QtCore import Qt
class Example1(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(0, 0, 600, 600)
        self.setWindowTitle("Demo")
        self.layout = QHBoxLayout()

        top_frame = QFrame()
        top_frame.setFrameShape(QFrame.StyledPanel)

        bottom_frame = QTabWidget(self)
        tab1 = QWidget()
        tab2 = QWidget()
        bottom_frame.setTabText(0, "Generic")
        bottom_frame.setTabText(1, "Other")
        bottom_frame.addTab(tab1, "Tab 1")
        bottom_frame.addTab(tab2, "Tab 2")

        splitter = QSplitter()
        splitter.setOrientation(Qt.Vertical)
        splitter.addWidget(top_frame)
        splitter.addWidget(bottom_frame)
        splitter.setSizes([300, 300])
        **splitter.setDisabled(True)**

        self.layout.addWidget(splitter)
        self.setLayout(self.layout)
        self.show()


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

the running result of the program


Solution

  • When you disable a widget you also disable its children, so disabling the QSplitter also disables the QTabWidget.

    A possible solution is enable or disable the handles:

    import sys
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import (
        QApplication,
        QFrame,
        QHBoxLayout,
        QSplitter,
        QSplitterHandle,
        QTabWidget,
        QWidget,
    )
    
    
    class CustomSplitter(QSplitter):
        @property
        def enabled(self):
            if not hasattr(self, "_enabled"):
                self._enabled = True
            return self._enabled
    
        @enabled.setter
        def enabled(self, d):
            self._enabled = d
            for i in range(self.count()):
                self.handle(i).setEnabled(self.enabled)
    
        def createHandle(self):
            handle = super().createHandle()
            handle.setEnabled(self.enabled)
            return handle
    
    
    class Example1(QWidget):
        def __init__(self):
            super().__init__()
            self.setGeometry(0, 0, 600, 600)
            self.setWindowTitle("Demo")
            self.layout = QHBoxLayout()
    
            top_frame = QFrame()
            top_frame.setFrameShape(QFrame.StyledPanel)
    
            bottom_frame = QTabWidget(self)
            tab1 = QWidget()
            tab2 = QWidget()
            bottom_frame.setTabText(0, "Generic")
            bottom_frame.setTabText(1, "Other")
            bottom_frame.addTab(tab1, "Tab 1")
            bottom_frame.addTab(tab2, "Tab 2")
    
            splitter = CustomSplitter()
            splitter.setOrientation(Qt.Vertical)
            splitter.addWidget(top_frame)
            splitter.addWidget(bottom_frame)
            splitter.setSizes([300, 300])
    
            splitter.enabled = False
    
            self.layout.addWidget(splitter)
            self.setLayout(self.layout)
            self.show()
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        ex = Example1()
        sys.exit(app.exec_())