使用 PyQt6 将 QTableWidget 和 QLabel 与 Pixmap 并排添加

Adding QTableWidget and QLabel with Pixmap side by side using PyQt6

提问人:Gerardo Lopez 提问时间:9/21/2023 更新时间:9/21/2023 访问量:37

问:

我正在尝试在 python 中使用 PyQt6 构建一个 GUI,我在选项卡内的右侧创建一个表格和一个图像。

出于某种原因,它创建了占据整个屏幕的表格,并且不显示 QLabel(现在我使用文本作为占位符)。

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"])

我做了一些研究并尝试向 ChatGPT 寻求帮助,但无法找到它不显示 QLabel 的任何原因。在下面找到它现在的样子的图片。

如果可能的话,我希望桌子水平占据屏幕的 2/3,图像占据剩余的 1/3

enter image description here

python qtablewidget pyqt6 qgridlayout

评论

0赞 musicamante 9/22/2023
您对网格布局的使用是错误的。例如,当你这样做时,你在第一列中添加表,但分配的列跨度为 2,而标签被添加到第二列,所以它与表重叠(它应该看起来“悬停”在表上,但如果没有更完整的代码,就不可能理解为什么它不可见); 也是错误的,因为您将其添加到第二行(而第一行中不存在任何内容),并且您无缘无故地将列跨度设置为 3。如果需要更具体的解释,请提供有效的最小可重现示例horizontal_layout.addWidget()tab_layout.addLayout()

答:

1赞 S. Nick 9/21/2023 #1

尝试一下:

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

评论

0赞 Gerardo Lopez 9/22/2023
它奏效了,谢谢你的帮助