QTextEdit в QScrollArea изменение размера виджета в соответствии с контентом
Ситуация следующая. Помещаю QTextEdit с текстом в виде обычной строки (из форматирования строки - только шрифт и его размер. никаких переносов на новую строку и табуляций) в QScrollArea динамически, по нажатию кнопки.
QTextEdit прекрасно помещается в скролл-пространство, но размеры QTextEdit становятся непотребно большими, даже при наличии Spacer, принимая какие-то константные/коэффициентные значения, заложенные в QTextEdit разрабами.
Для простоты понимания иерархии окна - иллюстрация:
Вопрос, как настроить QTextEdit таким образом, чтобы при наличии строки в одно слово QTextEdit уменьшался бы до размеров этого самого слова (рамки виджета не в счет). А при наличии строки в несколько предложений, QTextEdit бы растягивался до такой степени, чтобы вместить все предложение, не активируя тем самым свои внутренние скролл-бары.
Расширение QTextEdit в ширину должно быть ограничено неким константным значением, чтобы при расширении QTextEdit не активировал бы горизонтальные скролл-бары у QScrollArea = при наличии большой строки, QTextEdit должен расширяться в высоту (активировать функцию переноса слов)
В результате ожидается примерно такая работа виджета
Ответы (2 шт):
Как реализовать автоподгон размера QTextEdit под текст, я отвечал в свое время в ответе на этот вопрос
Вам остается только переписать с c++ на python и реализовать необходимый доп. функционал - разбиение на предложения и ограничение макс. размера
Как вариант:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.Qt import *
TEXT = """Вопрос, как настроить QTextEdit таким образом, \
чтобы при наличии строки в одно слово QTextEdit уменьшался \
бы до размеров этого самого слова (рамки виджета не в счет). \
А при наличии строки в несколько предложений, QTextEdit бы \
растягивался до такой степени, чтобы вместить все предложение, \
не активируя тем самым свои внутренние скролл-бары. Расширение \
QTextEdit в ширину должно быть ограничено неким константным значением, \
чтобы при расширении QTextEdit не активировал бы горизонтальные \
скролл-бары у QScrollArea = при наличии большой строки, \
QTextEdit должен расширяться в высоту (активировать функцию переноса слов)"""
TEXT2 = "Hello World"
class TextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.textChanged.connect(self.updateGeometry)
self._height = 0
palette = QPalette()
palette.setColor(QPalette.Base, QColor('#FAFDD6'))
self.setPalette(palette)
def sizeHint(self):
hint = super().sizeHint()
if self.toPlainText():
doc = self.document().clone()
width = self.width() - self.frameWidth() * 2
if self.verticalScrollBar().isVisible():
width -= self.verticalScrollBar().width()
doc.setTextWidth(width)
height = round(doc.size().height())
else:
height = self.fontMetrics().height()
height += self.document().documentMargin() * 2
height += self.frameWidth() * 2
hint.setHeight(height)
self._height = height
return hint
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.tableWidget = QTableWidget(0, 1, self)
self.tableWidget.verticalHeader().setVisible(False)
self.tableWidget.horizontalHeader().setVisible(False)
self.tableWidget.horizontalHeader().setSectionResizeMode(
0, QtWidgets.QHeaderView.Stretch)
rowCount = self.tableWidget.rowCount()
self.tableWidget.insertRow(rowCount)
self.textEdit = TextEdit(self)
self.tableWidget.setCellWidget(0, 0, self.textEdit)
self.textEdit.setText(f'{TEXT}')
self.textEdit.textChanged.connect(self.text_changed)
self.tableWidget.installEventFilter(self)
self.pushButton = QPushButton('Короткий текст')
self.pushButton.setCheckable(True)
self.pushButton.clicked.connect(self.button_clicked)
layout = QVBoxLayout(self)
layout.addWidget(self.tableWidget)
layout.addWidget(self.pushButton, alignment=Qt.AlignBottom)
def eventFilter(self, source, event):
if event.type() == event.Resize:
QTimer.singleShot(0, self.tableWidget.resizeRowsToContents)
self.tableWidget.setMaximumHeight(self.textEdit._height)
QTimer.singleShot(
1,
lambda: self.tableWidget.setMaximumHeight(self.textEdit._height))
return super().eventFilter(source, event)
def text_changed(self):
self.tableWidget.resizeRowToContents(0)
self.tableWidget.setMaximumHeight(self.textEdit._height)
def button_clicked(self, status):
if status:
self.textEdit.setText(f'{TEXT2}')
self.pushButton.setText('Длинный текст')
else:
self.textEdit.setText(f'{TEXT}')
self.pushButton.setText('Короткий текст')
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle(QStyleFactory.create('Fusion'))
ex = MyApp()
ex.resize(500, 400)
ex.show()
sys.exit(app.exec_())



