как эффект ввода в PyQt?

#python #qt #pyside2

#python #qt #pyside2

Вопрос:

У меня есть следующая программа, но оказывается, что когда она должна передавать текст, программа застревает и не показывает букву за буквой

 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. time.sleep() блокирует основной поток, используйте QTimer.

Ответ №1:

Вы должны реализовать логику получения каждой буквы каждые T секунд с использованием QTimer (не time.sleep) и вставить текст, вы не должны заменять весь текст:

 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_())