2011-08-25 40 views

Trả lời

4

Theo như tôi biết, không có cách nào dễ dàng để làm điều đó. Bạn phải tính tổng chiều rộng của các cột của bảng và sau đó thêm dấu cách cho các tiêu đề. Bạn cũng phải thêm khoảng trống cho thanh cuộn dọc và khung tiện ích. Dưới đây là một cách để làm điều đó,

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

Bạn có thể sử dụng một cái gì đó như thế (nhận xét đủ Tôi hy vọng):

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) 

Khi một sự thay đổi tiêu đề hàng, chiều rộng của toàn bộ những thay đổi tiêu đề theo chiều dọc, nhưng không phải ngay sau khi tín hiệu headerDataChanged được phát ra.
Đó là lý do tại sao tôi đã sử dụng số QTimer để gọi số updateGeometry (phải được gọi khi sizeHint thay đổi) sau khi QTableWidget thực sự đã cập nhật chiều rộng tiêu đề dọc.

+0

Điều này làm việc tốt cho tôi, trong khi câu trả lời 'chấp nhận' thì không. Một lý do có thể là tôi đang sử dụng QTableView mà không có phương pháp columnCount được sử dụng trong giải pháp của Terry. Lưu ý rằng với QTableView, bạn cần thiết lập mô hình sớm trong hàm tạo để giải pháp này hoạt động vì nó sử dụng mô hình để cho biết các tiêu đề có thay đổi không. –

+0

Lời cảnh báo: Tôi đã sử dụng triển khai này 'MyTableWidget' trong một hộp thoại không được lưu (ví dụ: hộp thoại đã được tạo và thoát khỏi phạm vi trong cùng phương thức), và nó cho tôi một đối tượng C Runtime C++ loại MyTableWidget đã bị xóa' lỗi. Tôi nghĩ rằng 'QTimer' đang cố gắng gọi' self.updateGeometry' sau khi widget đã được thu gom rác (có thể không?). Trong mọi trường hợp, tôi chỉ thay thế các cuộc gọi thành 'self.updateGeometryAsync' bằng các lệnh gọi đến' self.updateGeometry' và nó vẫn hoạt động tốt cho tôi. – jeremiahbuddha

Các vấn đề liên quan