Search code examples
pythonpyqtpyqt4qtabwidget

pyqt4 QTabWidget addtab unsuccessful


I'm use pyqt4,this is my code

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *


class View(QWidget):
    def __init__(self):
        super(View, self).__init__()

        self.hbox = QHBoxLayout()

        self.study_box = QVBoxLayout()

        self.study_box.addWidget(QLabel('dsadasdasd'))

        self.hbox.addLayout(self.study_box)

        self.setLayout(self.hbox)


class Model(QWidget):
    def __init__(self):
        super(Model, self).__init__()

    def func(self):
        Tab().add_tab('sd')


class Tab(QTabWidget):
    _instance = None

    def __new__(cls, *args, **kw):
        if cls._instance is None:
            cls._instance = QWidget.__new__(cls, *args, **kw)
        return cls._instance

    def __init__(self):
        super(Tab, self).__init__()
        label = QPushButton('asd')
        self.addTab(label, 'asd')
        #method one,  added successfully
        # label.clicked.connect(lambda: self.add_tab('dsd'))
        #method two,  added unsuccessfully
        label.clicked.connect(lambda: Model().func())

    def add_tab(self, data):
        # for x in range(self.count()):
        #     self.removeTab(0)

        self.addTab(View(), data)
        self.addTab(View(), data)
        self.addTab(View(), data)
        self.setCurrentIndex(1)


class Demo(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(0, 25, 2500, 1500)

        wg = QWidget()
        hbox = QHBoxLayout()
        hbox.addWidget(Tab())

        wg.setLayout(hbox)
        self.setCentralWidget(wg)
        self.setWindowState(Qt.WindowMaximized)
        self.show()


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

My requirement is that when I click the button of the first tab, he should add a tab to the interface. However, it does not have it. I am very confused. It clearly calls the add_tab function, but it does not add it to the interface. The structure of the class cannot be changed, because this is my code in the project, how do I get the implementation requirements?


Solution

  • Your code has the following errors:

    • According to what you indicate in the comments you want the Tab class to be a Singleton but your code is not. To solve it I used my previous answer.

    • The Tab class that inherits from QTabWidget does not have any attribute called tabs, you must use addTab.

    • It is not necessary for Model to inherit from QWidget, if you want it to be used to issue signals it is enough that it is a QObject, on the other hand if you want it to be a singleton you just have to change it to class Model(QObject, metaclass=Singleton):.

    Considering the above, the solution is:

    import sys
    
    from PyQt4.QtCore import QObject, Qt
    from PyQt4.QtGui import (
        QApplication,
        QHBoxLayout,
        QLabel,
        QMainWindow,
        QPushButton,
        QTabWidget,
        QVBoxLayout,
        QWidget,
    )
    
    
    class Singleton(type(QObject), type):
        def __init__(cls, name, bases, dict):
            super().__init__(name, bases, dict)
            cls._instance = None
    
        def __call__(cls, *args, **kwargs):
            if cls._instance is None:
                cls._instance = super().__call__(*args, **kwargs)
            return cls._instance
    
    
    class View(QWidget):
        def __init__(self):
            super(View, self).__init__()
            self.hbox = QHBoxLayout(self)
            self.study_box = QVBoxLayout()
            self.study_box.addWidget(QLabel("dsadasdasd"))
            self.hbox.addLayout(self.study_box)
    
    
    class Model(QObject, metaclass=Singleton):
        def func(self):
            Tab().add_tab("sd")
    
    
    class Tab(QTabWidget, metaclass=Singleton):
        def __init__(self):
            super(Tab, self).__init__()
            label = QPushButton("asd")
            self.addTab(label, "asd")
            model = Model()
            label.clicked.connect(model.func)
    
        def add_tab(self, data):
            index = self.addTab(View(), data)
    
    
    class Demo(QMainWindow):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.setGeometry(0, 25, 2500, 1500)
            wg = QWidget()
            hbox = QHBoxLayout(wg)
            hbox.addWidget(Tab())
            self.setCentralWidget(wg)
            self.setWindowState(Qt.WindowMaximized)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        demo = Demo()
        demo.show()
        sys.exit(app.exec_())
    

    Note: I have assumed many things deducing that you want to implement the MVC pattern (or one of its variants) since in your question you do not give many details.