user13786679
user13786679

Reputation:

QTableWidget column span doesnt resize correctly

I filled a QTableWidget() the way it should be done :) Now I have problem with col span.

enter image description here

The left image shows the correct size for each column, the right one is what I get with the introduction of the first row "spanned" and this is not what I want.

import sys

from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QAction, QTableWidget, QTableWidgetItem, QVBoxLayout



class MakeStrip(QWidget):
    def __init__(self, anno , mese):
        super().__init__()
        self.initUI(anno, mese)

    def initUI(self, anno, mese):
        self.title = "MAMbo - Strips di '%s' '%s' "%(mese, anno)
        self.setWindowTitle(self.title)
        self.setGeometry(50, 100, 250, 800)
        MakeStrip.callTable(self, anno, mese)
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.tableWidget)
        self.setLayout(self.layout)
        # Show widget
        self.show()

    def callTable(self, anno, mese):
        anno = '2021'
        self.alphamese = 'January'
        # Create table
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(10)
        self.tableWidget.setColumnCount(3)
        self.tableWidget.horizontalHeader().setVisible(False)
        header = self.tableWidget.horizontalHeader()
        header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.verticalHeader().setDefaultSectionSize(13)
        self.vol_name = 'MAZZONI'
        zz=1
        self.tableWidget.setSpan(0, 0, 1, 3)
        newItem = QTableWidgetItem(self.vol_name)
        newItem.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
        self.tableWidget.setItem(0, 0, newItem)

        self.tableWidget.setSpan(1, 0, 1, 3)
        newItem = QTableWidgetItem(self.alphamese)
        newItem.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
        self.tableWidget.setItem(1, 0, newItem)

        while zz <= 10:
            self.dow = 'do'+str(zz)
            self.value = 'AAAAAAAA' +str(zz)
            self.tableWidget.setItem(zz+1, 0, QtWidgets.QTableWidgetItem(str(zz)))
            self.tableWidget.setItem(zz+1, 1, QtWidgets.QTableWidgetItem(self.dow))
            item = QtWidgets.QTableWidgetItem(self.value)
            item.setTextAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
            self.tableWidget.setItem(zz+1, 2, item)
            zz += 1

        pippo = 0
        #return

if __name__ == '__main__':
    app = QApplication(sys.argv)
    anno = '2021'
    mese = 'January'
    ex = MakeStrip(anno, mese)
    sys.exit(app.exec_())

How can I get the first column of the second image with the size of the one in the left image?

P.S. The second row will contain another spanned info

Upvotes: 0

Views: 1182

Answers (1)

eyllanesc
eyllanesc

Reputation: 243907

The problem is not the span but the calculation of the minimum width all the information of all the items in the column even if the span was applied or not, for example it is seen that the width is the same with or without span:

without span:

enter image description here

with span:

enter image description here

So a trick to work around this behavior is to pass the text through a delegate without using the model:

import sys

from PyQt5 import QtCore, QtWidgets


class SpecialStyledItemDelegate(QtWidgets.QStyledItemDelegate):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._values = dict()

    def add_text(self, text, row):
        self._values[row] = text

    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)
        row = index.row()
        if row in self._values:
            option.text = self._values[row]
            option.displayAlignment = QtCore.Qt.AlignCenter


class MakeStrip(QtWidgets.QWidget):
    def __init__(self, anno, mese):
        super().__init__()
        self.initUI(anno, mese)

    def initUI(self, anno, mese):
        self.title = "MAMbo - Strips di '%s' '%s' " % (mese, anno)
        self.setWindowTitle(self.title)
        self.setGeometry(50, 100, 250, 800)
        self.callTable(anno, mese)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.tableWidget)

    def callTable(self, anno, mese):
        anno = "2021"
        self.alphamese = "January"
        # Create table
        self.tableWidget = QtWidgets.QTableWidget()
        self.tableWidget.setRowCount(10)
        self.tableWidget.setColumnCount(3)

        self.special_delegate = SpecialStyledItemDelegate()
        self.tableWidget.setItemDelegate(self.special_delegate)

        self.special_delegate.add_text("MAZZONI", 0)
        self.special_delegate.add_text("January", 1)

        h_header = self.tableWidget.horizontalHeader()
        h_header.hide()
        for i in range(h_header.count()):
            h_header.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents)

        v_header = self.tableWidget.verticalHeader()
        v_header.hide()
        v_header.setDefaultSectionSize(13)

        self.tableWidget.setSpan(1, 0, 1, 3)
        self.tableWidget.setSpan(0, 0, 1, 3)

        for zz in range(1, 10):
            dow = "do{}".format(zz)
            value = "AAAAAAAA{}".format(zz)
            self.tableWidget.setItem(zz + 1, 0, QtWidgets.QTableWidgetItem(str(zz)))
            self.tableWidget.setItem(zz + 1, 1, QtWidgets.QTableWidgetItem(dow))
            item = QtWidgets.QTableWidgetItem(value)
            item.setTextAlignment(QtCore.Qt.AlignCenter)
            self.tableWidget.setItem(zz + 1, 2, item)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    anno = "2021"
    mese = "January"
    ex = MakeStrip(anno, mese)
    ex.show()
    sys.exit(app.exec_())

enter image description here

Upvotes: 1

Related Questions