pythonpyqt5qtablewidgetpyqt6qgridlayout

Adding QTableWidget and QLabel with Pixmap side by side using PyQt6


I am trying to build a GUI with PyQt6 in python where I create a table and an image to the right inside a tab.

For some reason it creates the table occupying the entire screen and does not show the QLabel (for now I am using text as a placeholder).

def set_tab_info(self, num_rows): # Sets the structure for each tab
    self.num_rows = num_rows
    tab_info = [
        {"name": "Junction", "columns": 11, "header_labels": ["Type", "X", "Shear Plane Location", "Fastener Position", "Bolt/Screw", "Under head", "Thread",
                                                              "Minimum friction coefficient under bolt head", "Maximum friction coefficient under bolt head",
                                                              "Minimum friction coefficient on thread", "Maximum friction coefficient on thread"],
        "editor_types": ["combo_box", "combo_box", "combo_box", "combo_box", "combo_box", "combo_box", "combo_box", "line_edit", "line_edit", "lined_edit", "line_edit"]},
        {"name": "Screw", "columns": 7, "header_labels": ["Type of Screw", "Nominal Diameter", "Material of Screw", "g",
                                                           "Is there a change in diameter (shank)?", "Shank Length", "Shank Diameter"],
        "editor_types": ["combo_box", "line_edit", "combo_box", "line_edit", "combo_box", "line_edit", "line_edit"]},
        {"name": "Plate", "columns": 9, "header_labels": ["Material Plate 1 (Fastener Head)", "Material Plate 2", "muc", "Type of Hole", "Diameter of Hole",
                                                          "Plate 1 Thickness", "Plate 2 Thickness", "Plate 1 Minimum Shear-out Length", "Plate 2 Minimum Shear-out Length"],
        "editor_types": ["combo_box", "combo_box", "line_edit", "combo_box", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]},
        {"name": "Nut/Insert", "columns": 8, "header_labels": ["Nut/Insert", "Type of Nut", "Type of Insert", "Diameter", "Height",
                                                                "Material of Nut/Insert", "Maximum Prevailing Torque", "Minimum Prevailing Torque"],
        "editor_types": ["combo_box", "combo_box", "combo_box", "line_edit", "line_edit", "combo_box", "line_edit", "line_edit"]},
        {"name": "Washer", "columns": 11, "header_labels": ["Type of Washer", "Washer present under bolt head?", "Washer present under nut?", "External Diameter (under head)",
                                                            "internal diameter (under head)", "External diameter (under nut)", "internal diameter (under nut)", "Height (under head)",
                                                            "Height (under nut)", "Maximum Prevailing Torque", "Minimum Prevailing Torque"],
        "editor_types": ["combo_box", "combo_box", "combo_box", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]},
        {"name": "Loads", "columns": 9, "header_labels": ["Fkreq", "Kkreq", "DT+", "DT-", "CTEc", "CTEb", "Mnom", "External Shear Load", "External Tension Load"],
        "editor_types": ["line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]},
        {"name": "Safety Factors", "columns": 12, "header_labels": ["Bearing Factor", "Kq", "Km", "Kp", "KLD", "Yield", "Ultimate", "Gapping", "Slippage", "Embedding", "omega", "epsilon"],
        "editor_types": ["line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]}
    ]
    self.create_tabs(tab_info)
    
def create_tabs(self, tab_info): # Creates each tab by receiving the structure from the set_tab_info method
    self.column_inputs = {}
    
    for info in tab_info:
        tab_widget = QWidget()
        tab_layout = QGridLayout(tab_widget)
        
        horizontal_layout = QGridLayout()
        
        table = QTableWidget(self.num_rows, info["columns"])
        table.setHorizontalHeaderLabels(info["header_labels"])
        
        for row in range(self.num_rows):
            for col in range(info["columns"]):
                if info["editor_types"][col] == "line_edit":
                    item = QLineEdit()
                    table.setCellWidget(row, col, item)
                    self.column_inputs[(info["name"], info["header_labels"][col])] = item
                elif info["editor_types"][col] == "combo_box":
                    item = QComboBox()
                    item.addItems(self.get_combo_box_items(info["header_labels"][col]))
                    table.setCellWidget(row, col, item)
                    self.column_inputs[(info["name"], info["header_labels"][col])] = item
                else:
                    item = QTableWidgetItem()
                    
                table.setItem(row, col, QTableWidgetItem())
                
        table.resizeColumnsToContents()
            
        image_label = QLabel("Placeholder")
        horizontal_layout.addWidget(table, 0, 0, 1, 2)
        horizontal_layout.addWidget(image_label, 0, 1, 1, 1)
        
        tab_layout.addLayout(horizontal_layout, 1, 0, 1, 3)
        self.tabs.addTab(table, info["name"])

I have made some research and tried asking for some help to ChatGPT I have not been able to find any reason for why it is not displaying the QLabel. Find an image below of how it is looking now.

If possible I would like the table to occupy 2/3 of the screen horizontally and the image the remaining 1/3

enter image description here


Solution

  • Try it:

    class MainWindow(QWidget):                             
        def __init__(self):
            super().__init__()
            
            self.tabs = QTabWidget()
           
            self.grid = QGridLayout(self)
            self.grid.addWidget(self.tabs)
            
            num_rows = 0
            self.set_tab_info(num_rows)
    
        def set_tab_info(self, num_rows):           # Sets the structure for each tab
            self.num_rows = num_rows
            tab_info = [
                {"name": "Junction", "columns": 11, "header_labels": ["Type", "X", "Shear Plane Location", "Fastener Position", "Bolt/Screw", "Under head", "Thread",
                                                                      "Minimum friction coefficient under bolt head", "Maximum friction coefficient under bolt head",
                                                                      "Minimum friction coefficient on thread", "Maximum friction coefficient on thread"],
                "editor_types": ["combo_box", "combo_box", "combo_box", "combo_box", "combo_box", "combo_box", "combo_box", "line_edit", "line_edit", "lined_edit", "line_edit"]},
                {"name": "Screw", "columns": 7, "header_labels": ["Type of Screw", "Nominal Diameter", "Material of Screw", "g",
                                                                   "Is there a change in diameter (shank)?", "Shank Length", "Shank Diameter"],
                "editor_types": ["combo_box", "line_edit", "combo_box", "line_edit", "combo_box", "line_edit", "line_edit"]},
                {"name": "Plate", "columns": 9, "header_labels": ["Material Plate 1 (Fastener Head)", "Material Plate 2", "muc", "Type of Hole", "Diameter of Hole",
                                                                  "Plate 1 Thickness", "Plate 2 Thickness", "Plate 1 Minimum Shear-out Length", "Plate 2 Minimum Shear-out Length"],
                "editor_types": ["combo_box", "combo_box", "line_edit", "combo_box", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]},
                {"name": "Nut/Insert", "columns": 8, "header_labels": ["Nut/Insert", "Type of Nut", "Type of Insert", "Diameter", "Height",
                                                                        "Material of Nut/Insert", "Maximum Prevailing Torque", "Minimum Prevailing Torque"],
                "editor_types": ["combo_box", "combo_box", "combo_box", "line_edit", "line_edit", "combo_box", "line_edit", "line_edit"]},
                {"name": "Washer", "columns": 11, "header_labels": ["Type of Washer", "Washer present under bolt head?", "Washer present under nut?", "External Diameter (under head)",
                                                                    "internal diameter (under head)", "External diameter (under nut)", "internal diameter (under nut)", "Height (under head)",
                                                                    "Height (under nut)", "Maximum Prevailing Torque", "Minimum Prevailing Torque"],
                "editor_types": ["combo_box", "combo_box", "combo_box", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]},
                {"name": "Loads", "columns": 9, "header_labels": ["Fkreq", "Kkreq", "DT+", "DT-", "CTEc", "CTEb", "Mnom", "External Shear Load", "External Tension Load"],
                "editor_types": ["line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]},
                {"name": "Safety Factors", "columns": 12, "header_labels": ["Bearing Factor", "Kq", "Km", "Kp", "KLD", "Yield", "Ultimate", "Gapping", "Slippage", "Embedding", "omega", "epsilon"],
                "editor_types": ["line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit", "line_edit"]}
            ]
            self.create_tabs(tab_info)
            
        def create_tabs(self, tab_info): # Creates each tab by receiving the structure from the set_tab_info method
            self.column_inputs = {}
            
            for info in tab_info:
                tab_widget = QWidget()
                tab_layout = QGridLayout(tab_widget)
                
    #-            horizontal_layout = QGridLayout()
    # !!! +++                       vvvvvvvvvvvvv
                horizontal_layout = QHBoxLayout()                         # !!! +++
                
                table = QTableWidget(self.num_rows, info["columns"])
                table.setHorizontalHeaderLabels(info["header_labels"])
                
                for row in range(self.num_rows):
                    for col in range(info["columns"]):
                        if info["editor_types"][col] == "line_edit":
                            item = QLineEdit()
                            table.setCellWidget(row, col, item)
                            self.column_inputs[(info["name"], info["header_labels"][col])] = item
                        elif info["editor_types"][col] == "combo_box":
                            item = QComboBox()
                            item.addItems(self.get_combo_box_items(info["header_labels"][col]))
                            table.setCellWidget(row, col, item)
                            self.column_inputs[(info["name"], info["header_labels"][col])] = item
                        else:
                            item = QTableWidgetItem()
                            
                        table.setItem(row, col, QTableWidgetItem())
                        
                table.resizeColumnsToContents()
                    
                image_label = QLabel(info["name"], alignment=Qt.AlignCenter) # "Placeholder"
    # +++
                image_label.setStyleSheet("""
                    color: rgb(253, 53, 53); 
                    background-color: #105652;
                    font-size: 24px;
                """)
    #-            
                '''
                horizontal_layout.addWidget(table, 0, 0, 1, 2)
                horizontal_layout.addWidget(image_label, 0, 1, 1, 1)
                '''
    # !!! +++                                      vvvvvvvvv            
                horizontal_layout.addWidget(table, stretch=2)                  # !!! +++ 
    # !!! +++                                            vvvvvvvvv 
                horizontal_layout.addWidget(image_label, stretch=1)            # !!! +++        
                
                tab_layout.addLayout(horizontal_layout, 1, 0, 1, 3)
                
                
    #-            self.tabs.addTab(table, info["name"])
    # !!! +++                    vvvvvvvvvv 
                self.tabs.addTab(tab_widget, info["name"])                     # !!! +++ 
    
    
    if __name__ == '__main__':
        import sys
        app = QApplication(sys.argv)
        w = MainWindow()
        w.resize(640, 480)
        w.show()
        sys.exit(app.exec_())
    

    enter image description here