it-swarm.com.de

PySide - PyQt: Wie kann man die Breite der QTableWidget-Spalte im Verhältnis zum verfügbaren Platz festlegen?

Ich entwickle eine Computeranwendung mit PySide und verwende das QTableWidget. Angenommen, meine Tabelle hat 3 Spalten, aber die darin enthaltenen Daten sind sehr unterschiedlich, wie (für jede Zeile) ein langer Satz in der ersten Spalte und dann dreistellige Zahlen in den beiden letzten Spalten. Ich möchte, dass meine Tabelle skaliert, um ihre Größe an die Daten anzupassen, oder zumindest die Spaltengröße auf 70/15/15% des verfügbaren Speicherplatzes einstellen kann.

Was ist der beste Weg, dies zu tun?

Ich habe table.horizontalHeader().setResizeMode(QHeaderView.Stretch) probiert, nachdem ich diese Frage gelesen habe, aber es macht 3 Spalten der gleichen Größe.

Ich habe auch table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) dank Fabio s Kommentar ausprobiert, aber es füllt nicht den gesamten verfügbaren Platz aus.

Weder Interactive, Fixed, Stretch, ResizeToContents aus der QHeaderView-Dokumentation scheinen mir das zu geben, was ich brauche (siehe zweite Bearbeitung).

Jede Hilfe wäre dankbar, auch wenn es sich um Qt/C++ handelt! Vielen Dank.


EDIT: Ich habe eine Art Workaround gefunden, aber es ist nicht das, wonach ich suche:

header = table.horizontalHeader()
header.setResizeMode(QHeaderView.ResizeToContents)
header.setStretchLastSection(True)

Es wäre besser, wenn es eine setStretchFirstSection-Methode gäbe, aber leider scheint es keine zu geben.


EDIT 2:

Das einzige, was in der Tabelle geändert werden kann, ist die letzte Spalte, in die der Benutzer eine Zahl eingeben kann. Rote Pfeile zeigen an, was ich gerne hätte.

Folgendes passiert mit StretchStretch

Folgendes passiert mit ResizeToContentsResizeToContents

7
AdrienW

Dies kann durch Einstellen des Größenänderungsmodus für jede Spalte gelöst werden. Der erste Abschnitt muss sich ausdehnen, um den verfügbaren Platz zu beanspruchen, während die letzten beiden Abschnitte die Größe des Inhalts ändern:

PyQt4:

header = self.table.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.Stretch)
header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)

PyQt5:

header = self.table.horizontalHeader()       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
19
ekhumoro

PyQt4

header = self.table.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.Stretch)
header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(2, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(3, QtGui.QHeaderView.Stretch)

PyQt5

header = self.table.horizontalHeader()       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents)
header.setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
5
Xavi Martínez

Sie können dies mit QItemDelegates oder QStyledItemDelegates tun. Wenn Sie die Größe der Inhalte und automatisch strecken möchten, müssen Sie auswählen, welche Spalte die Streckenspalte ist.

class ResizeDelegate(QStyledItemDelegate):

    def __init__(self, table, stretch_column, *args, **kwargs):
        super(ResizeDelegate, self).__init__(*args, **kwargs)        
        self.table = table
        self.stretch_column = stretch_column

    def sizeHint(self, option, index):
        size = super(ResizeDelegate, self).sizeHint(option, index)
        if index.column() == self.stretch_column:
            total_width = self.table.viewport().size().width()
            calc_width = size.width()
            for i in range(self.table.columnCount()):
                if i != index.column():
                    option_ = QtGui.QStyleOptionViewItem()
                    index_ = self.table.model().index(index.row(), i)
                    self.initStyleOption(option_, index_)
                    size_ = self.sizeHint(option_, index_)
                    calc_width += size_.width()
            if calc_width < total_width:
                size.setWidth(size.width() + total_width - calc_width)
        return size

...

table = QTableWidget()
delegate = ResizeDelegate(table, 0)
table.setItemDelegate(delegate)
... # Add items to table
table.resizeColumnsToContents()

Sie können den Größenänderungsmodus auf ResizeToContents setzen. Wenn Sie möchten, dass der Benutzer die Spaltenbreite nach Bedarf anpassen kann, rufen Sie resizeColumnsToContents einfach manuell auf, nachdem Sie Änderungen an den Tabellenelementen vorgenommen haben.

Möglicherweise müssen Sie auch ein wenig mit den Breitenberechnungen herumspielen, da zwischen den Spalten Ränder und Füllzeichen vorhanden sind (z. B. fügen Sie dem calculated_width ein oder zwei Pixel für jede Spalte hinzu, um den Zellenrand zu berücksichtigen).

2
Brendan Abel

Wie bereits erwähnt, können Sie dies tun, indem Sie den Größenänderungsmodus für jede Spalte festlegen. Wenn Sie jedoch viele Spalten haben, kann dies viel Code sein. So wie ich das mache, setze ich den "allgemeinen" Größenänderungsmodus auf "ResizeToContent" und dann für eine (oder mehrere) Spalten auf "Dehnen"!

Hier ist der Code:

PyQt4:

header = self.table.horizontalHeader()
header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(0, QtGui.QHeaderView.Stretch)

PyQt5:

header = self.table.horizontalHeader()
header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)       
header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch)
2
koxx