2011-08-25 12 views

Odpowiedz

4

O ile mi wiadomo, nie ma prostego sposobu na zrobienie tego. Musisz zsumować szerokość kolumn tabeli, a następnie dodać miejsce na nagłówki. Musisz również dodać miejsce na pionowy pasek przewijania i ramkę widżetu. Oto jeden ze sposobów, aby to zrobić,

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

Można użyć coś takiego (skomentował tyle mam nadzieję):

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) 

Kiedy zmiany wierszu nagłówka, szerokość całych pionowych zmian nagłówka, ale nie od razu po wyemitowaniu sygnału headerDataChanged.
Dlatego użyłem QTimer, aby zadzwonić pod numer updateGeometry (który musi zostać wywołany po zmianie sizeHint) po tym, jak QTableWidget rzeczywiście zaktualizował szerokość nagłówka w pionie.

+0

To zadziałało dla mnie, podczas gdy "zaakceptowana" odpowiedź nie. Jednym z powodów może być to, że używam QTableView, który nie ma metody columnCount używanej w rozwiązaniu pana Terry'ego. Zauważ, że przy QTableView musisz ustawić model na wczesnym etapie konstruktora, aby to rozwiązanie działało, ponieważ używa modelu do sprawdzenia, czy zmieniają się nagłówki. –

+0

Słowo ostrzeżenia: Używałem tej implementacji 'MyTableWidget' w niezapisanym oknie dialogowym (np. Okno dialogowe zostało utworzone i wykracza poza zakres w tej samej metodzie), a to dało mi obiekt' RuntimeError: zawinięty obiekt C/C++ typu MyTableWidget został usunięty błąd. Myślę, że 'QTimer' próbował wywołać' self.updateGeometry' po tym, jak widget został już zebrany (czy to możliwe?). W każdym razie właśnie zamieniłem wywołania na 'self.updateGeometryAsync' z wywołaniami do' self.updateGeometry' i nadal działało dobrze dla mnie. – jeremiahbuddha

Powiązane problemy