Автоматическое расширение и сжатие QTextEdit для PyQt5Python

Программы на Python
Anonymous
Автоматическое расширение и сжатие QTextEdit для PyQt5

Сообщение Anonymous »

Я пытаюсь создать собственный виджет QTextEdit в PyQt5, который автоматически расширяется и сжимается в зависимости от его содержимого. Виджет должен увеличиваться в высоту по мере того, как пользователь вводит новые строки, и уменьшаться, когда строки удаляются. У меня есть некоторый код, но когда размер TextEdit изменяется, размер окна остается постоянным, поэтому виджет над TextEdit, который должен иметь динамический размер, увеличивается в размере. Мой код CustomTextEdit выглядит следующим образом:

Код: Выделить всё

# CustomTextEdit.py

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class CustomTextEdit(QTextEdit):
def __init__(self, max_lines=5, parent=None):
super().__init__(parent)
self.max_lines = max_lines
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
self.document().contentsChanged.connect(self.update_height)

self.setFixedHeight(self.fontMetrics().height())

def update_height(self):
document_height = self.document().size().height()
line_height = self.fontMetrics().lineSpacing()

text_layout = self.document().documentLayout()
block = self.document().begin()
num_lines = 0
while block.isValid():
layout = block.layout()
num_lines += layout.lineCount()
block = block.next()

desired_height = document_height + self.contentsMargins().top() + self.contentsMargins().bottom()

if num_lines > self.max_lines:
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
else:
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setFixedHeight(int(desired_height))

self.scroll_to_bottom()

def scroll_to_bottom(self):
scrollbar = self.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())

Код: Выделить всё

# NewMessageWidget.py

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import time
from . import utils
from .CustomTextEdit import CustomTextEdit

class NewMessageWidget(QWidget):
def __init__(self, chat_window):
super().__init__(chat_window)
self.chat_window = chat_window

self.layout = QVBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.layout)

self.text_edit = CustomTextEdit(5, self)
self.layout.addWidget(self.text_edit)
self.text_edit.setStyleSheet("""
font-size: 12pt;
""")
QTimer().singleShot(5, self.text_edit.update_height)

Код: Выделить всё

# ChatWindow.py

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from . import utils

class ChatWindow(QWidget):
def __init__(self, main_window):
super().__init__(main_window)
self.main_window = main_window

self.layout = QVBoxLayout()
self.layout.setSpacing(0)
self.layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(self.layout)

def init_ui(self):
from .ChatWidget import ChatWidget
from .NewMessageWidget import NewMessageWidget

utils.clear_layout(self.layout)

self.chat_widget = ChatWidget(self)
self.chat_widget.add_to_layout(self.layout)

self.new_message_widget = NewMessageWidget(self)
self.layout.addWidget(self.new_message_widget, alignment=Qt.AlignBottom)

#self.layout.addStretch()

Код: Выделить всё

# ChatWidget.py

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import time
from .  import utils

class ChatWidget(QFrame):
def __init__(self, chat_window):
super().__init__(chat_window)
self.chat_window = chat_window

self.setObjectName("chatbox")
self.setStyleSheet("#chatbox {background-color: black; border: 0;}")

self.scroll_area = QScrollArea(chat_window)
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setWidget(self)
self.scroll_area.setStyleSheet("""
QScrollArea {
}
QScrollBar:vertical {
background-color: black;
color: white;
}
""")

self.setMinimumHeight(utils.pt_to_px(337))
self.setMinimumWidth(utils.pt_to_px(225))
self.scroll_area.setMinimumHeight(utils.pt_to_px(340))
self.scroll_area.setMinimumWidth(utils.pt_to_px(250))

self.layout = QVBoxLayout(self)
self.layout.setSpacing(0)
self.setLayout(self.layout)

self.layout.addStretch()
self.layout.setDirection(QBoxLayout.TopToBottom)

self.add_message_bubble("Hello, im me or whatever lol. Damn I really hope this acc works now man, WOW!", 1718283735.9385817, ["me", "random", "testing"])
self.add_message_bubble("Hello, im me or whatever lol", 1719283735.9385817, ["me", "random", "testing"])
self.add_message_bubble("Hi", 1725283735.9385817, ["greetings"])

def add_to_layout(self, layout):
layout.addWidget(self.scroll_area)

def add_message_bubble(self, content, timestamp, tags):
from .MessageBubble import MessageBubble

message_bubble = MessageBubble(self, content, timestamp, tags)
self.layout.insertWidget(self.layout.count() - 1, message_bubble)
Пример изображения пользовательского интерфейса
Буду признателен, если кто-нибудь поможет, спасибо!
Попытка/ Цель/Ожидание: я пытался изменить размер TextEdit по мере увеличения количества строк.
Проблема: размеры других виджетов изменяются/размер окна не изменяется.

Подробнее здесь: https://stackoverflow.com/questions/786 ... -for-pyqt5

Вернуться в «Python»