pyqt - 调整自定义 QTableWidget 的大小(宽/高)

标签 pyqt resize qt5 qtablewidget

我需要一个 QTableWidget基于 QTabelModelQTableView在表格上方添加了一些按钮。见下图:

enter image description here
QTableWidget的宽度应进行调整,使其不小于合理的最小值,并且不会超出其上方的按钮;特别是第1、2、4栏的大小要根据其内容进行调整,第3栏Aberrations应该扩大以填补右侧的空白。我想知道如何在代码中做到这一点。

以下是我用于自定义 QTableWidget 的代码的最小示例(PyQt5,Python3):

from PyQt5 import QtGui, QtCore, QtWidgets
import numpy as np

#-- Table Model
class MyTableModel(QtCore.QAbstractTableModel):

    def __init__(self, data, parent=None, *args):
        super(MyTableModel, self).__init__(parent)

        # table data
        self.table_data = data
        self.rows_nr, self.columns_nr = data.shape

        # vertical & horizontal header labels
        self.hheaders = ["Head-{}".format(i) for i in range(self.columns_nr)]
        self.vheaders = ["Row-{}".format(i) for i in range(self.rows_nr)]

    # nr of rows
    def rowCount(self, parent):
        return self.rows_nr

    # nr of columns
    def columnCount(self, parent):
        return self.columns_nr

    # row and column headers
    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self.hheaders[section]
            #END if

        #ELSE:
        return QtCore.QVariant()

    # display table contents
    def data(self, index, role=QtCore.Qt.DisplayRole):        
        r_ = index.row()
        c_ = index.column()

        if role == QtCore.Qt.DisplayRole:
            return "{}".format(data[r_, c_])
        #ELSE:
        return QtCore.QVariant()

    # set data
    def setData(self, index, value, role):

        r_ = index.row()
        c_ = index.column()

        # editable fields
        if role == QtCore.Qt.EditRole:
            # interprete values
            self.table_data[r_,c_] = str(value)

        return True

    # view/edit flags
    def flags(self, index):
        r_ = index.row()
        c_ = index.column()

        return QtCore.Qt.ItemIsEnabled


class MyTableWidget(QtWidgets.QWidget):
    def __init__(self, data, *args):
        super(MyTableWidget, self).__init__(*args)

        #-- table model
        tablemodel = MyTableModel(data=data, parent=self)

        #-- table view
        tableview = QtWidgets.QTableView()
        tableview.setModel(tablemodel)
        tableview.verticalHeader().hide() # hide vertical/row headers

        # size policy
        tableview.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        tableview.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)

        #-- layouts
        #--- buttons
        button_hlayout = QtWidgets.QHBoxLayout()
        button_hlayout.addWidget(QtWidgets.QPushButton("Button 1"))
        button_hlayout.addWidget(QtWidgets.QPushButton("Button 2"))
        button_hlayout.addWidget(QtWidgets.QPushButton("Button 3"))

        #--- table
        table_layout = QtWidgets.QVBoxLayout()
        table_layout.addLayout(button_hlayout)
        table_layout.addWidget(tableview)
        self.setLayout(table_layout)
#----------------------------------------

#-- produce sample data
data = np.empty(shape=(3,4), dtype=np.object)
for r in range(3):
    for c in range(4):
        data[r,c] = str(list(range((r+1) * (c+1))))

app = QtWidgets.QApplication([""])
w = MyTableWidget(data=data)
w.show()
app.exec_()

最佳答案

void QHeaderView::setSectionResizeMode(int logicalIndex, QHeaderView::ResizeMode mode)

Sets the constraints on how the section specified by logicalIndex in the header can be resized to those described by the given mode. The logical index should exist at the time this function is called.

from PyQt5 import QtGui, QtCore, QtWidgets
import numpy as np

