Skip to content

Instantly share code, notes, and snippets.

@mahenzon
Created July 13, 2018 13:04
Show Gist options
  • Save mahenzon/3b3ca2516d2ce59f24e8b1045bf33ca1 to your computer and use it in GitHub Desktop.
Save mahenzon/3b3ca2516d2ce59f24e8b1045bf33ca1 to your computer and use it in GitHub Desktop.
Simple PyQt5 Timer

Откладываем простые задачи в PyQt5

Иногда при разработке приложений необходимо отложить действие на определенный срок. При этом зачастую отслеживать исполнение нет необходимости. Рассмотрим пример отложенного действия на PyQt5 при помощи QTimer, для этого создадим простейший таймер обратного отсчёта без возможности прерывания.

Для этого добавляем на интерфейс приложения QLCDNumber - на нем мы будем отображать текущее значение, QSlider - при помощи него мы будем устанавливать желаемое значение и кнопку QPushButton для запуска таймера.

Полный листинг программы приведен ниже (с расстановкой элементов и подключением слотов к сигналам), а сейчас я опишу суть:

  • По нажатию кнопки Start отрабатывается метод start_btn_clicked. Для того, чтобы случайно не изменить значение и не нарушить выполнение текущего отсчёта, мы отключаем слайдер и кнопку старта (self.toggle_btns(False)), а затем запускаем сам таймер методом tick_timer.
  • Внутри метода tick_timer мы получаем текущее значение на экране lcd_value = self.lcd.value() и проверяем, достигло ли оно нуля. Если значение больше, то отнимаем от него единицу (у нас отсчёт идет в секундах) и создаем экземпляр QTimer, на котором сразу вызываем метод singleShot: QTimer().singleShot(1000, self.tick_timer). Он создаёт фоновый процесс с обратным отсчётом. Первое значение передаем время, через которое таймер должен сработать (в миллисекундах), а второй параметр - функция, которая должна быть вызвана по окончанию. Передаём туда tick_timer, чтобы достичь нуля на дисплее
  • Как только мы достигли нуля на дисплее, включаем кнопки обратно self.toggle_btns(), а на дисплей устанавливаем значение со слайдера (то значение, с которого мы начали отсчёт в прошлый раз) self.lcd.display(self.slider.value())

Вот и всё, таким образом мы сделали самый простой таймер на PyQt5.

PyQt5 Timer

Полный листинг программы:

import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QWidget, QApplication, \
    QLCDNumber, QSlider, QVBoxLayout, QHBoxLayout, QPushButton


class MainWindow(QWidget):

    def __init__(self):
        super().__init__()

        self.lcd = QLCDNumber(self)
        # Устанавливаем значение по умолчанию на дисплей
        self.lcd.display(1)

        self.slider = QSlider(Qt.Horizontal, self)
        # Устанавливаем минимальное и максимальное значение
        self.slider.setMinimum(1)
        self.slider.setMaximum(90)
        self.slider.valueChanged.connect(self.lcd.display)

        self.start_btn = QPushButton('Start', self)
        self.start_btn.clicked.connect(self.start_btn_clicked)
        self.toggle_btns()

        hbox = QHBoxLayout()
        hbox.addWidget(self.slider)
        hbox.addWidget(self.start_btn)

        vbox = QVBoxLayout()
        vbox.addWidget(self.lcd)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

        self.setWindowTitle('Timer PyQt5')
        self.resize(400, 300)

    def toggle_btns(self, value=True):
        self.slider.setEnabled(value)
        self.start_btn.setEnabled(value)

    def start_btn_clicked(self):
        # Отключаем слайдер и кнопку старта
        self.toggle_btns(False)
        # запускаем отсчет
        self.tick_timer()

    def tick_timer(self):
        # Получаем значение на LCD виджете
        lcd_value = self.lcd.value()
        if lcd_value > 0:
            # Устанавливаем значение на 1 меньше
            self.lcd.display(lcd_value - 1)
            # Засекаем таймер - значение в милисекундах
            # метод singleShot создает поток в фоне, отменить его нельзя
            QTimer().singleShot(1000, self.tick_timer)
        else:
            # Значение дисплея стало 0
            # Включаем элементы интерфейса обратно
            self.toggle_btns()
            # Устанавливаем на дисплей выбранную на слайдере настройку
            self.lcd.display(self.slider.value())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment