PyQt5:如何在QTextEdit中自动滚动文本(动画效果)?

2024-05-19 15:38:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我想问一下如何使文本在qtexted scoll中,达到动画效果。动画效果应该类似于视频中显示的效果:https://www.youtube.com/watch?v=MyeuGdXv4XM

有了PyQt,我想得到这样的效果: 文本应该以2行/秒的速度向下自动缩小,直到到达结尾并停止。在

在下面的代码中,当单击按钮时,文本将显示在QTextEdit小部件中。文本很长,因此显示滚动条。在

我的问题是: 我不知道如何制作动画效果。因此,我想请您帮忙更正我的代码。在

# -*- coding: utf-8 -*-

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

import sys
import time


list_longText = [" long text 1 - auto scrolling " * 1000, " long text 2 - auto scrolling " * 2000]

class Worker(QObject):
    finished = pyqtSignal()
    strTxt = pyqtSignal(str)

    def __init__(self, parent=None):
        super(Worker, self).__init__(parent)

    @pyqtSlot()
    def onJob(self):
        for i in range(2):
            self.strTxt.emit(list_longText[i])
            time.sleep(2)

class MyApp(QWidget):
    def __init__(self):
        super(MyApp, self).__init__()
        self.setFixedSize(600, 400)
        self.setObjectName("window")

        self.initUI()


    def initUI(self):

        self.txt = QTextEdit("", self)
        self.btn = QPushButton("Button", self)
        self.btn.clicked.connect(self.start)

        self.layout = QHBoxLayout(self)
        self.layout.addWidget(self.txt)
        self.layout.addWidget(self.btn)
        self.setLayout(self.layout)

        self.show()

    def start(self):
        self.thread = QThread()
        self.obj = Worker()

        self.obj.strTxt.connect(self.showText)
        self.obj.moveToThread(self.thread)
        self.obj.finished.connect(self.thread.quit)
        self.thread.started.connect(self.obj.onJob)
        self.thread.start()

    def showText(self, str):
        self.txt.setText("{}".format(str))
        self.autoScroll()

    def autoScroll(self):
        vsb = self.txt.verticalScrollBar()
        if vsb.value() <= vsb.maximum():
            vsb.setValue(vsb.value() + 2)
            time.sleep(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyApp()
    sys.exit(app.exec_())

非常感谢你的帮助!在


Tags: from文本importselftxtobjinitdef
1条回答
网友
1楼 · 发布于 2024-05-19 15:38:47

您想要的任务不重,它是周期性的,所以使用线程是不合适的,对于这个任务,我们可以使用QVariantAnimation。在

另一部分是创建一个方法,它移动到文本的某一行,我们使用QTextCursorQTextDocumentfindBlockByLineNumber()旁边。在

对于最后一个,我们必须开始移动到最后一个可见的初始值,我们使用cursorForPosition()方法,通过viewport()的大小。在

longText = "\n".join(["{}: long text - auto scrolling ".format(i) for i in range(100)])

class AnimationTextEdit(QTextEdit):
    def __init__(self, *args, **kwargs):
        QTextEdit.__init__(self, *args, **kwargs)
        self.animation = QVariantAnimation(self)
        self.animation.valueChanged.connect(self.move)

    @pyqtSlot()
    def startAnimation(self):
        self.animation.stop()
        lines_per_second = 2
        self.moveToLine(0)
        p = QPoint(self.viewport().width() - 1, self.viewport().height() - 1)
        cursor = self.cursorForPosition(p)
        self.animation.setStartValue(cursor.blockNumber())
        self.animation.setEndValue(self.document().blockCount()-1)
        self.animation.setDuration(self.animation.endValue()*1000/lines_per_second)
        self.animation.start()

    @pyqtSlot(QVariant)
    def move(self, i):
        cursor = QTextCursor(self.document().findBlockByLineNumber(i))
        self.setTextCursor(cursor)

class MyApp(QWidget):
    def __init__(self):
        super(MyApp, self).__init__()
        self.setFixedSize(600, 400)
        self.txt = AnimationTextEdit(self)
        self.btn = QPushButton("Start", self)
        self.layout = QHBoxLayout(self)
        self.layout.addWidget(self.txt)
        self.layout.addWidget(self.btn)
        self.txt.append(longText)
        self.txt.move(0)
        self.btn.clicked.connect(self.txt.startAnimation)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

更新:

如果要连续移动,必须使用verticalScrollBar()

^{pr2}$

相关问题 更多 >