QTextDocument QTextEdit не удалось изменить размер страницы после SetText - PullRequest
1 голос
/ 09 мая 2019

Отказ от ответственности: я использую PySide2; однако, любой ответ в Qt (pyqt5, Qt c ++) подойдет.

У меня проблема с установкой размера моего документа в текстовом сообщении.

Когда я инициализирую QTextEdit с setText(text:QString), изменяется размер QTextEdit QTextDocument. Последовательное применение setPageSize игнорируется, если только текст не попадает в область просмотра виджета.

Если изначально я не setText, то размер документа будет правильно учтен, независимо от того, изменю я размер окна или нет.

Ниже приведен минимальный пример странного поведения, которое я испытываю. Если вы запустите код, попробуйте изменить размер окна, и вы увидите, что pageSize учитывается, когда текст превышает виджет; однако, если нет, то размер страницы QTextEdit будет соответствовать его ширине, а его высота будет -1.

Если вы выключите SET_TEXT_TEST, то проблем с самого начала не будет. Если есть какие-либо объяснения или обходные пути, я хотел бы услышать.

import PySide2
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtPrintSupport import *

SET_TEXT_TEST = True


class IPageEdit(QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        # these lines don't seem to do anything
        doc = self.document()
        pageSize = QPageSize(QPageSize.A6).size(QPageSize.Point)
        doc.setPageSize(QPageSize(QPageSize.A6).size(QPageSize.Point))

    def paintEvent(self, event):
        doc = self.document()
        pageSize = QPageSize(QPageSize.A6).size(QPageSize.Point)
        doc.setPageSize(QPageSize(QPageSize.A6).size(QPageSize.Point))

        print('({},{})  ({},{})'.format(
            pageSize.width(),
            pageSize.height(),
            doc.pageSize().width(),
            doc.pageSize().height()))

        painter = QPainter(self.viewport())
        doc.drawContents(painter)


class IMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(1000, 500)
        self.setContentsMargins(20, 20, 20, 20)

        pageEdit = IPageEdit(self)
        if SET_TEXT_TEST:
            pageEdit.setText('''\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Velit aliquet sagittis id consectetur purus ut faucibus pulvinar elementum. Metus vulputate eu scelerisque felis imperdiet proin fermentum leo vel. Massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin. Enim neque volutpat ac tincidunt vitae semper. Leo duis ut diam quam nulla porttitor massa id neque. Cras pulvinar mattis nunc sed blandit libero volutpat. Eleifend quam adipiscing vitae proin sagittis. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Tellus molestie nunc non blandit massa enim nec dui nunc. Eget nullam non nisi est sit amet. Sed odio morbi quis commodo odio aenean sed. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Adipiscing diam donec adipiscing tristique risus nec. Sit amet consectetur adipiscing elit ut aliquam purus sit. Sed sed risus pretium quam. Elit pellentesque habitant morbi tristique senectus. Turpis egestas sed tempus urna.

Nunc aliquet bibendum enim facilisis gravida neque. Condimentum id venenatis a condimentum vitae sapien pellentesque habitant. Purus sit amet volutpat consequat mauris. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Ultrices mi tempus imperdiet nulla malesuada pellentesque elit. Dolor purus non enim praesent elementum facilisis leo vel. Donec adipiscing tristique risus nec. Non consectetur a erat nam. Fusce id velit ut tortor pretium. Sit amet nulla facilisi morbi tempus iaculis urna. Vel facilisis volutpat est velit egestas. Ac orci phasellus egestas tellus rutrum tellus pellentesque.

Turpis tincidunt id aliquet risus feugiat in ante metus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Amet luctus venenatis lectus magna fringilla urna. Morbi blandit cursus risus at ultrices mi tempus imperdiet. Sit amet porttitor eget dolor. Nec ultrices dui sapien eget mi. Turpis massa tincidunt dui ut ornare lectus sit. Ac odio tempor orci dapibus. Et netus et malesuada fames ac turpis egestas integer. Morbi quis commodo odio aenean. Vulputate sapien nec sagittis aliquam malesuada. Lobortis mattis aliquam faucibus purus in. Sem fringilla ut morbi tincidunt. Volutpat commodo sed egestas egestas fringilla phasellus faucibus.

Tempor orci dapibus ultrices in iaculis nunc sed augue. Etiam sit amet nisl purus in mollis nunc sed. Nulla porttitor massa id neque aliquam vestibulum morbi. Nibh tortor id aliquet lectus proin. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Volutpat odio facilisis mauris sit. Magna eget est lorem ipsum dolor sit amet consectetur. Lacinia quis vel eros donec ac odio tempor. Justo donec enim diam vulputate. Fringilla urna porttitor rhoncus dolor purus. In dictum non consectetur a erat nam at. Egestas erat imperdiet sed euismod nisi porta lorem. Scelerisque fermentum dui faucibus in ornare quam viverra orci. Lectus proin nibh nisl condimentum id venenatis a. Faucibus pulvinar elementum integer enim neque volutpat ac tincidunt. Habitasse platea dictumst quisque sagittis purus sit amet volutpat consequat. Enim sed faucibus turpis in.

Eu lobortis elementum nibh tellus molestie nunc non blandit. Dui id ornare arcu odio. Sit amet nisl purus in mollis nunc sed id semper. Senectus et netus et malesuada fames. Porttitor rhoncus dolor purus non enim praesent elementum. Amet est placerat in egestas erat imperdiet sed euismod. Mi tempus imperdiet nulla malesuada pellentesque elit eget. Tellus molestie nunc non blandit massa enim nec. Pellentesque eu tincidunt tortor aliquam nulla. Ut consequat semper viverra nam libero.
''')
        self.setCentralWidget(pageEdit)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    wnd = IMainWindow()
    wnd.show()
    sys.exit(app.exec_())

Для демонстрации приведем несколько изображений:

Ширина страницы размером ~ 1000 Wide Window

Ширина страницы размером 623,0 Window A No Wrap

Ширина страницы размером 622,0 Window A Wrapped

Ответы [ 2 ]

1 голос
/ 09 мая 2019

Ваш setPageSize определенно принят на QTextDocument().

Для доказательства этого я отверг resizeEvent(). вернуть Пусто, скажем, None.

Вы можете видеть, что размер документа соответствует размеру вашей страницы.

Вы убедились, что изменили размер документа один раз, но измененный размер очень скоро изменится на оригинальный.

Так что вам нужно позаботиться об изменении.

почему происходит это изменение?

Я думаю, это потому, что исполнение QTextEdit resizeEvent. Если QTextEdit выполняет его, излучается сигнал documentSizeChanged в QAbstractTextDocumentLayout.

Если вы заблокируете сигнал, когда размер QTextEdit изменится, вы сможете получить желаемый результат. Для меня с этим кодом остаются некоторые проблемы, но я думаю, что смогу ответить на ваш вопрос. Да, документ длиннее QMainWindow. И Вы изменили только размер документа, поэтому QTextEdit не может показать все тексты. Возможно, это может быть следующий квест.

import PySide2
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtPrintSupport import *

SET_TEXT_TEST = True

#In my environment PySide2 fails. So I searched the solution, I found out the codes.This codes are for my verification.
#import sys,os

# in my Environment this code is necessary
#dirname = os.path.dirname(PySide2.__file__)
#plugin_path = os.path.join(dirname, 'plugins', 'platforms')
#os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path



class IPageEdit(QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        # these lines don't seem to do anything
        doc = self.document()
        pageSize = QPageSize(QPageSize.A6).size(QPageSize.Point)
        doc.setPageSize(QPageSize(QPageSize.A6).size(QPageSize.Point))

    def paintEvent(self, event):
        doc = self.document()
        pageSize = QPageSize(QPageSize.A6).size(QPageSize.Point)
        doc.setPageSize(QPageSize(QPageSize.A6).size(QPageSize.Point))

        print('({},{})  ({},{})'.format(
            pageSize.width(),
            pageSize.height(),
            doc.pageSize().width(),
            doc.pageSize().height()))

        painter = QPainter(self.viewport())
        doc.drawContents(painter)
    def resizeEvent(self, event):
        self.document().documentLayout().blockSignals(True)
        return QTextEdit.resizeEvent(self, event)

class IMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(1000, 500)
        self.setContentsMargins(20, 20, 20, 20)

        pageEdit = IPageEdit(self)
        if SET_TEXT_TEST:
            pageEdit.setText('''\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Velit aliquet sagittis id consectetur purus ut faucibus pulvinar elementum. Metus vulputate eu scelerisque felis imperdiet proin fermentum leo vel. Massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin. Enim neque volutpat ac tincidunt vitae semper. Leo duis ut diam quam nulla porttitor massa id neque. Cras pulvinar mattis nunc sed blandit libero volutpat. Eleifend quam adipiscing vitae proin sagittis. Nulla facilisi cras fermentum odio eu feugiat pretium nibh. Tellus molestie nunc non blandit massa enim nec dui nunc. Eget nullam non nisi est sit amet. Sed odio morbi quis commodo odio aenean sed. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Adipiscing diam donec adipiscing tristique risus nec. Sit amet consectetur adipiscing elit ut aliquam purus sit. Sed sed risus pretium quam. Elit pellentesque habitant morbi tristique senectus. Turpis egestas sed tempus urna.

Nunc aliquet bibendum enim facilisis gravida neque. Condimentum id venenatis a condimentum vitae sapien pellentesque habitant. Purus sit amet volutpat consequat mauris. Mauris in aliquam sem fringilla ut morbi tincidunt augue interdum. Ultrices mi tempus imperdiet nulla malesuada pellentesque elit. Dolor purus non enim praesent elementum facilisis leo vel. Donec adipiscing tristique risus nec. Non consectetur a erat nam. Fusce id velit ut tortor pretium. Sit amet nulla facilisi morbi tempus iaculis urna. Vel facilisis volutpat est velit egestas. Ac orci phasellus egestas tellus rutrum tellus pellentesque.

Turpis tincidunt id aliquet risus feugiat in ante metus. Nibh ipsum consequat nisl vel pretium lectus quam id leo. Amet luctus venenatis lectus magna fringilla urna. Morbi blandit cursus risus at ultrices mi tempus imperdiet. Sit amet porttitor eget dolor. Nec ultrices dui sapien eget mi. Turpis massa tincidunt dui ut ornare lectus sit. Ac odio tempor orci dapibus. Et netus et malesuada fames ac turpis egestas integer. Morbi quis commodo odio aenean. Vulputate sapien nec sagittis aliquam malesuada. Lobortis mattis aliquam faucibus purus in. Sem fringilla ut morbi tincidunt. Volutpat commodo sed egestas egestas fringilla phasellus faucibus.

Tempor orci dapibus ultrices in iaculis nunc sed augue. Etiam sit amet nisl purus in mollis nunc sed. Nulla porttitor massa id neque aliquam vestibulum morbi. Nibh tortor id aliquet lectus proin. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Volutpat odio facilisis mauris sit. Magna eget est lorem ipsum dolor sit amet consectetur. Lacinia quis vel eros donec ac odio tempor. Justo donec enim diam vulputate. Fringilla urna porttitor rhoncus dolor purus. In dictum non consectetur a erat nam at. Egestas erat imperdiet sed euismod nisi porta lorem. Scelerisque fermentum dui faucibus in ornare quam viverra orci. Lectus proin nibh nisl condimentum id venenatis a. Faucibus pulvinar elementum integer enim neque volutpat ac tincidunt. Habitasse platea dictumst quisque sagittis purus sit amet volutpat consequat. Enim sed faucibus turpis in.

Eu lobortis elementum nibh tellus molestie nunc non blandit. Dui id ornare arcu odio. Sit amet nisl purus in mollis nunc sed id semper. Senectus et netus et malesuada fames. Porttitor rhoncus dolor purus non enim praesent elementum. Amet est placerat in egestas erat imperdiet sed euismod. Mi tempus imperdiet nulla malesuada pellentesque elit eget. Tellus molestie nunc non blandit massa enim nec. Pellentesque eu tincidunt tortor aliquam nulla. Ut consequat semper viverra nam libero.
''')
        self.setCentralWidget(pageEdit)




if __name__ == '__main__':
    import sys
    #In my environment, error happends from the second execution unless this code.
    try:
        QApplication(sys.argv)
    except Exception as e:
        print("QApplication is already exists")
    wnd = IMainWindow()
    wnd.show()
    sys.exit(QApplication.exec_())
0 голосов
/ 09 мая 2019

Исходя из ответа @Heike, решение было таким же простым, как добавление этой строки кода:

class IPageEdit(QTextEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setLineWrapMode(QTextEdit.FixedPixelWidth)
        ...

Это дает правильное поведение при изменении размера, а pageSize сохраняет свое значение после изменения размера.

...