Sahil
Sahil

Reputation: 47

PyQt5 Different Grids on Different Tabs

I am trying to design a GUI interface that will have two Tabs both Tabs have there own Grid. However, I am getting this GUI Look;

Here is my code:

class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.setupUi()

    def generate_pstest_tab_elements(self,str1):
        groupBox = QGroupBox(str1)
        label1 = QLabel(self)
        label1.setText('Serial No:')
        line1 = QLineEdit(self)
        line1.setText("XXXX")
        label2 = QLabel(self)
        label2.setText('Chip ID:')
        line2 = QLineEdit(self)
        line2.setText("XXXX")
        rd_group = QButtonGroup()
        rdbtn_FCB15 = QRadioButton("FCB-15")
        rdbtn_DCB15 = QRadioButton("DCB-15")
        rd_group.addButton(rdbtn_FCB15)
        rd_group.addButton(rdbtn_FCB15)

        layout1 = QFormLayout()
        layout1.addRow(label1,line1)
        layout1.addRow(label2,line2)
        layout1.addRow(rdbtn_FCB15,rdbtn_DCB15)

        grid1 = QGridLayout()

        grid1.addWidget(label1,0,0)
        grid1.addWidget(line1,0,1)

        grid1.addWidget(rdbtn_FCB15,0,2)
        grid1.addWidget(rdbtn_DCB15,0,3)

        grid1.addWidget(label2,1,0)
        grid1.addWidget(line2,1,1)

        groupBox.setLayout(grid1)

        return groupBox

    def generate_pscalib_tab_elements(self,str1):
        groupBox = QGroupBox(str1)
        label1 = QLabel(self)
        label1.setText('Serial No:')
        line1 = QLineEdit(self)
        line1.setText("XXXX")
        label2 = QLabel(self)
        label2.setText('Chip ID:')
        line2 = QLineEdit(self)
        line2.setText("XXXX")
        label3 = QLabel(self)
        label3.setText('QR Code:')
        line3 = QLineEdit(self)
        line3.setText("XXXX")
        label4 = QLabel(self)
        label4.setText('Current Range:')
        line4 = QLineEdit(self)
        line4.setText("1.0")
        label5 = QLabel(self)
        label5.setText("PS Offset")
        line5 = QLineEdit(self)
        line5.setText("0.0")
        line5.setReadOnly(True)
        label6 = QLabel()
        label6.setText("PSGain")
        line6 = QLineEdit(self)
        line6.setText("1.0")
        line6.setReadOnly(True)

        grid2 = QGridLayout()

        grid2.addWidget(label1,0,0)
        grid2.addWidget(line1,0,1)

        grid2.addWidget(label2,1,0)
        grid2.addWidget(line2,1,1)

        grid2.addWidget(label3,2,0)
        grid2.addWidget(line3,2,1)

        grid2.addWidget(label4,3,0)
        grid2.addWidget(line4,3,1)

        grid2.addWidget(label5,4,0)
        grid2.addWidget(line5,4,1)

        grid2.addWidget(label6,5,0)
        grid2.addWidget(line6,5,1)
        groupBox.setLayout(grid2)        
        return groupBox

    def setupUi(self):

            self.title = 'BiPolar Power Supply Testing'
            self.setWindowTitle(self.title)             
            print (self.title)
            self.left = 50
            self.top = 50
            self.width = 1000
            self.height = 800

            self.PSTestTabGrid = QGridLayout()
            self.PSCalibTabGrid = QGridLayout()
            #self.setGeometry(self.left, self.top, self.width, self.height)

            #Create one main box that will hold all the tabs
            self.mainbox = QFormLayout()

            ##################### Items for PS Functional Test Tab #################

            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS1"), 0,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS2"), 1,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS3"), 2,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS4"), 3,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS5"), 4,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS6"), 5,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS7"), 6,0)
            self.PSTestTabGrid.addWidget(self.generate_pstest_tab_elements("PS8"), 7,0)

            self.PSFStart_btn = QPushButton("Start",self)
            self.PSFStop_btn = QPushButton("Stop",self)

            self.PSTestTabGrid.addWidget(self.PSFStart_btn,8,0)
            self.PSTestTabGrid.addWidget(self.PSFStop_btn,9,0)


            ##################### Items for PS Calib Tab #################

            self.PSCalibTabGrid.addWidget(self.generate_pscalib_tab_elements("PS"), 0,0)

            self.PSCalibStart_btn = QPushButton("Calib Start",self)
            self.PSCalibStop_btn = QPushButton("Calib Stop",self)

            self.PSCalibTabGrid.addWidget(self.PSCalibStart_btn,1,0)
            self.PSCalibTabGrid.addWidget(self.PSCalibStop_btn,2,0)

            ######################################################################
            #Init Tab Screen
            self.tabs = QTabWidget()
            self.tab1 = QWidget()
            self.tab2 = QWidget()

            #Add Tab
            self.tabs.addTab(self.tab1, "PS Tests")
            self.tabs.addTab(self.tab2, "PS Calib")

            #Set Layout for tab1, tab2
            self.tab1.setLayout(self.PSTestTabGrid)
            self.tab2.setLayout(self.PSCalibTabGrid)

            #Add the Tabs widget to MainBox
            self.mainbox.addWidget(self.tabs)

            #self.mainbox.addRow(self.tab2HBox)
            self.wid = QWidget(self)
            self.setCentralWidget(self.wid)
            #layout = QtGui.QVBoxLayout()
            self.wid.setLayout(self.mainbox)

