I am trying to find solution by some time but nothing works so far..
I made a simple QTableWidget in PyQt5 and while casual QTableWidgetItems and QLabel resizes well using the option .resizeColumnsToContents(), the QPushButton somehow keeps its minimum width which makes the column too wide.
I tried using setMinimumWidth(1) on the button but it didn't work.
Here is the code I made:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTableWidget, QApplication, QTableWidgetItem, QPushButton, QLabel
class Table(QTableWidget):
def __init__(self, *args):
super().__init__(*args)
button = QPushButton("X")
button.setMinimumWidth(1)
self.setHorizontalHeaderLabels(["1", "2", "3", "4"])
self.setItem(0, 0, Cell("Val1"))
self.setCellWidget(0, 1, button)
self.setCellWidget(0, 2, QLabel("Y"))
self.setItem(0, 3, Cell("Val3"))
self.resizeColumnsToContents()
self.resizeRowsToContents()
class Cell(QTableWidgetItem):
def __init__(self, *args):
super().__init__(*args)
self.setTextAlignment(Qt.AlignCenter)
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = Table(1, 4)
widget.show()
sys.exit(app.exec_())
When using widgets in item views, the header auto resizing uses the widget's size hint, not the minimum size.
A QPushButton normally has a wider size hint (even if it doesn't have text), so you have two options:
sizeHint()
;In the second case, you could just return a minimum arbitrary size:
class PushButton(QPushButton):
def sizeHint(self):
return QSize(10, 10)
# ...
button = PushButton("X")
self.setCellWidget(0, 1, button)
But that wouldn't be appropriate, because you'd need to try to show the full text of the button.
A proper solution should use the style, which has a function that can compute the proper sizes of widgets and other elements: sizeFromContents()
.
Note that in this case you should use a QStyleOptionToolButton and the CT_ToolButton
type (instead of QStyleOptionButton and CT_PushButton
), otherwise you'll end up with a larger button anyway:
class PushButton(QPushButton):
def sizeHint(self):
self.ensurePolished()
opt = QStyleOptionToolButton()
opt.initFrom(self)
fm = self.fontMetrics()
textSize = fm.size(Qt.TextShowMnemonic, self.text())
textSize.setWidth(textSize.width() +
fm.horizontalAdvance(' ') * 2)
opt.rect.setSize(textSize)
return self.style().sizeFromContents(
QStyle.CT_ToolButton, opt, textSize)