2016-06-29 4 views
5

Я разрабатываю компьютерное приложение с PySide, и я использую QTableWidget. Скажем, моя таблица имеет 3 столбца, но содержащиеся в них данные очень разные, например (для каждой строки) длинное предложение в первом столбце, а затем 3-значные числа в двух последних столбцах. Я хотел бы, чтобы изменил размер моей таблицы, чтобы настроить его размер на данные или, по крайней мере, для того, чтобы иметь возможность установить размеры столбцов как (скажем) 70/15/15% от доступного пространства.PySide - PyQt: Как настроить ширину столбца QTableWidget как долю доступного пространства?

Каков наилучший способ для этого?

Я пробовал table.horizontalHeader().setResizeMode(QHeaderView.Stretch) после прочтения this question, но он делает 3 колонки одинакового размера.

Я также пробовал table.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) благодаря Fabiocomment, но он не заполняет все доступное пространство по мере необходимости.

Ни Interactive, Fixed, Stretch, ResizeToContents от QHeaderView documentation, кажется, чтобы дать мне то, что мне нужно (см второе изменение).

Любая помощь будет оценена, даже если она предназначена для Qt/C++! Большое спасибо.


EDIT: я нашел своего рода обходной путь, но это еще не то, что я ищу:

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

Было бы лучше, если бы существовал способ setStretchFirstSection, но, к сожалению, делает похоже, не один.


EDIT 2:

Единственное, что может быть изменен в таблице последний столбец, пользователь может ввести номер в нем. Красные стрелки указывают, что я хотел бы иметь.

Вот что происходит с StretchStretch

Вот что происходит с ResizeToContentsResizeToContents

+0

Попробуйте QHeaderView.ResizeToContents вместо QHeaderView.Stretch – Fabio

+0

Это работает, но это не совсем то, что я ищу, потому что с помощью 'ResizeToContents', поскольку мои столбцы недостаточно велики, они не заполняют свободное пространство. Я отредактирую, чтобы он стал более ясным. – BusyAnt

ответ

10

Это можно решить, установив режим изменения размера для каждого столбца. Первая секция должна растягиваться, чтобы занять свободное пространство, в то время как последние две секции просто изменить размер их содержание:

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) 
+0

Я не знал, что могу выбрать другой 'QHeaderView' для каждого столбца. Это отлично работает, хотя я изменил на «Fixed» для последних двух столбцов, а затем добавил минимальную ширину с помощью 'self.table.setColumnWidth (index, width)' (подходит для моего случая) – BusyAnt

+2

В qt5 эта функция изменена на setSectionResizeMode() –

2

Вы можете сделать это с QItemDelegates или QStyledItemDelegates. Если вы хотите изменить размер до содержания и, у вас есть автоматическое растяжение, вам нужно выбрать, в каком столбце находится столбец «растянуть».

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() 

Вы можете установить режим изменения в ResizeToContents, или если вы хотите, чтобы пользователь, чтобы иметь возможность регулировать ширину столбца по мере необходимости, просто позвоните resizeColumnsToContents вручную после внесения изменений в элементы таблицы.

Вам также может потребоваться немного рассчитать вычисления ширины из-за полей и заполнения между столбцами (например, добавьте пиксель или два в calculated_width для каждого столбца, чтобы учесть границу ячейки).

+0

Это хорошо, потому что теперь мои столбцы не изменяются в любое время, как раньше, но они все еще не занимают все свободное пространство, а изменение столбца «растяжка», похоже, не имеет никакого эффекта ... Я что-то не так? Я отредактирую свой вопрос с результатами, которые получаю – BusyAnt

2

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)