1

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?

redj
  • 171
  • 1
  • 10
  • 1
    What do you mean with "it's addTab unsuccessful"? Also, from your code, it seems correct that `res` is equal to 1, as there was only one tab before ("patients_tab"). Anyway, you should provide us a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), otherwise it would be difficult to help you. – musicamante Dec 31 '19 at 15:11
  • It is not displayed on the interface, do I need to refresh the interface? – redj Jan 02 '20 at 00:41
  • As I said, you should edit your question by providing an MRE (it *has* to be reproducible, meaning that we should be able to copy, paste and run it by ourselves), otherwise we can't help you much with it. Besides that, I really don't understand the need of overriding `__new__`, and even if you really require that, you should: 1. explain that need, possibly with code/comments that justify it; 2. remember that, according to your code, `self._Tab` refers to the **class**, not its newly created instance. – musicamante Jan 02 '20 at 00:56
  • The new method was added because I called an instance of this class in many other modules, but they wanted to share the same set of data, so I added the new method so that the created instance is the data of the same object no matter where it is. I re-edited the question, this is a copyable run, thanks – redj Jan 02 '20 at 01:27
  • Just now, I re-edited the code on the question – redj Jan 02 '20 at 01:39

1 Answers1

1

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.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • I followed your thoughts to solve the problem. The reason is that there is a problem with my singleton. I implemented the singleton with your method. He works normally. Thank you very much for your help. This problem has troubled me for a long time. Thanks a lot – redj Jan 02 '20 at 02:10