Insertion d'un onglet dans QTabWidget à partir d'une mise en page prédéfinie

Dec 04 2020

J'essaye d'ajouter des onglets à mon QTabWidget dynamiquement et la chose simple que je veux faire est de dupliquer le 1er onglet prédéfini que j'ai déjà. Maintenant, avant de m'amener à cette question: Bouton de duplication des onglets dans un QTabWidget , écoutez-moi.

Je ne souhaite pas dupliquer manuellement l'onglet. L'onglet que j'ai est détaillé et peut faire l'objet de mises à jour majeures à tout moment, je voudrais simplement le modifier dans QTDesigner puis peut-être le dupliquer dynamiquement ou simplement insérer le formulaire donné dans le QTabWidget. J'ai essayé beaucoup de choses (par exemple: essayer de créer un formulaire séparé et de l'importer, concevoir ma propre classe de page d'onglets [qui a fonctionné mais ce n'est pas ce que je recherche], copier littéralement le tabWidget et essayer de l'ajouter) mais aucun d'entre eux ne semble faire l'affaire.

J'ai juste besoin d'un onglet à insérer via une interface utilisateur prédéfinie.

ÉDITER:

Après avoir créé un formulaire via le logiciel QtDesigner et l'avoir exporté dans un fichier python, j'obtiens ce code:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'newTab.ui'
#
# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(810, 672)
        self.verticalLayout = QtWidgets.QVBoxLayout(Form)
        self.verticalLayout.setObjectName("verticalLayout")
        self.testIdFrame = QtWidgets.QFrame(Form)
        self.testIdFrame.setMinimumSize(QtCore.QSize(0, 622))
        font = QtGui.QFont()
        font.setFamily("Segoe UI Black")
        font.setBold(True)
        font.setItalic(True)
        font.setUnderline(False)
        font.setWeight(75)
        self.testIdFrame.setFont(font)
        self.testIdFrame.setStyleSheet("background: transparent;")
        self.testIdFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.testIdFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.testIdFrame.setObjectName("testIdFrame")
        self.atpDropBox = QtWidgets.QComboBox(self.testIdFrame)
        self.atpDropBox.setGeometry(QtCore.QRect(120, 20, 98, 31))
        self.atpDropBox.setObjectName("atpDropBox")
        self.snLabel = QtWidgets.QLabel(self.testIdFrame)
        self.snLabel.setGeometry(QtCore.QRect(260, 30, 32, 21))
        self.snLabel.setObjectName("snLabel")
        self.workOrderLabel = QtWidgets.QLabel(self.testIdFrame)
        self.workOrderLabel.setGeometry(QtCore.QRect(10, 30, 75, 21))
        self.workOrderLabel.setObjectName("workOrderLabel")
        self.powerSupplyLabel1 = QtWidgets.QLabel(self.testIdFrame)
        self.powerSupplyLabel1.setGeometry(QtCore.QRect(10, 70, 101, 21))
        self.powerSupplyLabel1.setObjectName("powerSupplyLabel1")
        self.snTextEdit = QtWidgets.QTextEdit(self.testIdFrame)
        self.snTextEdit.setGeometry(QtCore.QRect(300, 20, 131, 31))
        self.snTextEdit.setStyleSheet("QTextEdit {\n"
"border: 1px solid black;\n"
"border-radius:5px; \n"
"}")
        self.snTextEdit.setObjectName("snTextEdit")
        self.voltageTextEdit1 = QtWidgets.QTextEdit(self.testIdFrame)
        self.voltageTextEdit1.setGeometry(QtCore.QRect(200, 60, 101, 31))
        self.voltageTextEdit1.setAutoFillBackground(False)
        self.voltageTextEdit1.setStyleSheet("QTextEdit {\n"
"border: 1px solid black;\n"
"border-radius:5px; \n"
"}")
        self.voltageTextEdit1.setObjectName("voltageTextEdit1")
        self.voltageLabel1 = QtWidgets.QLabel(self.testIdFrame)
        self.voltageLabel1.setGeometry(QtCore.QRect(120, 70, 71, 21))
        self.voltageLabel1.setObjectName("voltageLabel1")
        self.voltageLabel2 = QtWidgets.QLabel(self.testIdFrame)
        self.voltageLabel2.setGeometry(QtCore.QRect(120, 110, 71, 21))
        self.voltageLabel2.setObjectName("voltageLabel2")
        self.voltageTextEdit2 = QtWidgets.QTextEdit(self.testIdFrame)
        self.voltageTextEdit2.setGeometry(QtCore.QRect(200, 100, 101, 31))
        self.voltageTextEdit2.setAutoFillBackground(False)
        self.voltageTextEdit2.setStyleSheet("QTextEdit {\n"
"border: 1px solid black;\n"
"border-radius:5px; \n"
"}")
        self.voltageTextEdit2.setObjectName("voltageTextEdit2")
        self.powerSupplyLabel2 = QtWidgets.QLabel(self.testIdFrame)
        self.powerSupplyLabel2.setGeometry(QtCore.QRect(10, 110, 101, 21))
        self.powerSupplyLabel2.setObjectName("powerSupplyLabel2")
        self.currentLabel2 = QtWidgets.QLabel(self.testIdFrame)
        self.currentLabel2.setGeometry(QtCore.QRect(310, 110, 81, 21))
        self.currentLabel2.setObjectName("currentLabel2")
        self.currentLabel1 = QtWidgets.QLabel(self.testIdFrame)
        self.currentLabel1.setGeometry(QtCore.QRect(310, 70, 91, 21))
        self.currentLabel1.setObjectName("currentLabel1")
        self.currentTextEdit1 = QtWidgets.QTextEdit(self.testIdFrame)
        self.currentTextEdit1.setGeometry(QtCore.QRect(400, 60, 101, 31))
        self.currentTextEdit1.setAutoFillBackground(False)
        self.currentTextEdit1.setStyleSheet("QTextEdit {\n"
"border: 1px solid black;\n"
"border-radius:5px; \n"
"}")
        self.currentTextEdit1.setObjectName("currentTextEdit1")
        self.currentTextEdit2 = QtWidgets.QTextEdit(self.testIdFrame)
        self.currentTextEdit2.setGeometry(QtCore.QRect(400, 100, 101, 31))
        self.currentTextEdit2.setAutoFillBackground(False)
        self.currentTextEdit2.setStyleSheet("QTextEdit {\n"
"border: 1px solid black;\n"
"border-radius:5px; \n"
"}")
        self.currentTextEdit2.setObjectName("currentTextEdit2")
        self.verticalLayout.addWidget(self.testIdFrame)
        self.RXFrame = QtWidgets.QFrame(Form)
        self.RXFrame.setStyleSheet("background: transparent;")
        self.RXFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.RXFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.RXFrame.setObjectName("RXFrame")
        self.verticalLayout.addWidget(self.RXFrame)
        self.TXFrame = QtWidgets.QFrame(Form)
        self.TXFrame.setStyleSheet("background: transparent;")
        self.TXFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.TXFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.TXFrame.setObjectName("TXFrame")
        self.verticalLayout.addWidget(self.TXFrame)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.snLabel.setText(_translate("Form", "SN:"))
        self.workOrderLabel.setText(_translate("Form", "Work Order:"))
        self.powerSupplyLabel1.setText(_translate("Form", "Power Supply 1:"))
        self.voltageLabel1.setText(_translate("Form", "Voltage [V]:"))
        self.voltageLabel2.setText(_translate("Form", "Voltage [V]:"))
        self.powerSupplyLabel2.setText(_translate("Form", "Power Supply 2:"))
        self.currentLabel2.setText(_translate("Form", "Current [mA]:"))
        self.currentLabel1.setText(_translate("Form", "Current [mA]:"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

Dans ma classe MainWindow, j'importe l'Ui_Form du fichier python nouvellement généré qui contient le contenu du nouvel onglet que je voudrais dupliquer. C'est là que je suis bloqué .. J'appelle la fonction qui construira mes onglets pour moi:

def buildTabs(self, numberOfTabs): 
    for dut in range(numberOfTabs): 
        text = ('TAB ' + ascii_uppercase[dut]) 
        self.ui.tabWidget.addTab(Ui_Form(), text)

Le widget onglet se trouve dans l'interface utilisateur de la fenêtre principale.

Je ne comprends pas comment je peux transformer l'Ui_Form () en une Ui_TabPage ou un QWidget comme indiqué dans cette question

Formulaire du concepteur QT:

entrez la description de l'image ici

Réponses

musicamante Dec 04 2020 at 02:57

Les fichiers générés par pyuic sont des classes de formulaire , ce sont en fait des objectclasses python standard , et ils ont besoin d'une instance de QWidget (ou de toute autre classe utilisée dans Designer pour cette ui, telle qu'un QDialog) pour les «construire».

def buildTabs(self, numberOfTabs): 
    for dut in range(numberOfTabs): 
        page = QtWidgets.QWidget()
        page.ui = Ui_Form()
        page.ui.setupUi(page)        
        text = ('TAB ' + ascii_uppercase[dut])
        self.ui.tabWidget.addTab(page, text)

Considérez que PyQt et PySide ne peuvent pas être mélangés, donc si vous utilisez PyQt, la commande est pyuic, tandis qu'avec PySide, la commande est pyside2-uic.

Notez que si vous avez besoin d'une interaction supplémentaire avec les pages à onglets , il est généralement préférable de les sous-classer:

class PageOne(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.ui.someButton.clicked.connect(self.someFunction)
        # ...

Ou mieux, avec la méthode d'héritage multiple, qui évite d'accéder en permanence aux éléments de l'interface utilisateur via le ui"sous-objet":

class PageOne(QtWidgets.QWidget, Ui_Form):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.someButton.clicked.connect(self.someFunction)
        # ...

Et alors:

def buildTabs(self, numberOfTabs): 
    for dut in range(numberOfTabs): 
        page = PageOne()
        text = ('TAB ' + ascii_uppercase[dut])
        self.ui.tabWidget.addTab(page, text)