python-3.x 如何在QGroupBox中添加表,PyQt5

ssm49v7z  于 2023-08-08  发布在  Python
关注(0)|答案(2)|浏览(144)

我对PyQt 5很陌生,仍然在挣扎。我试了一整天在QGroupBox中添加行和列。我找到的唯一解决方案是添加一个QTableWidget,问题是Widget的大小。
现在我只想有这个表的头,用户可以在这个表中添加行。[ID,姓名]
我想要细胞,但不是随之而来的“窗口”。如果我试图将它对齐在QGroupBox的中心,它会将整个东西对齐在中心,而不是列。(列在小部件的左上角,见图)
x1c 0d1x的数据
这是创建表的代码片段:

创建盒子

self.groupbox1 = QGroupBox('Data')
    self.groupbox1.setMaximumWidth(350)
    self.groupbox1.setMaximumHeight(400)
    self.layout = QVBoxLayout()
    self.groupbox1.setLayout(self.layout)
    self.layout.addWidget(self.groupbox1)

字符串

创建QTableWidget

self.table_widget = QTableWidget()
    self.table_widget.setColumnCount(2)
    self.table_widget.setHorizontalHeaderLabels(['ID', 'Data'])
    self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
    self.table_widget.resizeColumnsToContents()
    self.table_widget.setMaximumSize(200, 200)
    self.upper_layout.setAlignment(Qt.AlignCenter)

    self.upper_layout.addWidget(self.table_widget)


我唯一找到的是.resizeColumnsToContents和.setSectionResizeMode,这只是根据其中的内容调整列。
通过设置表格小部件的最大大小,我使它变小了,但这不是我想要的。如果有更多的数据添加到表中,用户必须滚动,因为小部件不够大。难道没有什么东西可以自动调整吗?
还是有其他解决问题的方法?用户可以选择要显示的数据(将添加哪一行)的按钮应位于中间行的正下方,如果行被删除/添加,则自动向上/向下移动。如果我必须有一个固定大小的QTableWidget,这也是不可能的。
希望我解释得够好。我感谢每一个能让我更接近答案的答案。:)(是的,我已经看了Stack Overflow上所有相关的帖子,可能每隔一页都看了,可惜没有解决我的问题)

vxbzzdmp

vxbzzdmp1#

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QTableWidget, QPushButton, QTableWidgetItem, QHeaderView, QMessageBox

class TestApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Test Application')
        self.setGeometry(200, 200, 400, 400)

        # Create a QVBoxLayout for the main window
        self.layout = QVBoxLayout(self)  # 'self' refers to the main window
        self.groupbox1 = QGroupBox('Data')
        self.groupbox_layout = QVBoxLayout()
        self.groupbox1.setLayout(self.groupbox_layout)

        # Create a QTableWidget
        self.table_widget = QTableWidget()
        self.table_widget.setColumnCount(2)
        self.table_widget.setHorizontalHeaderLabels(['ID', 'Name'])
        self.table_widget.verticalHeader().setVisible(False)
        self.table_widget.setShowGrid(False)
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # Create a QPushButton to add rows to the QTableWidget
        self.add_row_button = QPushButton('Add Row')
        self.add_row_button.clicked.connect(self.add_row)

        # Add the QTableWidget and QPushButton to the QGroupBox layout
        self.groupbox_layout.addWidget(self.table_widget)
        self.groupbox_layout.addWidget(self.add_row_button)

        # Add the QGroupBox to the main QVBoxLayout of the main window
        self.layout.addWidget(self.groupbox1)

    def add_row(self):
        # Add a new row to the QTableWidget when the button is clicked
        row_position = self.table_widget.rowCount()
        self.table_widget.insertRow(row_position)
        self.table_widget.setItem(
            row_position, 0, QTableWidgetItem(str(row_position + 1)))
        self.table_widget.setItem(row_position, 1, QTableWidgetItem(''))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = TestApp()
    window.show()
    sys.exit(app.exec_())

字符串
尝试一下,并将其调整到您的项目中。
这是输出:
x1c 0d1x的数据

版本2023-07-26首码:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QTableWidget, QPushButton, QTableWidgetItem, QHeaderView, QMessageBox

class TestApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Test Application')
        self.setGeometry(200, 200, 400, 400)

        # Create a QVBoxLayout for the main window
        self.layout = QVBoxLayout(self)  # 'self' refers to the main window
        self.groupbox1 = QGroupBox('Data')
        self.groupbox_layout = QVBoxLayout()
        self.groupbox1.setLayout(self.groupbox_layout)

        # Create a QTableWidget
        self.table_widget = QTableWidget()
        self.table_widget.setColumnCount(2)
        self.table_widget.setHorizontalHeaderLabels(['ID', 'Name'])
        self.table_widget.verticalHeader().setVisible(False)
        self.table_widget.setShowGrid(False)

        # Set a fixed width for the 'ID' column
        self.table_widget.setColumnWidth(0, 50)
        #Set a fixed width for the 'NAME' column
        self.table_widget.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
        #Block widht fro the 'ID' column
        self.table_widget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Fixed)

        # Create a QPushButton to add rows to the QTableWidget
        self.add_row_button = QPushButton('Add Row')
        self.add_row_button.clicked.connect(self.add_row)

        # Add the QTableWidget and QPushButton to the QGroupBox layout
        self.groupbox_layout.addWidget(self.table_widget)
        self.groupbox_layout.addWidget(self.add_row_button)

        # Add the QGroupBox to the main QVBoxLayout of the main window
        self.layout.addWidget(self.groupbox1)

    def add_row(self):
        # Add a new row to the QTableWidget when the button is clicked
        row_position = self.table_widget.rowCount()
        self.table_widget.insertRow(row_position)
        self.table_widget.setItem(
            row_position, 0, QTableWidgetItem(str(row_position + 1)))
        self.table_widget.setItem(row_position, 1, QTableWidgetItem(''))

        # Resize the 'Name' column to fit the contents
        self.table_widget.resizeColumnToContents(1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = TestApp()
    window.show()
    sys.exit(app.exec_())


试试这个,我已经调整了大小,并阻止了ID项链和名称列自动调整大小
这是输出:


版本2023-07-26秒码:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QTableWidget, QPushButton, QTableWidgetItem, QHeaderView, QScrollArea, QSizePolicy
from PyQt5.QtCore import Qt

class TestApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Test Application')
        self.setGeometry(200, 200, 400, 400)

        # Create a QVBoxLayout for the main window
        self.layout = QVBoxLayout(self)  # 'self' refers to the main window

        # Create a QScrollArea and set it as the main widget
        self.scroll_area = QScrollArea(self)
        self.layout.addWidget(self.scroll_area)

        # Create a QWidget to hold the content
        self.main_widget = QWidget()
        self.main_layout = QVBoxLayout(self.main_widget)

        # Create a QGroupBox to display the table
        self.groupbox1 = QGroupBox('Data')
        self.groupbox_layout = QVBoxLayout()
        self.groupbox1.setLayout(self.groupbox_layout)
        self.groupbox1.setWindowFlag(Qt.WindowContextHelpButtonHint, False)
        self.groupbox1.hide()  # Hide the group box initially

        # Create a QTableWidget
        self.table_widget = QTableWidget()
        self.table_widget.setColumnCount(2)
        self.table_widget.setHorizontalHeaderLabels(['ID', 'Name'])
        self.table_widget.verticalHeader().setVisible(False)
        self.table_widget.setShowGrid(False)
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # Add the QTableWidget to the QGroupBox layout
        self.groupbox_layout.addWidget(self.table_widget)

        # Add the QGroupBox to the main_layout of the main_widget
        self.main_layout.addWidget(self.groupbox1)

        # Create a QPushButton to add rows to the QTableWidget
        self.add_row_button = QPushButton('Add Row')
        self.add_row_button.clicked.connect(self.add_row)

        # Add the QPushButton to the main_layout of the main_widget
        self.main_layout.addWidget(self.add_row_button)

        # Set the main_widget as the widget for the QScrollArea
        self.scroll_area.setWidget(self.main_widget)

        # Set the QScrollArea to expand the widget vertically
        self.scroll_area.setWidgetResizable(True)
        self.main_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)

        # Set the number of rows to display (2 rows in this case)
        self.displayed_rows = 1

        # Calculate and set the initial height of the QScrollArea based on the QTableWidget height
        table_height = self.table_widget.rowHeight(0) * self.displayed_rows + self.groupbox_layout.spacing()
        self.scroll_area.setMinimumHeight(table_height)

        # Set the maximum height for the QGroupBox
        self.groupbox1.setMaximumHeight(table_height)

    def add_row(self):
        if not self.groupbox1.isVisible():  # Show the group box when the first row is added
            self.groupbox1.show()

        # Add a new row to the QTableWidget when the button is clicked
        row_position = self.table_widget.rowCount()
        self.table_widget.insertRow(row_position)
        self.table_widget.setItem(row_position, 0, QTableWidgetItem(str(row_position + 1)))
        self.table_widget.setItem(row_position, 1, QTableWidgetItem(''))
 
        # Recalculate the new height of the QGroupBox based on the updated QTableWidget height
        table_height = self.table_widget.rowHeight(
            0) * (self.displayed_rows + 1.5) + self.groupbox_layout.spacing()
        self.groupbox1.setFixedHeight(table_height)
        self.table_widget.setMinimumHeight(table_height)

        if (self.displayed_rows < 5):
            self.displayed_rows += 1
        else:
            # Enable scrolling when the displayed rows reach 5
            self.update_scroll_area_height()

    def update_scroll_area_height(self):
        table_height = self.table_widget.rowHeight(
            0) * (self.displayed_rows + 2) + self.groupbox_layout.spacing()
        self.groupbox1.setFixedHeight(table_height)
        self.scroll_area.setMinimumHeight(table_height)

        # Enable vertical scrolling
        self.scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = TestApp()
    window.show()
    sys.exit(app.exec_())


