2011-08-25 6 views

risposta

4

Per quanto ne so, non esiste un modo semplice per farlo. Devi sommare le larghezze delle colonne della tabella e quindi aggiungere spazio per le intestazioni. Devi anche aggiungere spazio per la barra di scorrimento verticale e il riquadro del widget. Ecco un modo per farlo,

class myTableWidget(QtGui.QTableWidget): 

    def sizeHint(self): 
     width = 0 
     for i in range(self.columnCount()): 
      width += self.columnWidth(i) 

     width += self.verticalHeader().sizeHint().width() 

     width += self.verticalScrollBar().sizeHint().width() 
     width += self.frameWidth()*2 

     return QtCore.QSize(width,self.height()) 
6

Si potrebbe usare qualcosa di simile (commentato abbastanza spero):

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

class MyTableWidget(QTableWidget): 
    def __init__(self, x, y, parent = None): 
     super(MyTableWidget, self).__init__(x, y, parent) 

     self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
     self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) 

     # To force the width to use sizeHint().width() 
     self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) 

     # To readjust the size automatically... 
     # ... when columns are added or resized 
     self.horizontalHeader().geometriesChanged \ 
      .connect(self.updateGeometryAsync) 
     self.horizontalHeader().sectionResized \ 
      .connect(self.updateGeometryAsync)   
     # ... when a row header label changes and makes the 
     # width of the vertical header change too 
     self.model().headerDataChanged.connect(self.updateGeometryAsync) 

    def updateGeometryAsync(self):  
     QTimer.singleShot(0, self.updateGeometry) 

    def sizeHint(self): 
     height = QTableWidget.sizeHint(self).height() 

     # length() includes the width of all its sections 
     width = self.horizontalHeader().length() 

     # you add the actual size of the vertical header and scrollbar 
     # (not the sizeHint which would only be the preferred size)     
     width += self.verticalHeader().width()   
     width += self.verticalScrollBar().width()  

     # and the margins which include the frameWidth and the extra 
     # margins that would be set via a stylesheet or something else 
     margins = self.contentsMargins() 
     width += margins.left() + margins.right() 

     return QSize(width, height) 

Quando un'intestazione di riga cambia, la larghezza di tutto il cambiamento di intestazione verticali, ma non subito dopo che il segnale headerDataChanged è stato emesso.
Ecco perché ho utilizzato uno QTimer per chiamare lo updateGeometry (che deve essere chiamato quando cambia sizeHint) dopo che QTableWidget ha effettivamente aggiornato la larghezza dell'intestazione verticale.

+0

Questo ha funzionato bene per me, mentre la risposta "accettata" no. Una ragione potrebbe essere che sto usando un QTableView che non ha il metodo columnCount utilizzato nella soluzione di Mr Terry. Si noti che con un QTableView è necessario impostare il modello all'inizio del costruttore affinché questa soluzione funzioni perché utilizza il modello per stabilire se le intestazioni cambiano. –

+0

Word of warning: stavo usando questa implementazione di 'MyTableWidget' in una finestra di dialogo non salvata (ad es. La finestra di dialogo è stata creata ed è uscita dall'ambito nello stesso metodo) e mi stava dando un oggetto' RuntimeError: wrapped C/C++ di tipo MyTableWidget è stato cancellato errore. Penso che il 'QTimer' stava cercando di chiamare' self.updateGeometry' dopo che il widget era già stato eliminato dalla spazzatura (è possibile?). In ogni caso, ho appena sostituito le chiamate a 'self.updateGeometryAsync' con chiamate allo stock' self.updateGeometry' e comunque ha funzionato bene per me. – jeremiahbuddha

Problemi correlati