Изменить горизонтальный размер виджетов QTableView на основе данных - PullRequest
1 голос
/ 23 февраля 2020

Я пытался заставить 2 виджета QTableView изменить размер друг с другом в PyQt5. Виджеты находятся в QComboBox, а макет настроен на сетку. Я попробовал метод resizeColumnToContents, но он просто уменьшает ширину столбцов QTableView.

Как это в настоящее время:

how it is

Как это должно быть:

how it should be

QTableView 1 может иметь несколько столбцов или только один. Я хочу, чтобы QTableView 2 расширялся в макете так, чтобы он покрывал все пространство, а QTableView 1 - только один отображаемый столбец. Есть ли способ сделать это? Я пытался использовать сплиттер и динамически изменять множитель setstretch, но не смог его реализовать. Некоторые подсказки или подсказки?

Ответы [ 2 ]

2 голосов
/ 23 февраля 2020

Существует два возможных решения.

Если вы хотите использовать QSplitter, позволяющий пользователю изменять размер столбцов, вы можете изменить размер содержимого после изменения размера окна. Поскольку таблицам и разделителям может потребоваться некоторое время, чтобы отрегулировать их размеры, это должно произойти после небольшой задержки (цикл «событие l oop»).

class Test(QtWidgets.QMainWindow):
    # ...
    def delaySplitterResize(self):
        if not self.model1.columnCount():
            return
        total = self.table1.width() + self.table2.width()
        leftWidth = self.table1.frameWidth() * 2 + self.table1.contentsMargins().left() * 2
        for s in range(self.model1.columnCount()):
            leftWidth += self.table1.horizontalHeader().sectionSize(s)
        self.splitter.setSizes([leftWidth, total - leftWidth])

    def resizeEvent(self, event):
        super().resizeEvent(event)
        QtCore.QTimer.singleShot(0, self.delaySplitterResize)

Другая возможность состоит в создании подкласса таблицы и обновлять sizeHint каждый раз, когда изменяется содержимое модели. Это работает путем вызова updateGeometry() (который делает недействительным sizeHint и говорит родителям [s] снова вычислять размеры) каждый раз, когда изменяется размер модели и изменяется размер раздела.

class MinimumSizeTable(QtWidgets.QTableView):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # an explicit minimum size is recommended
        self.setMinimumWidth(self.horizontalHeader().defaultSectionSize())
        # ensure that the widget tries to occupy only the width provided
        # by the sizeHint
        self.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
        # section resizing requires some time to "update" the section hints,
        # so we need to delay the call to updateGeometry
        self.horizontalHeader().sectionResized.connect(lambda: QtCore.QTimer.singleShot(0, self.updateGeometry))
        self.verticalHeader().sectionResized.connect(lambda: QtCore.QTimer.singleShot(0, self.updateGeometry))

    def setModel(self, model):
        if self.model():
            self.model().columnsInserted.disconnect(self.updateGeometry)
            self.model().columnsRemoved.disconnect(self.updateGeometry)
        super().setModel(model)
        if self.model():
            self.model().columnsInserted.connect(self.updateGeometry)
            self.model().columnsRemoved.connect(self.updateGeometry)
        self.updateGeometry()

    def sizeHint(self):
        hint = super().sizeHint()
        if not self.model() or not self.model().columnCount():
            hint.setWidth(self.horizontalHeader().defaultSectionSize())
        else:
            width = self.frameWidth() * 2 + self.contentsMargins().left() * 2
            for s in range(self.model().columnCount()):
                width += self.horizontalHeader().sectionSize(s)
            hint.setWidth(width)
        return hint

Чтобы использовать этот класс в вашем пользовательском интерфейсе, вам нужно повысить таблицу в Designer:

  • Щелкните правой кнопкой мыши по таблице и выберите «Повышение до»
  • Введите имя подкласса в поле «Имя продвигаемого класса»
  • Введите файл python, содержащий подкласс, без расширения (например, «mytable») в поле «Файл заголовка»
  • Нажмите «Добавить», затем «Продвинуть» и сохраните.

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

0 голосов
/ 23 февраля 2020

Возможно, вы захотите использовать: heather = table.hor horizontalHeader для каждого столбца (столбца) в таблице: header.setSectionResizemode (ncol, QHeadedrView.resizeToContents) # Это ограничит ширину столбца. Если вы хотите, чтобы столбец занимал все доступное пространство, используйте «QHeaderView.Stretch». Кроме того, вы можете использовать QHBoxlayout и, возможно, связать ширину обеих таблиц.

...