#-- Table Model
class MyTableModel(QtCore.QAbstractTableModel):

    def __init__(self, data, parent=None, *args):
        super(MyTableModel, self).__init__(parent)

        # table data
        self.table_data = data
        self.rows_nr, self.columns_nr = data.shape

        # vertical & horizontal header labels
        self.hheaders = ["Head-{}".format(i) for i in range(self.columns_nr)]
        self.vheaders = ["Row-{}".format(i) for i in range(self.rows_nr)]

    # nr of rows
    def rowCount(self, parent):
        return self.rows_nr

    # nr of columns
    def columnCount(self, parent):
        return self.columns_nr

    # row and column headers
    def headerData(self, section, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self.hheaders[section]
            #END if

        #ELSE:
        return QtCore.QVariant()

    # display table contents
    def data(self, index, role=QtCore.Qt.DisplayRole):        
        r_ = index.row()
        c_ = index.column()

        if role == QtCore.Qt.DisplayRole:
            return "{}".format(data[r_, c_])
        #ELSE:
        return QtCore.QVariant()

    # set data
    def setData(self, index, value, role):

        r_ = index.row()
        c_ = index.column()

        # editable fields
        if role == QtCore.Qt.EditRole:
            # interprete values
            self.table_data[r_,c_] = str(value)

        return True

    # view/edit flags
    def flags(self, index):
        r_ = index.row()
        c_ = index.column()

        return QtCore.Qt.ItemIsEnabled


class MyTableWidget(QtWidgets.QWidget):
    def __init__(self, data, *args):
        super(MyTableWidget, self).__init__(*args)

        #-- table model
        tablemodel = MyTableModel(data=data, parent=self)

        #-- table view
        tableview = QtWidgets.QTableView()
        tableview.setModel(tablemodel)
        tableview.verticalHeader().hide() # hide vertical/row headers
        
        #-- +++
        tableview.setAlternatingRowColors(True)
        tableview.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        tableview.horizontalHeader().setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
        tableview.horizontalHeader().setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
        tableview.horizontalHeader().setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents)

        # size policy
        tableview.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        #tableview.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) # ---
        tableview.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)# +++

        #-- layouts
        #--- buttons
        button_hlayout = QtWidgets.QHBoxLayout()
        button_hlayout.addWidget(QtWidgets.QPushButton("Button 1"))
        button_hlayout.addWidget(QtWidgets.QPushButton("Button 2"))
        button_hlayout.addWidget(QtWidgets.QPushButton("Button 3"))

        #--- table
        table_layout = QtWidgets.QVBoxLayout()
        table_layout.addLayout(button_hlayout)
        table_layout.addWidget(tableview)
        self.setLayout(table_layout)
#----------------------------------------

#-- produce sample data
data = np.empty(shape=(3,4), dtype=np.object)
for r in range(3):
    for c in range(4):
        data[r,c] = str(list(range((r+1) * (c+1))))

app = QtWidgets.QApplication([""])
w = MyTableWidget(data=data)
w.show()
app.exec_()
enter image description here
在上面的代码中,tableview.horizontalHeader().SetSectionResizeMode(QtWidgets.QHeaderView.Stretch)将 Stretch 模式应用于所有列,其余 3 个运算符将相应的列设置为 ResizeToContents模式。
小部件窗口的大小调整行为由 setSizePolicy 决定方法。在这种情况下,策略也可以是 tableview.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) ,它允许用户放大或缩小小部件窗口。

关于pyqt - 调整自定义 QTableWidget 的大小(宽/高),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51893313/

相关文章:

python - 从其他类发出的 PyQt5 信号的问题

python - PyQt4 Python2 Unicode

qt - PyQt4:为 QLineEdit 结合 textChanged 和 editFinished

python - 使用pyqt webview渲染pdf

c# - 如何按比例调整WPF Listview的大小?

java - 当容器大小更改时,JTable 仅调整选定列的大小

html - 调整浏览器窗口大小时如何防止表格和图像元素移动[REPOST]

linux - PyQt5 找不到已安装的 Qt5 库

c++ - 无法访问Qt5中对话框的成员

c++ - 从代码内部编译 QT 源代码