ymmx
ymmx

Reputation: 4967

How do I make QtableWidget cell squared the size I want?

I'm trying to have a zoom in/zoom out effet on a QtableWidget. to do so I have to variables self.myfont which is a Qfont objet and self.table_size which is an int.

When I want zoom in/out I call those two functions :

   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()

which change my two variables.

Then I redraw the QtableWidget with

    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)

When I'm zooming in it works fine

enter image description here

but when I'm zooming out, the horizontal header width does not match the vertical height anymore.

enter image description here

How can I force them to have the cells squared even for small width and height?

Here is a 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_() )

Upvotes: 0

Views: 417

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

You have to set the setMinimumSectionSize to 0. On the other hand instead of deleting and creating the elements it is better to reuse:

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)

Upvotes: 1

Related Questions