I encountered a problem while using Pyton's QPlaintExt component: How do I set the line height of QPlainText? I've tried multiple approaches: Method 1: Using QTextDocument with HTML (Guaranteed to Work)
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt
class TextEditor(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Working Line Height - HTML Method')
self.setGeometry(100, 100, 600, 400)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# Use QTextEdit instead of QPlainTextEdit
self.text_edit = QTextEdit() self.text_edit.setAcceptRichText(True)
layout.addWidget(self.text_edit)
# Set line height using HTML/CSS
self.set_text_with_line_height()
def set_text_with_line_height(self):
"""Set text with line height using HTML/CSS"""
html_content = """
<style>
p {
line-height: 2.0; /* Double spacing */
margin: 0;
padding: 0;
}
</style>
<p>Line 1 with double spacing</p>
<p>Line 2 with double spacing</p>
<p>Line 3 with double spacing</p>
<p>Line 4 with double spacing</p>
"""
self.text_edit.setHtml(html_content)
if __name__ == '__main__':
app = QApplication(sys.argv)
editor= TextEditor()
editor.show()
sys.exit(app.exec_())
Method 2: Custom QPlainTextEdit with Painter (Advanced but Works)
importsys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPlainTextEdit, QVBoxLayout, QWidget
from PyQt5.QtGui import QTextFormat, QPainter, QFontMetrics
from PyQt5.QtCore import Qt, QRect
class CustomPlainTextEdit(QPlainTextEdit):
def __init__(self, line_height_factor=1.5):
super().__init__()
self.line_height_factor = line_height_factor
def paintEvent(self, event):
# Create a custom painter
painter = QPainter(self.viewport())
#Get the document and block
doc = self.document()
block = doc.firstBlock()
# Get font metrics
font_metrics = QFontMetrics(self.font())
line_spacing = font_metrics.lineSpacing() * self.line_height_factor
#Calculate visible area
content_offset_y = self.contentOffset().y()
viewport_rect = self.viewport().rect()
painter.setFont(self.font())
painter.setPen(self.palette().text().color())
# Iterate through blocks
while block.isValid():
layout = block.layout()
if not layout:
block = block.next()
continue
# Get block position
position = doc.findBlock(block.position()).position()
block_rect = self.blockBoundingGeometry(block).translated(self.contentOffset()).toRect()
# Only draw visible blocks
if block_rect.bottom() < viewport_rect.top():
block = block.next()
continue
if block_rect.top() > viewport_rect.bottom():
break
# Draw text with custom line height
lines = block.text().split('\n')
y = block_rect.top()
for line in lines:
if y > viewport_rect.bottom():
break
if y + line_spacing >= viewport_rect.top():
painter.drawText(QRect(0, y, viewport_rect.width(), line_spacing),
Qt.AlignLeft | Qt.AlignTop, line)
y += line_spacing
block = block.next()
painter.end()
class TextEditor(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Custom QPlainTextEdit with Line Height') self.setGeometry(100, 100, 600, 400)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# Use our custom QPlainTextEdit
self.text_edit = CustomPlainTextEdit(line_height_factor=2.0) # Double spacing
layout.addWidget(self.text_edit)
# Set text
self.text_edit.setPlainText("Line 1\nLine 2\nLine 3\nLine 4\nLine 5")
if __name__ == '__main__':
app = QApplication(sys.argv)
editor = TextEditor()
editor.show()
sys.exit(app.exec_())
Method 3: Simple Workaround - Use QTextEdit in Plain Text Mode ... Code omitted...
None of the methods work(from 1 to 3).