Как внутри цикла присваивать новые значения в QLineEdit?

Рейтинг: 1Ответов: 1Опубликовано: 01.05.2023

две куклы

Пытаюсь сделать таймер обратного отсчета.
Функция timer3() работает, но при попытке вывода в QLineEdit - self.time_edit.setText(str(self.text)) вывод происходит только после завершения функции полностью.

Можно ли как-то это исправить?

Вывод в консоль работает.
Пользователь вручную в интерфейсе вводит время, далее по клику старт это время получаю и отправляю в функцию timer3()

...

    self.time_edit = QLineEdit(self)
    self.time_edit.setMouseTracking(True)
    self.time_edit.setGeometry(QtCore.QRect(27, 60, 490, 220))
    self.time_edit.setObjectName("time_edit")
    self.time_edit.setMaxLength(8)
    self.time_edit.setText("00:00:00")
    self.time_edit.textEdited.connect(clicked_stop)
    self.time_edit.setStyleSheet('''QLineEdit#time_edit{
                                        font-family: "DS-Digital";
                                        font-size: 120px;
                                        border: solid;
                                        border-width: 0px; 
                                        border-color: rgb(153, 153, 153);
                                        color: rgb(145, 215,227);
                                        padding-left:20px;
                                        padding-right:20px;                                          
                                    }''')

def action_btn_start(self):
    self.text = self.time_edit.text()
    self.text = datetime.strptime(self.text, "%H:%M:%S").time()
    self.timer3()

def action_reset(self):
    self.time_edit.setText("00:00:00")

def timer3(self):
    while (True):
        time.sleep(1)
        
        if self.text.second == 00 and self.text.minute == 00:
            if self.text.hour != 00:
                self.text = self.text.replace(hour=self.text.hour - 1)
                self.text = self.text.replace(minute=59)
                self.text = self.text.replace(second=59)
            else:
                break
        elif self.text.second == 00:
            self.text = self.text.replace(minute=self.text.minute - 1)
            self.text = self.text.replace(second=59)
        elif self.text.second != 00:
            self.text = self.text.replace(second=self.text.second - 1)
        self.time_edit.setText(str(self.text))
        print(self.text)

...

Ответы

▲ 0Принят

Пожалуйста, ВСЕГДА предоставляйте минимально-ВОСПРОИЗВОДИМЫЙ пример, который демонстрирует проблему.

НЕЛЬЗЯ использовать ни while (True):, ни time.sleep(1) в основном потоке приложения - это блокирует интерфейс.

Класс QTimer предоставляет повторяющиеся и однократные таймеры.

import sys
from datetime import datetime
#import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.time_edit = QLineEdit(self)
        self.time_edit.setMouseTracking(True)
        self.time_edit.setObjectName("time_edit")
        self.time_edit.setMaxLength(8)
        self.time_edit.setText("00:01:05")
# --------------------------------------> vvvvv <------------------------        
        self.time_edit.textEdited.connect(self.clicked_stop)
        self.time_edit.setStyleSheet('''QLineEdit#time_edit{
                                            font-family: "DS-Digital";
                                            font-size: 110px;
                                            border: solid;
                                            border-width: 0px; 
                                            border-color: rgb(153, 153, 153);
                                            color: rgb(145, 215,227);
                                            padding-left:20px;
                                            padding-right:20px;                                          
                                        }''')
                                        
        self.pushButton = QPushButton('Старт', self)
        self.pushButton.clicked.connect(self.action_btn_start)
        
        layout =  QtWidgets.QGridLayout(self)
        layout.addWidget(self.time_edit, 0, 0, 1, 2)
        layout.addWidget(self.pushButton, 1, 1)
# +++ vvv         
        self.timer = QtCore.QTimer()
        self.timer.setInterval(1000)                            # 1 сек.
        self.timer.timeout.connect(self.timer3)
# +++ ^^^  

    def action_btn_start(self):
        self.text = self.time_edit.text()
        self.text = datetime.strptime(self.text, "%H:%M:%S").time()
#        self.timer3()
        self.timer.start()                                               # +++
        

    def action_reset(self):                                              # ???
        self.time_edit.setText("00:00:00")                               # ???

    def timer3(self):
#        while (True):
#            time.sleep(1)
            
            if self.text.second == 00 and self.text.minute == 00:
                if self.text.hour != 00:
                    self.text = self.text.replace(hour=self.text.hour - 1)
                    self.text = self.text.replace(minute=59)
                    self.text = self.text.replace(second=59)
                else:
#                    break
                     self.timer.stop()                                     # +++
            elif self.text.second == 00:
                self.text = self.text.replace(minute=self.text.minute - 1)
                self.text = self.text.replace(second=59)
            elif self.text.second != 00:
                self.text = self.text.replace(second=self.text.second - 1)
            self.time_edit.setText(str(self.text))
            print(self.text)
            
    def clicked_stop(self, text):                                          # ???
        print(f'def clicked_stop(self, text): {text}')                     # ???
    
            

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.resize(500, 200)
    w.show()
    sys.exit(app.exec())

введите сюда описание изображения