Python 如何在QTextEdit中自动滚动文本(动画效果)?
我想问一下如何在qtexteditscoll中制作文本,以实现动画效果。动画效果应该与视频中显示的类似: 使用PyQt,我希望获得以下效果: 文本应以2行/秒的速度自动向下滚动,直到到达末尾并停止 在下面的代码中,单击按钮时,文本显示在QTextEdit小部件中。文本很长,因此会显示滚动条 我的问题是: 我不知道如何制作动画效果。因此,我想请您帮助更正我的代码Python 如何在QTextEdit中自动滚动文本(动画效果)?,python,pyqt,pyqt5,qtextedit,Python,Pyqt,Pyqt5,Qtextedit,我想问一下如何在qtexteditscoll中制作文本,以实现动画效果。动画效果应该与视频中显示的类似: 使用PyQt,我希望获得以下效果: 文本应以2行/秒的速度自动向下滚动,直到到达末尾并停止 在下面的代码中,单击按钮时,文本显示在QTextEdit小部件中。文本很长,因此会显示滚动条 我的问题是: 我不知道如何制作动画效果。因此,我想请您帮助更正我的代码 # -*- coding: utf-8 -*- from PyQt5.QtWidgets import * from PyQt5.Qt
# -*- 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_())
#-*-编码:utf-8-*-
从PyQt5.QtWidgets导入*
从PyQt5.QtGui导入*
从PyQt5.QtCore导入*
导入系统
导入时间
列表_longText=[“长文本1-自动滚动”*1000,“长文本2-自动滚动”*2000]
班级工作人员(QObject):
finished=pyqtSignal()
strTxt=pyqtSignal(str)
def uuu init uuu(self,parent=None):
超级(工作者,自我)。\uuuu初始\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
@pyqtSlot()
def在职(自我):
对于范围(2)中的i:
self.strText.emit(list_longText[i])
时间。睡眠(2)
类MyApp(QWidget):
定义初始化(自):
超级(MyApp,self)。\uuuu init\uuuuu()
自设置固定大小(600400)
self.setObjectName(“窗口”)
self.initUI()
def initUI(self):
self.txt=QTextEdit(“,self)
self.btn=QPushButton(“按钮”,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启动(自):
self.thread=QThread()
self.obj=Worker()
self.obj.strText.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自动滚动(自):
vsb=self.txt.verticalScrollBar()
如果vsb.value()您想要的任务并不繁重,它是周期性的,因此使用线程是不合适的,对于此任务,我们可以使用QVariantAnimation
另一部分是创建一个移动到特定文本行的方法,我们在QTextDocument
的findBlockByLineNumber()旁边使用QTextCursor
对于最后一个,我们必须开始移动到最后一个可见的初始值。对于它,我们使用cursorForPosition()
方法通过viewport()
的大小
更新:
如果要连续移动,必须使用垂直滚动条()
:
@eyllanesc我粘贴视频只是为了表示。它显示文本已自动向上“移动”或“平移”。在视频中,文本来自底部,但在我的例子中,文本可以从顶部开始。正如我所说,这段视频只是一个代表。我编辑了上面的问题,现在可以理解了吗?@eyllanesc当点击按钮时,文本被加载,并开始自动滚动。一切都应该自动完成。只需单击一下,其余的都会自动运行。@eyllanesc我不想下载视频。这段视频只是为了表现,仅此而已。我只想让文本自动滚动。“是你不明白我的意思吗?”艾伦斯克现在我明白你的意思了。我想在开始时(单击按钮时)加载全文,但一点一点地显示文本。@eyllanesc是的,单击按钮时加载所有文本,然后自动启动自动滚动。太好了!非常感谢你!你的想法和我的大不相同。它是有效的,但我必须学习更多来理解它是如何工作的。:-)嗨@eyllanesc,我可以问你一些提示来让文本流畅地滚动吗?上面的方法逐行移动文本。是否有任何方法逐像素扫描文本?谢谢,谢谢!我取消勾选答案是做错了。对不起。
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_())
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.moveToLine)
@pyqtSlot()
def startAnimation(self):
self.animation.stop()
self.animation.setStartValue(0)
self.animation.setEndValue(self.verticalScrollBar().maximum())
self.animation.setDuration(self.animation.endValue()*4)
self.animation.start()
@pyqtSlot(QVariant)
def moveToLine(self, i):
self.verticalScrollBar().setValue(i)
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.moveToLine(0)
self.btn.clicked.connect(self.txt.startAnimation)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())