尝试一下,并将其调整到您的项目中。
这是输出:

nsc4cvqm

nsc4cvqm2#

这是Francesca Mazzeo回答的修改版本。它使用一个子类QTableWidget和一个重新实现的resizeEvent()方法来获得“随添加的行而增长”的行为。
有件奇怪的事我不明白添加第一行不会触发resizeEvent()。后面的行可以。
我以任何方式发布这个,希望有人知道如何解决这个问题。

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QTableWidget, QPushButton, QTableWidgetItem, QHeaderView, QMessageBox

# class ExpandingTableWidget(QTableWidget):
#    def resizeEvent(self, event):
#        super().resizeEvent(event)
#        height = self.horizontalHeader().height()
#        row_count = self.verticalHeader().count()
#        for i in range(row_count):
#            height += self.verticalHeader().sectionSize(i)
#
#        self.setMaximumHeight(height + 2)

class TestApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Test Application')
        self.setGeometry(200, 200, 400, 400)

        # Create a QVBoxLayout for the main window
        self.layout = QVBoxLayout(self)  # 'self' refers to the main window
        self.groupbox1 = QGroupBox('Data')
        self.groupbox_layout = QVBoxLayout()
        self.groupbox1.setLayout(self.groupbox_layout)

        # Create a QTableWidget
        self.table_widget = ExpandingTableWidget()
        self.table_widget.setColumnCount(2)
        self.table_widget.setHorizontalHeaderLabels(['ID', 'Name'])
        self.table_widget.verticalHeader().setVisible(False)
        self.table_widget.setShowGrid(False)
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # Create a QPushButton to add rows to the QTableWidget
        self.add_row_button = QPushButton('Add Row')
        self.add_row_button.clicked.connect(self.add_row)

        # Add the QTableWidget and QPushButton to the QGroupBox layout
        self.groupbox_layout.addWidget(self.table_widget, stretch=1)
        self.groupbox_layout.addStretch(0)
        self.groupbox_layout.addWidget(self.add_row_button)

        # Add the QGroupBox to the main QVBoxLayout of the main window
        self.layout.addWidget(self.groupbox1)

    def add_row(self):
        # Add a new row to the QTableWidget when the button is clicked
        row_position = self.table_widget.rowCount()
        self.table_widget.insertRow(row_position)
        self.table_widget.setItem(
            row_position, 0, QTableWidgetItem(str(row_position + 1)))
        self.table_widget.setItem(row_position, 1, QTableWidgetItem(''))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = TestApp()
    window.show()
    sys.exit(app.exec())

字符串
编辑:
使用musicamente的注解创建了新的QTablewidget子类:

class ExpandingTableWidget(QTableWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.model().rowsInserted.connect(self.set_height)
        self.model().columnsInserted.connect(self.set_height)

    def set_height(self):
        height = self.horizontalHeader().height() + self.verticalHeader().length() + self.frameWidth() * 2
        self.setMaximumHeight(height)

相关问题