RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1235877
Accepted
Николай Смирнов
Николай Смирнов
Asked:2022-01-25 21:32:03 +0000 UTC2022-01-25 21:32:03 +0000 UTC 2022-01-25 21:32:03 +0000 UTC

PyQt5。根据包含的文本行数调整 QPlainTextEdit 高度

  • 772

我在这里领悟PyQt5,我写一个聊天。我需要设置消息小部件的样式。

问题是什么:用户缩小聊天窗口,消息小部件随之缩小,分别位于不可编辑的文本QPlainTextEdit,消息自动换行到下一行,即高度增长,消息小部件本身不会扩展,并且QPlainTextEdit出现滚动,但它应该使滚动不会出现,而是QPlainTextEdit根据其中文本的高度(或行数)增加(和减少)其高度。

在图片上:

  • 窗口的初始位置(我们可以看到,消息的高度不适应): 如我们所见,帖子高度不适应

  • 缩小窗口(我们可以看到,消息的最后一行是隐藏的): 我们可以看到,消息的最后一行被隐藏了

我尝试了什么:

  • 我连接了documentSizeChanged来自 documentLayout 的信号,并根据文档的高度增加或减少了消息的高度。但是,在编辑时会出现此信号QPlainTextEdit,对我来说它只显示文本。连接到documentSizeChanged: txtMessageText.document().documentLayout().documentSizeChanged.connect(self.on_documentSize_changed)

我看不出插入插槽代码的意义,因为这个信号无论如何都不起作用。

  • 我挂上了信号 rangeChanged yverticalScrollBar并根据滚动条的最大值增加或减少消息的高度,但是,使用这种方法,如果窗口扩展到全屏,则消息不会改变其大小。

连接到rangeChanged: txtMessageText.verticalScrollBar().rangeChanged.connect(self.on_range_changed)

插槽on_range_changed:

    @pyqtSlot(int, int)
    def on_mod_changed(self, min_, max_):
        # нашел виджет сообщения
        parent = self.sender().parent().parent().parent().parent().parent().parent()
        # изменяю размер пока так: 
        # (к сообщению добавляется пустая строка, которая будет скрыта, 
        #  то есть постоянно пытаюсь сохранить максимальное значение равным 1 (max_==1))
        if max_>1:
            parent.setMinimumSize(parent.minimumWidth(), parent.minimumHeight() + 25)
            parent.setMaximumSize(parent.maximumWidth(), parent.minimumHeight() + 25)
        elif max_<1:
            parent.setMinimumSize(parent.minimumWidth(), parent.minimumHeight() - 25)
            parent.setMaximumSize(parent.maximumWidth(), parent.minimumHeight() - 25)

你将如何在PyQt5QPlainTextEdit中进行高度适应?

