Как динамически обновлять время в мультитаймере pyqt
У меня есть мультитаймер. Он работает по такому принципу:
Мы вводим время, нажимаем кнопку start, вычисляется время окончания таймера и записывается в словари по типу {"Timer 1": QDateTime} и {QDateTime: "Timer 1"}. Затем в QListWidget'ы выводится время окончания таймера и сколько осталось минут до окончания таймера.
Работает по такому принципу потому-что иногда нужно ускорять таймер в х1.5 раз(Есть checkBox).
Все работает отлично, только я ходел бы еще динамическое обновление времени в QListWidget и в QTimeEdit. У меня есть кнопка и функция для этого, но я хочу чтобы время обновлялось автоматически.
Может быть есть способ реализации этого всего этого более простым и эффективным способом, но мне главное чтобы обновлялось время?
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QDate, QTime, QDateTime, Qt
import time
timer_list = ["Timer 1", "Timer 2", "Timer 3", "Timer 4"]
timer_active_by_timeEnd = {}
timer_active_by_timer = {}
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.setWindowModality(QtCore.Qt.WindowModal)
MainWindow.resize(500, 269)
font = QtGui.QFont()
font.setBold(False)
font.setWeight(50)
MainWindow.setFont(font)
MainWindow.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
MainWindow.setMouseTracking(False)
MainWindow.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/Icon/Gold-Pickaxe-icon.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
MainWindow.setWindowIcon(icon)
MainWindow.setIconSize(QtCore.QSize(128, 128))
MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label_1 = QtWidgets.QLabel(self.centralwidget)
self.label_1.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_1.setAlignment(QtCore.Qt.AlignCenter)
self.label_1.setObjectName("label_1")
self.verticalLayout_3.addWidget(self.label_1)
self.timeEdit_1 = QtWidgets.QTimeEdit(self.centralwidget)
self.timeEdit_1.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.timeEdit_1.setAlignment(QtCore.Qt.AlignCenter)
self.timeEdit_1.setObjectName("timeEdit_1")
self.verticalLayout_3.addWidget(self.timeEdit_1)
self.btn_1 = QtWidgets.QPushButton(self.centralwidget)
self.btn_1.setMaximumSize(QtCore.QSize(16777215, 25))
self.btn_1.setObjectName("btn_1")
self.verticalLayout_3.addWidget(self.btn_1)
self.horizontalLayout_5.addLayout(self.verticalLayout_3)
self.verticalLayout_4 = QtWidgets.QVBoxLayout()
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.verticalLayout_4.addWidget(self.label_2)
self.timeEdit_2 = QtWidgets.QTimeEdit(self.centralwidget)
self.timeEdit_2.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.timeEdit_2.setAlignment(QtCore.Qt.AlignCenter)
self.timeEdit_2.setObjectName("timeEdit_2")
self.verticalLayout_4.addWidget(self.timeEdit_2)
self.btn_2 = QtWidgets.QPushButton(self.centralwidget)
self.btn_2.setMaximumSize(QtCore.QSize(16777215, 25))
self.btn_2.setObjectName("btn_2")
self.verticalLayout_4.addWidget(self.btn_2)
self.horizontalLayout_5.addLayout(self.verticalLayout_4)
self.verticalLayout.addLayout(self.horizontalLayout_5)
self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
self.horizontalLayout_6.setObjectName("horizontalLayout_6")
self.verticalLayout_5 = QtWidgets.QVBoxLayout()
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.verticalLayout_5.addWidget(self.label_3)
self.timeEdit_3 = QtWidgets.QTimeEdit(self.centralwidget)
self.timeEdit_3.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.timeEdit_3.setAlignment(QtCore.Qt.AlignCenter)
self.timeEdit_3.setObjectName("timeEdit_3")
self.verticalLayout_5.addWidget(self.timeEdit_3)
self.btn_3 = QtWidgets.QPushButton(self.centralwidget)
self.btn_3.setMaximumSize(QtCore.QSize(16777215, 25))
self.btn_3.setObjectName("btn_3")
self.verticalLayout_5.addWidget(self.btn_3)
self.horizontalLayout_6.addLayout(self.verticalLayout_5)
self.verticalLayout_13 = QtWidgets.QVBoxLayout()
self.verticalLayout_13.setObjectName("verticalLayout_13")
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setLayoutDirection(QtCore.Qt.LeftToRight)
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
self.label_4.setObjectName("label_4")
self.verticalLayout_13.addWidget(self.label_4)
self.timeEdit_4 = QtWidgets.QTimeEdit(self.centralwidget)
self.timeEdit_4.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.timeEdit_4.setAlignment(QtCore.Qt.AlignCenter)
self.timeEdit_4.setObjectName("timeEdit_4")
self.verticalLayout_13.addWidget(self.timeEdit_4)
self.btn_4 = QtWidgets.QPushButton(self.centralwidget)
self.btn_4.setMaximumSize(QtCore.QSize(16777215, 25))
self.btn_4.setObjectName("btn_4")
self.verticalLayout_13.addWidget(self.btn_4)
self.horizontalLayout_6.addLayout(self.verticalLayout_13)
self.verticalLayout.addLayout(self.horizontalLayout_6)
self.horizontalLayout.addLayout(self.verticalLayout)
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.verticalLayout_40 = QtWidgets.QVBoxLayout()
self.verticalLayout_40.setObjectName("verticalLayout_40")
self.listWidget_2 = QtWidgets.QListWidget(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.listWidget_2.sizePolicy().hasHeightForWidth())
self.listWidget_2.setSizePolicy(sizePolicy)
self.listWidget_2.setObjectName("listWidget_2")
self.verticalLayout_40.addWidget(self.listWidget_2)
self.horizontalLayout_2.addLayout(self.verticalLayout_40)
self.verticalLayout_41 = QtWidgets.QVBoxLayout()
self.verticalLayout_41.setObjectName("verticalLayout_41")
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth())
self.listWidget.setSizePolicy(sizePolicy)
self.listWidget.setObjectName("listWidget")
self.verticalLayout_41.addWidget(self.listWidget)
self.horizontalLayout_2.addLayout(self.verticalLayout_41)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.horizontalLayout_10 = QtWidgets.QHBoxLayout()
self.horizontalLayout_10.setObjectName("horizontalLayout_10")
self.checkBox_2 = QtWidgets.QCheckBox(self.centralwidget)
self.checkBox_2.setMaximumSize(QtCore.QSize(200, 16777215))
self.checkBox_2.setObjectName("checkBox_2")
self.horizontalLayout_10.addWidget(self.checkBox_2)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_10.addItem(spacerItem)
self.verticalLayout_2.addLayout(self.horizontalLayout_10)
self.btn_update = QtWidgets.QPushButton(self.centralwidget)
self.btn_update.setObjectName("btn_update")
self.verticalLayout_2.addWidget(self.btn_update)
self.horizontalLayout.addLayout(self.verticalLayout_2)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "BossTimer"))
self.label_1.setText(_translate("MainWindow", "1"))
self.btn_1.setText(_translate("MainWindow", "Start"))
self.label_2.setText(_translate("MainWindow", "2"))
self.btn_2.setText(_translate("MainWindow", "Start"))
self.label_3.setText(_translate("MainWindow", "3"))
self.btn_3.setText(_translate("MainWindow", "Start"))
self.label_4.setText(_translate("MainWindow", "4"))
self.btn_4.setText(_translate("MainWindow", "Start"))
self.checkBox_2.setText(_translate("MainWindow", "x1.5"))
self.btn_update.setText(_translate("MainWindow", "Update"))
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.lists() # Cоздаем списки QPushButton и QTimeEdit
self.btn_connect() # Подключаем кнопки к функции
def lists(self):
self.btn_list = [self.btn_1, self.btn_2, self.btn_3, self.btn_4]
self.tm_list = [self.timeEdit_1, self.timeEdit_2, self.timeEdit_3, self.timeEdit_4]
def btn_connect(self):
self.btn_1.clicked.connect(lambda: self.start_timer(0))
self.btn_2.clicked.connect(lambda: self.start_timer(1))
self.btn_3.clicked.connect(lambda: self.start_timer(2))
self.btn_4.clicked.connect(lambda: self.start_timer(3))
self.btn_update.clicked.connect(self.update)
def QTimeToSec(self, convert_time): # Функция которая преобразовывает QTime в секунды
return (convert_time.hour()*60+convert_time.minute())*60
def start_timer(self, timer_id): # Функция вызывается при нажатии кнопки старт, в функцию передается id тамера (1, 2, 3, 4)
if self.btn_list[timer_id].text() == "Start": # Если кнопка Start
Now = QDateTime.currentDateTime() # Получаем текущее вермя
QTimeLeft = self.tm_list[timer_id].time() # Получаем время из QTimeEdit
SecTimeLeft = self.QTimeToSec(QTimeLeft) # Переводим QTime в секунды
if self.checkBox_2.checkState() == 2: # Ускоритель х1.5
SecTimeLeft = int(SecTimeLeft/1.5)
timeEnd = Now.addSecs(SecTimeLeft) # Вичесляем время окончания таймера
timer_active_by_timeEnd[timeEnd] = timer_list[timer_id] # Добавляем в словарь по Окончании времени
timer_active_by_timer[timer_list[timer_id]] = timeEnd # Добавляем в словарь по названию таймера
self.btn_list[timer_id].setText("Stop") # Изменяем названия кнопки
elif self.btn_list[timer_id].text() == "Stop":
self.b_del(timer_list[timer_id]) # Удаляем таймер
self.update_lists() # Обновляем списки
def b_del(self, timer_id):
del timer_active_by_timeEnd[timer_active_by_timer[timer_id]] # Удаляем таймер в словарях
del timer_active_by_timer[timer_id]
self.btn_list[timer_list.index(timer_id)].setText("Start") # Меняем названия кнопки
def update_lists(self):
res = ""
timeNow = QTime.currentTime()
keys = timer_active_by_timeEnd.keys() # Получаем ключи из словаря
keys = sorted(keys) # Сортируем ключи
self.listWidget_2.clear() # Очищяем виджеты
self.listWidget.clear()
for key in keys: # Выводи список на 1-ый виджет. Вычетаем из времени окончания таймера текущее время и переводим в минуты
addsecs = self.QTimeToSec(timeNow)*-1
timeLeft = key.addSecs(addsecs)
MinTimeLeft = timeLeft.time().hour()*60+timeLeft.time().minute()
self.listWidget.addItem(timer_active_by_timeEnd[key] + " -> " + str(MinTimeLeft)+ "m")
for key in keys: # Выводи список на 2-ой виджет. Переводи QTime в строку
self.listWidget_2.addItem(key.toString("hh:mm")+" -> "+timer_active_by_timeEnd[key])
def update(self): # Функция обновления времени
timeNow = QTime.currentTime()
keys = timer_active_by_timer.keys() # Получаем список активных таймеров
for key in keys:
addsecs = ((timeNow.hour()*60+timeNow.minute())*60+timeNow.second())*-1 # Переводим текущее время в секунды
timeLeft = timer_active_by_timer[key].addSecs(addsecs) # Вычетаем из времени окончания таймера текущее время
self.tm_list[timer_list.index(key)].setTime(timeLeft.time()) # Устанавляваем оставшееся время для таймера в QTimeEdit
self.update_lists() # Обновляем список
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Ответы (1 шт):
Вам надо воспользоваться таймером (некий мастер-таймер), для этого используйте класс QTimer:
from PyQt5.QtCore import QTimer
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.lists() # Cоздаем списки QPushButton и QTimeEdit
self.btn_connect() # Подключаем кнопки к функции
self.masterTimer = QTimer()
self.masterTimer.timeout.connect(self.update) # периодический сигнал-вызов метода через интервал timeout (здесь 0.5 сек)
self.masterTimer.start(500) # СТАРТ таймера с интервалом 0.5 сек
...