Как упаковать с PyQt - как заставить QFrame/Layout адаптироваться к контенту

Я строю сетку QTextEdit с HTML-подмножеством, чтобы показать некоторые данные в интерфейсе в PyQt.

В настоящий момент я получаю GridLayout и QFrame, который содержит его, который делает все, что они хотят, и я не могу заставить их соответствовать размеру QTextEdit. Я плед с SizePolicy, но не работает. Посмотрите на изображение, как дополнительное пространство появляется на стороне каждого QText и как GridLayout режет QTextEdit по высоте.

Единственный способ заставить его работать, если я установлю правильный размер QFrame, чтобы все подходило, но так как размер QTextEdit настраивается, я бы хотел, чтобы QFrame просто помещал все, что он должен содержать вместо получения свободной воли +_+

Обратите внимание, что GridLayout обычно больше, чем основное окно, поэтому ему не нужно помещаться в окно, поэтому нужно использовать scrollArea.

Что я не хочу Что я не хочу, чтобы случилось

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

Что я хочу, чтобы случилось обратите внимание, что изображение, которое я хочу, было получено добавлением этой строки (в MainFrame()):

container.resize(1100,1360)

Как я сказал, я хочу получить то же поведение, но без указания измерения для QFrame, это должно соответствовать содержимому (подмножеству таблиц HTML).

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from random import *

class Box(QTextBrowser):

    def __init__(self):
        super().__init__()

        self.setText('''
            <table border="0" cellspacing="0" cellpadding="5" style="background-color: rgba(119, 212, 212, 0.7);">
                <tr>
                    <td width="100">
                    bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
                    </td>
                <tr>
                <tr>
                    <td>
                    bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
                    </td>
                <tr>
            </table>

        ''')

        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.setContentsMargins(0,0,0,0)

        cstring ="""
        QTextBrowser {
            border: 0;
            background-color: #<---->;
            margin: 0px;
            padding-left:0;
            padding-top:0;
            padding-bottom:0;
            padding-right:0;
        }
        """

        ncol = randint(300000, 999999)

        cstring = cstring.replace('<---->', str(ncol))

        self.setStyleSheet(cstring)


class MainFrame(QScrollArea):
    def __init__(self):
        super().__init__()

        container = QFrame(self)


        layout = QGridLayout(container)

        for row in range(0, 5):
            for col in range(0, 10):
                QGridLayout.addWidget(layout, Box(), row, col)

        self.setWidget(container)

        container.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

        layout.setContentsMargins(0,0,0,0)
        layout.setSpacing(0)

        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = MainFrame()
    sys.exit(app.exec_())

1 ответ

Решение

Чтобы получить правильный размер, вы должны использовать idealWidth() метод document(), но это будет правильно только тогда, когда элемент виден, поэтому вы должны применять его, когда виджет виден, поэтому вы должны вызвать show() метод, к которому применяется это изменение, помимо вызова его каждый раз, когда изменяется текст.

Чтобы получить правильную высоту, используйте size() метод QTextDocument()

class Box(QTextBrowser):
    def __init__(self, parent=None):
        QTextBrowser.__init__(self, parent)
        self.setContentsMargins(0, 0, 0, 0)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        cstring = """
        QTextBrowser {
            border: 0;
            background-color: #<---->;
            margin: 0px;
            padding-left:0;
            padding-top:0;
            padding-bottom:0;
            padding-right:0;
        }
        """

        ncol = randint(300000, 999999)
        cstring = cstring.replace('<---->', str(ncol))
        self.setStyleSheet(cstring)

        self.document().contentsChange.connect(lambda: self.customGeometry())
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.setContentsMargins(0, 0, 0, 0)

    def customGeometry(self):
        if self.isVisible():
            self.setFixedWidth(self.document().idealWidth())
            self.setFixedHeight(self.document().size().height())

    def showEvent(self, event):
        self.customGeometry()
        QTextBrowser.showEvent(self, event)


class MainFrame(QScrollArea):
    def __init__(self, parent=None):
        QScrollArea.__init__(self, parent)
        container = QFrame(self)

        layout = QGridLayout(container)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.show()

        text = '''
                <table border="0" cellspacing="0" cellpadding="5" style="background-color: rgba(119, 212, 212, 0.7);">
                <tr>
                    <td width="100">
                        bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
                    </td>
                <tr>
                <tr>
                   <td>
                        bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
                    </td>
                <tr>
                </table>
                '''

        for row in range(5):
            for col in range(10):
                box = Box(container)
                box.setText(text)
                box.show()
                layout.addWidget(box, row, col)

        self.setWidget(container)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    ex = MainFrame()
    ex.show()
    sys.exit(app.exec_())

Выход:

Другие вопросы по тегам