首页 > 解决方案 > 如何使 QtableWidget 单元格按我想要的大小平方?

问题描述

我正在尝试对 QtableWidget 进行放大/缩小效果。为此,我必须变量 self.myfont 是一个 Qfont 对象和 self.table_size 这是一个 int。

当我想放大/缩小时,我调用这两个函数:

   def zoomin(self):
        fontsize = self.myfont.pointSize() + 1
        if fontsize < 1:
            fontsize = 1
        self.myfont.setPointSize(fontsize)
        self.table_size += 5
        if self.table_size < 1:
            self.table_size = 1
        print(self.table_size,fontsize)
        self.redrawCMLayout()

    def zoomout(self):
        fontsize = self.myfont.pointSize() - 1
        if fontsize < 1:
            fontsize = 1
        self.myfont.setPointSize(fontsize)
        self.table_size -= 5
        if self.table_size < 1:
            self.table_size = 1
        print(self.table_size,fontsize)
        self.redrawCMLayout()

这改变了我的两个变量。

然后我用重绘 QtableWidget

    self.tableWidget = QTableWidget()

    self.tableWidget.verticalHeader().setDefaultSectionSize(self.table_size)
    self.tableWidget.horizontalHeader().setDefaultSectionSize(self.table_size)

    self.tableWidget.horizontalHeader().setFixedHeight(self.table_size)
    self.tableWidget.verticalHeader().setFixedWidth(self.table_size)

    self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)
    self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)

    self.tableWidget.horizontalHeader().setFont(self.myfont)
    self.tableWidget.verticalHeader().setFont(self.myfont)

当我放大它工作正常

在此处输入图像描述

但是当我缩小时,水平标题宽度不再与垂直高度匹配。

在此处输入图像描述

即使宽度和高度很小,我如何才能强制它们使单元格平方?

这是一个 MRE

import sys
import os
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class ExampleWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.setMinimumSize(QSize(440, 240))
        self.setWindowTitle("PyQt5 Textarea example")

        self.myarray =  [[4, 0, 2, 1],
                         [6, 0, 3, 7],
                         [4, 2, 2, 8],
                         [3, 2, 1, 0]]
        self.myfont = QFont()
        self.myfont.setPointSize(10)
        self.table_size = 35

        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)

        self.gridCM = QHBoxLayout()
        self.update_CMLayout()

        zoomin = QAction('zoomin', self)
        zoomin.setShortcut('Ctrl+shift+Z')
        zoomin.setToolTip('Redo')
        zoomin.triggered.connect(self.zoomin)

        zoomout = QAction( 'zoomout',self)
        zoomout.setShortcut('Ctrl+shift+Z')
        zoomout.setToolTip('Redo')
        zoomout.triggered.connect(self.zoomout)
        # toolbar
        toolbar = self.addToolBar('')
        toolbar.addAction(zoomin)
        toolbar.addAction(zoomout)


        self.centralWidget.setLayout(self.gridCM)


    def update_CMLayout(self):
        print('update_CMLayout')
        #self.gridCM = QHBoxLayout()
        self.grid3_layout = QGroupBox('Connectivity Matrix')
        grid3 = QGridLayout()
        self.grid3_layout.setLayout(grid3)

        self.tableWidget = QTableWidget()

        self.tableWidget.horizontalHeader().setFont(self.myfont)
        self.tableWidget.verticalHeader().setFont(self.myfont)

        self.tableWidget.verticalHeader().setDefaultSectionSize(self.table_size)
        self.tableWidget.horizontalHeader().setDefaultSectionSize(self.table_size)

        self.tableWidget.horizontalHeader().setFixedHeight(self.table_size)
        self.tableWidget.verticalHeader().setFixedWidth(self.table_size)

        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.tableWidget.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)

        line = len(self.myarray)
        column = len(self.myarray[0])
        self.tableWidget.setRowCount(line)
        self.tableWidget.setColumnCount(column)

        for c in range(column):
            for l in range(line):
                item = QTableWidgetItem(str(self.myarray[c][l]))
                item.setFont(self.myfont)
                item.setSizeHint(QSize(self.table_size, self.table_size))
                self.tableWidget.setItem(c, l, item) 

        grid3.addWidget(self.tableWidget, 1, 1, 1, 1)

        self.gridCM.insertWidget(0, self.grid3_layout)


    def zoomin(self):
        fontsize = self.myfont.pointSize() + 1
        if fontsize < 1:
            fontsize = 1
        self.myfont.setPointSize(fontsize)
        self.table_size += 5
        if self.table_size < 1:
            self.table_size = 1
        print(self.table_size,fontsize)
        self.redrawCMLayout()

    def zoomout(self):
        fontsize = self.myfont.pointSize() - 1
        if fontsize < 1:
            fontsize = 1
        self.myfont.setPointSize(fontsize)
        self.table_size -= 5
        if self.table_size < 1:
            self.table_size = 1
        print(self.table_size,fontsize)
        self.redrawCMLayout()

    def redrawCMLayout(self):
        self.gridCM.removeWidget(self.grid3_layout)
        self.grid3_layout.deleteLater()
        self.grid3_layout = None
        self.tableWidget.deleteLater()
        self.tableWidget = None
        self.update_CMLayout()
        # self.layout_Main.insertItem(2,self.gridCM)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Windows")
    mainWin = ExampleWindow()
    mainWin.show()
    sys.exit( app.exec_() )