There are two functions that are being called from SetupUi().

  1. First function is to generate layout for Tab1 by calling generate_pstest_tab_elements()
  2. Second function is to generater layout for Tab2 by calling generate_pscalib_tab_elements()

The spacing between different widgets on Tab2 is very large. I tried calling setVerticalSpacing() to shrink the vertical spacing but it doesnt shrink either.

However If I commment out Tab1 items such that Tab1 doesnt contain any widget then Tab2 items look fine. It seems like Qt is some how confused between the two independent Grids ?

Attached are the snapshots of the two tabs.

Tab1 image

Tab2 image

Upvotes: 1

Views: 391

Answers (1)

eyllanesc
eyllanesc

Reputation: 244132

Each tab takes the size of the previous tab shown, and in the case of the first tab shown the available size will be used, if you want the smallest size to be taken then you must establish a stretch at the end using a QVBoxLayout.

Considering the above, the solution is:

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("BiPolar Power Supply Testing")

        tab_widget = QtWidgets.QTabWidget()
        self.setCentralWidget(tab_widget)

        pstest_widget = QtWidgets.QWidget()
        tab_widget.addTab(pstest_widget, "PS Tests")

        pstest_vlay = QtWidgets.QVBoxLayout(pstest_widget)

        for i in range(1, 9):
            title = "PS{}".format(i)
            group_box = MainWindow.create_pstest_element(title)
            pstest_vlay.addWidget(group_box)

        self.PSFStart_btn = QtWidgets.QPushButton("Start")
        self.PSFStop_btn = QtWidgets.QPushButton("Stop")
        pstest_vlay.addWidget(self.PSFStart_btn)
        pstest_vlay.addWidget(self.PSFStop_btn)
        pstest_vlay.addStretch()

        pscalib_widget = QtWidgets.QWidget()
        tab_widget.addTab(pscalib_widget, "PS Calib")

        pscalib_vlay = QtWidgets.QVBoxLayout(pscalib_widget)

        group_box = MainWindow.create_pscalib_element("PS")
        self.PSCalibStart_btn = QtWidgets.QPushButton("Calib Start")
        self.PSCalibStop_btn = QtWidgets.QPushButton("Calib Stop")

        pscalib_vlay.addWidget(group_box)
        pscalib_vlay.addWidget(self.PSCalibStart_btn)
        pscalib_vlay.addWidget(self.PSCalibStop_btn)
        pscalib_vlay.addStretch()

    @staticmethod
    def create_pstest_element(title):
        group_box = QtWidgets.QGroupBox(title)
        grid = QtWidgets.QGridLayout()
        group_box.setLayout(grid)

        serial_label = QtWidgets.QLabel("Serial No:")
        serial_lineedit = QtWidgets.QLineEdit("XXXX")

        chipid_label = QtWidgets.QLabel("Chip ID:")
        chipid_lineedit = QtWidgets.QLineEdit("XXXX")

        rd_group = QtWidgets.QButtonGroup()
        rdbtn_FCB15 = QtWidgets.QRadioButton("FCB-15")
        rdbtn_DCB15 = QtWidgets.QRadioButton("DCB-15")

        grid.addWidget(serial_label, 0, 0)
        grid.addWidget(serial_lineedit, 0, 1)

        grid.addWidget(rdbtn_FCB15, 0, 2)
        grid.addWidget(rdbtn_DCB15, 0, 3)

        grid.addWidget(chipid_label, 1, 0)
        grid.addWidget(chipid_lineedit, 1, 1)

        return group_box

    @staticmethod
    def create_pscalib_element(title):
        group_box = QtWidgets.QGroupBox(title)
        flay = QtWidgets.QFormLayout()
        group_box.setLayout(flay)

        serial_lineedit = QtWidgets.QLineEdit("XXXX")
        chipid_lineedit = QtWidgets.QLineEdit("XXXX")
        qrcode_lineedit = QtWidgets.QLineEdit("XXXX")
        range_lineedit = QtWidgets.QLineEdit("1.0")
        offset_lineedit = QtWidgets.QLineEdit("0.0", readOnly=True)
        gain_lineedit = QtWidgets.QLineEdit("1.0", readOnly=True)

        flay.addRow("Serial No:", serial_lineedit)
        flay.addRow("Chip ID:", chipid_lineedit)
        flay.addRow("QR Code:", qrcode_lineedit)
        flay.addRow("Current Range:", range_lineedit)
        flay.addRow("PS Offset:", offset_lineedit)
        flay.addRow("PS Gain:", gain_lineedit)

        return group_box


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

