我在 QScrollArea 的 QVBoxLayout 中有一堆 QTextEdits。
文本通常会变得很长,并且水平空间受设计限制,而 QTextEdit 会自动将文本换成多行,这很好。
我想自动调整 QTextEdit 的大小以适合换行的文本,文本本身将始终在一行中,并且换行的文本可以有多行,我希望 QTextEdits 适合换行的高度。
经过数小时的谷歌搜索,我找到了一个解决方案,但它没有按预期工作,有时底部可能会多出一行,我将在下面发布示例代码:
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
font = QFont('Noto Serif', 9)
class Editor(QTextEdit):
doubleClicked = pyqtSignal(QTextEdit)
def __init__(self):
super().__init__()
self.setReadOnly(True)
self.setFont(font)
self.textChanged.connect(self.autoResize)
self.margins = self.contentsMargins()
self.setAttribute(Qt.WidgetAttribute.WA_DontShowOnScreen)
@pyqtSlot(QMouseEvent)
def mouseDoubleClickEvent(self, e: QMouseEvent) -> None:
self.doubleClicked.emit(self)
def autoResize(self):
self.show()
height = int(self.document().size().height() + self.margins.top() + self.margins.bottom())
self.setFixedHeight(height)
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.resize(405, 720)
frame = self.frameGeometry()
center = self.screen().availableGeometry().center()
frame.moveCenter(center)
self.move(frame.topLeft())
self.centralwidget = QWidget(self)
self.vbox = QVBoxLayout(self.centralwidget)
self.scrollArea = QScrollArea(self.centralwidget)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.scrollArea.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop)
self.vbox.addWidget(self.scrollArea)
self.setCentralWidget(self.centralwidget)
def addItems():
items = [
"L'Estro Armonico No. 9 in D Major\u2014III. Allegro",
"L'Estro Armonico No. 6 in A Minor\u2014III. Presto",
"L'Estro Armonico No. 6 in A Minor\u2014I. Allegro",
"L'Estro Armonico No. 1 in D major\u2014I. Allegro",
"12 Concertos Op.3 \u2014 L'estro Armonico \u2014 Concerto No. 6 In A Minor For Solo Violin RV 356\u2014Presto",
"Ultimate Mozart\u2014 The Essential Masterpieces",
"Serenade in G K.525 Eine kleine Nachtmusik\u20141. Allegro",
"Vivaldi\u2014 L'estro Armonico",
"Academy of St. Martin in the Fields",
"Are You With Me \u2014 Reality"
]
for i in items:
textbox = Editor()
textbox.setText(i)
window.verticalLayout.addWidget(textbox)
app = QApplication([])
window = Window()
window.show()
addItems()
app.exec()
请注意,您需要 Noto Serif 才能正确运行(当然您可以替换它),当然您还需要 PyQt6。
在示例中,前七个文本框的底部都有一个额外的空行,而后三个则没有。
是什么导致了多余的线以及如何删除它?
更新:
我必须设置 Qt.WidgetAttribute.WA_DontShowOnScreen 因为如果我不设置它,调用 QTextEdit 的 .show() 会导致 QTextEdit 出现在屏幕中间并迅速消失,这很烦人。
我必须调用 .show() 因为在没有 show() 的情况下调用 document().size(),值将全部为 0,我不知道为什么会这样。