how Typing effect in PyQT?

502 views Asked by At

I have the following program but it turns out that when it has to pass the text the program gets stuck and does not show letter by letter

import sys
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from time import sleep
from mensaje import Ui_MainWindow


class mensaje(QMainWindow):
 def __init__(self, parent=None):
     super(mensaje, self).__init__(parent)
     self.mensaje = Ui_MainWindow()
     self.mensaje.setupUi(self)
     self.mensaje.pushButton_2.clicked.connect(self.typetext)

 def typetext(self):
     t = "hello world"
     a = ""
     for i in t:
         a = a + i
         self.mensaje.texto.setText(a)
         sleep(0.5)
if __name__ == "__main__":
 app = QApplication(sys.argv)
 app.setQuitOnLastWindowClosed(True)
 myapp = mensaje()
 myapp.show()
 sys.exit(app.exec_())
1

There are 1 answers

0
eyllanesc On BEST ANSWER

You have to implement the logic of getting each letter every T second using a QTimer (not time.sleep) and insert the text, you should not replace all the text:

import sys

from PySide2.QtCore import QObject, QTimer, Signal
from PySide2.QtWidgets import QApplication, QMainWindow

from mensaje import Ui_MainWindow


class Producer(QObject):
    letterChanged = Signal(str)

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

        self._text = ""
        self._text_it = None
        self._timer = QTimer(self, timeout=self._handle_timeout)

    @property
    def text(self):
        return self._text

    @text.setter
    def text(self, text):
        self._text = text

    def start(self, interval=1000):
        self._text_it = iter(self.text)
        self._timer.start(interval)
        self._handle_timeout()

    def stop(self):
        self._timer.stop()
        self._text_it = None

    def _handle_timeout(self):
        try:
            letter = next(self._text_it)
        except StopIteration as e:
            self._timer.stop()
        else:
            self.letterChanged.emit(letter)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.mensaje = Ui_MainWindow()
        self.mensaje.setupUi(self)

        self.producer = Producer()
        self.producer.text = "hello world"

        self.producer.letterChanged.connect(self.mensaje.texto.insert)
        self.mensaje.pushButton_2.clicked.connect(self.handle_clicked)

    def handle_clicked(self):
        self.producer.start(500)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(True)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())