Napisałem małe okno dialogowe, które zawiera tylko TableWigdet. Jak mogę określić poziomy rozmiar stołu? Chcę zmienić rozmiar okna dialogowego, aby tabela była wyświetlana bez poziomego paska przewijania.Ustaw optymalny rozmiar okna dialogowego zawierającego TableWidget
5
A
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.
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. –
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