В PyQt5 time.sleep срабатывает не тогда когда нужно

В программе на python3 с PyQt5 я делаю такую штуку: в Qt Designer у меня есть textBrowser, lineEdit и кнопка send.

При нажатии кнопки, текст из lineEdit добавляется в textBrowser, после чего по идее должен сработать time.sleep(1). По прошествии времени, которого textBrowser должен вывести "окей", но time.sleep работает не так как надо, при нажатии кнопки он ждет 1 секунду, textBrowser выводит мое сообщение и сразу же выводит "окей", то есть он ждет секунду не после того как сообщение из lineEdit уже добавилось в textBrowser, а перед всем действием после нажатия кнопки. У меня linux и python 3.6.9.

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

Вот код:

main.py

import sys
from PyQt5 import QtWidgets
import time
from test import Ui_MainWindow

class myapp(QtWidgets.QMainWindow):
    def __init__(self):
        super(myapp, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.send.clicked.connect(self.btnClicked)
    def btnClicked(self):
        lineEditText = self.ui.lineEdit.text()
        self.ui.textBrowser.append(lineEditText)
        time.sleep(1)
        self.ui.textBrowser.append("окей")

app = QtWidgets.QApplication([])
window = myapp()
window.show()

app.exec_()

test.py

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(351, 328)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setObjectName("textBrowser")
        self.gridLayout.addWidget(self.textBrowser, 0, 0, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 1, 0, 1, 1)
        self.send = QtWidgets.QPushButton(self.centralwidget)
        self.send.setObjectName("send")
        self.gridLayout.addWidget(self.send, 2, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 351, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.send.setText(_translate("MainWindow", "send"))

Ответы (1 шт):

Автор решения: eri

time.sleep блокирует интерфейс программы, в том числе отрисовку (да оно весь поток блокирует).

Используйте QtCore.QTimer.singleShot чтоб вызвать функцию через определенное время.

def btnClicked(self):
    lineEditText = self.ui.lineEdit.text()
    self.ui.textBrowser.append(lineEditText)
    QtCore.QTimer.singleShot(
        1000,
        functools.partial(self.ui.textBrowser.append, "окей")
    )
→ Ссылка