If you want to continue using QGridLayout then the solution is to place it inside a QVBoxLayout:

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("BiPolar Power Supply Testing")

        tab_widget = QtWidgets.QTabWidget()
        self.setCentralWidget(tab_widget)

        pstest_widget = QtWidgets.QWidget()
        tab_widget.addTab(pstest_widget, "PS Tests")

        grid_lay_1 = QtWidgets.QGridLayout(pstest_widget)
        pstest_vlay = QtWidgets.QVBoxLayout()
        grid_lay_1.addLayout(pstest_vlay, 0, 0)

        for i in range(1, 9):
            title = "PS{}".format(i)
            group_box = MainWindow.create_pstest_element(title)
            pstest_vlay.addWidget(group_box)

        self.PSFStart_btn = QtWidgets.QPushButton("Start")
        self.PSFStop_btn = QtWidgets.QPushButton("Stop")
        pstest_vlay.addWidget(self.PSFStart_btn)
        pstest_vlay.addWidget(self.PSFStop_btn)
        pstest_vlay.addStretch()

        pscalib_widget = QtWidgets.QWidget()
        tab_widget.addTab(pscalib_widget, "PS Calib")

        grid_lay_2 = QtWidgets.QGridLayout(pscalib_widget)

        pscalib_vlay = QtWidgets.QVBoxLayout()
        grid_lay_2.addLayout(pscalib_vlay, 0, 0)

        group_box = MainWindow.create_pscalib_element("PS")
        self.PSCalibStart_btn = QtWidgets.QPushButton("Calib Start")
        self.PSCalibStop_btn = QtWidgets.QPushButton("Calib Stop")

        pscalib_vlay.addWidget(group_box)
        pscalib_vlay.addWidget(self.PSCalibStart_btn)
        pscalib_vlay.addWidget(self.PSCalibStop_btn)
        pscalib_vlay.addStretch()
    # ...

Upvotes: 2

Related Questions