标签: pythonpyqt5qtablewidget

解决方案


您必须将 setMinimumSectionSize 设置为 0。另一方面,与其删除和创建元素,不如重用:

class Delegate(QStyledItemDelegate):
    def sizeHint(self, option, index):
        s = QStyledItemDelegate.sizeHint(self, option, index)
        return max(s.width(), s.height()) * QSize(1, 1)


class ExampleWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        self.myfont = QFont()
        self.myfont.setPointSize(10)

        self.setMinimumSize(QSize(440, 240))
        self.setWindowTitle("PyQt5 Textarea example")

        self.myarray = [[4, 0, 2, 1], [6, 0, 3, 7], [4, 2, 2, 8], [3, 2, 1, 0]]

        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)

        self.gridCM = QHBoxLayout(self.centralWidget)

        zoomin = QAction("zoomin", self)
        zoomin.setShortcut("Ctrl+shift+Z")
        zoomin.setToolTip("Redo")
        zoomin.triggered.connect(self.zoomin)

        zoomout = QAction("zoomout", self)
        zoomout.setShortcut("Ctrl+shift+Z")
        zoomout.setToolTip("Redo")
        zoomout.triggered.connect(self.zoomout)
        # toolbar
        toolbar = self.addToolBar("")
        toolbar.addAction(zoomin)
        toolbar.addAction(zoomout)

        self.grid3_layout = QGroupBox("Connectivity Matrix")
        grid3 = QGridLayout()
        self.grid3_layout.setLayout(grid3)
        self.gridCM.insertWidget(0, self.grid3_layout)
        self.tableWidget = QTableWidget()
        grid3.addWidget(self.tableWidget, 1, 1, 1, 1)

        line = len(self.myarray)
        column = len(self.myarray[0])
        self.tableWidget.setRowCount(line)
        self.tableWidget.setColumnCount(column)

        self.delegate = Delegate()
        self.tableWidget.setItemDelegate(self.delegate)

        for c, row in enumerate(self.myarray):
            for r, e in enumerate(row):
                item = QTableWidgetItem(str(e))
                self.tableWidget.setItem(r, c, item)

        for header in (
            self.tableWidget.horizontalHeader(),
            self.tableWidget.verticalHeader(),
        ):
            header.setSectionResizeMode(QHeaderView.ResizeToContents)
            header.setMinimumSectionSize(0)

        self.update_font()

    def zoomin(self):
        self.myfont.setPointSize(self.myfont.pointSize() + 1)
        self.update_font()

    def zoomout(self):
        if self.myfont.pointSize() > 1:
            self.myfont.setPointSize(self.myfont.pointSize() - 1)
            self.update_font()

    def update_font(self):
        self.tableWidget.setFont(self.myfont)

推荐阅读