升级版。这是一个最小的例子:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_Client(object):
        def setupUi(self, Client):
            Client.setObjectName("Client")
            Client.resize(522, 228)
            Client.setStyleSheet("QMainWindow{\n"
    "background-color: #29334A;\n"
    "}\n"
    "\n"
    "QFrame {\n"
    "background-color: #29334A;\n"
    "}\n"
    "\n"
    "QLabel {\n"
    "color: #E8EAF1;\n"
    "font-size:24px\n"
    "}\n"
    "\n"
    "QPlainTextEdit {\n"
    "color: #E8EAF1;\n"
    "}\n"
    "\n"
    "")
            self.centralwidget = QtWidgets.QWidget(Client)
            self.centralwidget.setMinimumSize(QtCore.QSize(0, 6))
            self.centralwidget.setObjectName("centralwidget")
            self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
            self.verticalLayout_2.setObjectName("verticalLayout_2")
            self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
            self.scrollArea.setWidgetResizable(True)
            self.scrollArea.setObjectName("scrollArea")
            self.scrollAreaWidgetContents = QtWidgets.QWidget()
            self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 502, 408))
            self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
            self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
            self.verticalLayout_3.setObjectName("verticalLayout_3")
            self.frame_2 = QtWidgets.QFrame(self.scrollAreaWidgetContents)
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
            self.frame_2.setSizePolicy(sizePolicy)
            self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
            self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
            self.frame_2.setObjectName("frame_2")
            self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_2)
            self.horizontalLayout.setObjectName("horizontalLayout")
            self.frame = QtWidgets.QFrame(self.frame_2)
            self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
            self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
            self.frame.setObjectName("frame")
            self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
            self.verticalLayout.setContentsMargins(0, 0, 0, 0)
            self.verticalLayout.setObjectName("verticalLayout")
            self.label = QtWidgets.QLabel(self.frame)
            self.label.setObjectName("label")
            self.verticalLayout.addWidget(self.label)
            self.plainTextEdit = QtWidgets.QPlainTextEdit(self.frame)
            self.plainTextEdit.setReadOnly(True)
            self.plainTextEdit.setObjectName("plainTextEdit")
            self.verticalLayout.addWidget(self.plainTextEdit)
            self.label_2 = QtWidgets.QLabel(self.frame)
            self.label_2.setObjectName("label_2")
            self.verticalLayout.addWidget(self.label_2)
            self.horizontalLayout.addWidget(self.frame)
            spacerItem = QtWidgets.QSpacerItem(197, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
            self.horizontalLayout.addItem(spacerItem)
            self.verticalLayout_3.addWidget(self.frame_2)
            spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
            self.verticalLayout_3.addItem(spacerItem1)
            self.scrollArea.setWidget(self.scrollAreaWidgetContents)
            self.verticalLayout_2.addWidget(self.scrollArea)
            Client.setCentralWidget(self.centralwidget)
    
            self.retranslateUi(Client)
            QtCore.QMetaObject.connectSlotsByName(Client)
    
        def retranslateUi(self, Client):
            _translate = QtCore.QCoreApplication.translate
            Client.setWindowTitle(_translate("Client", "Client"))
            self.label.setText(_translate("Client", "Имя Пользователя"))
            self.plainTextEdit.setPlainText(_translate("Client", "11111111111111111111111111111111111111111222222222222222222222222222222222222222223333333333333333333333333333333333333333344444444444444444444444444444444444444444555555555555555555555555555555555555555556666666666666666666666666666666666666666677777777777777777777777777777777777777777888888888888888888888888888888888888888889999999999999999999999999999999999999999910101010101010101010101010101010101010101"))
            self.label_2.setText(_translate("Client", "Дата  Время"))
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        Client = QtWidgets.QMainWindow()
        ui = Ui_Client()
        ui.setupUi(Client)
        Client.show()
        sys.exit(app.exec_())

其中会发生什么:当应用程序窗口变窄时,会QPlainTextEdit出现滚动,并且隐藏了部分文本,但是您需要确保消息的高度随着QPlainTextEdit.

python
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    S. Nick
    2022-01-25T22:31:24Z2022-01-25T22:31:24Z

    void QPlainTextEdit:: updateRequest (const QRect &rect, int dy)

    当文本文档需要更新指定的矩形时发出此信号。如果文本可滚动,则矩形覆盖整个视口。如果文本垂直滚动,dy 包含视口滚动的像素数。

    请注意,我已删除self.plainTextEdit.setReadOnly(True),因此您可以检查发生了什么。

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_Client(object):
        def setupUi(self, Client):
            Client.setObjectName("Client")
            Client.resize(522, 228)
            Client.setStyleSheet("QMainWindow{\n"
    "background-color: #29334A;\n"
    "}\n"
    "\n"
    "QFrame {\n"
    "background-color: #29334A;\n"
    "}\n"
    "\n"
    "QLabel {\n"
    "color: #E8EAF1;\n"
    "font-size:24px\n"
    "}\n"
    "\n"
    "")
            self.centralwidget = QtWidgets.QWidget(Client)
            self.centralwidget.setMinimumSize(QtCore.QSize(0, 6))
            self.centralwidget.setObjectName("centralwidget")
            self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget)
            self.verticalLayout_2.setObjectName("verticalLayout_2")
            self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)
            self.scrollArea.setWidgetResizable(True)
            self.scrollArea.setObjectName("scrollArea")
            self.scrollAreaWidgetContents = QtWidgets.QWidget()
            self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 502, 408))
            self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
            self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
            self.verticalLayout_3.setObjectName("verticalLayout_3")
            self.frame_2 = QtWidgets.QFrame(self.scrollAreaWidgetContents)
            sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
            self.frame_2.setSizePolicy(sizePolicy)
            self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
            self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
            self.frame_2.setObjectName("frame_2")
            self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_2)
            self.horizontalLayout.setObjectName("horizontalLayout")
            self.frame = QtWidgets.QFrame(self.frame_2)
            self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
            self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
            self.frame.setObjectName("frame")
            self.verticalLayout = QtWidgets.QVBoxLayout(self.frame)
            self.verticalLayout.setContentsMargins(0, 0, 0, 0)
            self.verticalLayout.setObjectName("verticalLayout")
            self.label = QtWidgets.QLabel(self.frame)
            self.label.setObjectName("label")
            self.verticalLayout.addWidget(self.label)
    
            
            self.plainTextEdit = QtWidgets.QPlainTextEdit(self.frame)
    #        self.plainTextEdit.setReadOnly(True)
            self.plainTextEdit.setObjectName("plainTextEdit")
            self.verticalLayout.addWidget(self.plainTextEdit)
            
            
            self.label_2 = QtWidgets.QLabel(self.frame)
            self.label_2.setObjectName("label_2")
            self.verticalLayout.addWidget(self.label_2)
            self.horizontalLayout.addWidget(self.frame)
            spacerItem = QtWidgets.QSpacerItem(197, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
            self.horizontalLayout.addItem(spacerItem)
            self.verticalLayout_3.addWidget(self.frame_2)
            spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
            self.verticalLayout_3.addItem(spacerItem1)
            self.scrollArea.setWidget(self.scrollAreaWidgetContents)
            self.verticalLayout_2.addWidget(self.scrollArea)
            Client.setCentralWidget(self.centralwidget)
    
            self.retranslateUi(Client)
            QtCore.QMetaObject.connectSlotsByName(Client)
    
        def retranslateUi(self, Client):
            _translate = QtCore.QCoreApplication.translate
            Client.setWindowTitle(_translate("Client", "Client"))
            self.label.setText(_translate("Client", "Имя Пользователя"))
            self.plainTextEdit.setPlainText(_translate("Client", "11111111111111111111111111111111111111111222222222222222222222222222222222222222223333333333333333333333333333333333333333344444444444444444444444444444444444444444555555555555555555555555555555555555555556666666666666666666666666666666666666666677777777777777777777777777777777777777777888888888888888888888888888888888888888889999999999999999999999999999999999999999910101010101010101010101010101010101010101"))
            self.label_2.setText(_translate("Client", "Дата  Время"))
    
    
    class Window(QtWidgets.QMainWindow, Ui_Client):
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            
            self.plainTextEdit.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.plainTextEdit.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
    
            self.plainTextEdit.appendHtml(""" <h3 style='color: red;'> Hello World </h3>
    Подцепился к сигналу documentSizeChanged у documentLayout и увеличивал или 
    уменьшал высоту сообщения, в зависимости от высоты документа. 
    Однако, этот сигнал возникает при редактировании в QPlainTextEdit, 
    а у меня он только отображает текст. Подключение к documentSizeChanged:   ...
            """)     
            self.plainTextEdit.updateRequest.connect(self.handle_updateRequest)         # !!!
            self.handle_updateRequest(QtCore.QRect(), 0)                           
    
        def handle_updateRequest(self, rect, dy):
            doc = self.plainTextEdit.document()
            tb = doc.findBlockByNumber(doc.blockCount() - 1)
            h = self.plainTextEdit.blockBoundingGeometry(tb).bottom() + 2 * doc.documentMargin()
            self.plainTextEdit.setFixedHeight(h)
            
        
    if __name__ == '__main__':
        import sys
        
        app = QtWidgets.QApplication(sys.argv)
        w = Window()
        w.show()
        sys.exit(app.exec_())
    

    在此处输入图像描述

    在此处输入图像描述

    • 2

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5