Search on blog:

PyQt: Jak użyć QTimer aby uruchomić funkcję wiele razy w tych samych odstępach czasu.

Jeśli chcesz uruchomić jakaś funkcję z opóźnieniem to możesz wykorzystać time.sleep() ale to blokuje resztę kodu. Możesz też uruchomić to w osobnym wątku i wtedy już to nie blokuje reszty kodu. Możesz też próbować jakiś używać modułów typu shedule, shed to zarządzania zadaniami lub wręcz wykorzystać zewnętrze programy jak cron pod Linux do załawienia tego.

Ale kiedy pracujesz z jakimś frameworkiem GUI wtedy zazwyczaj ma on jakąś funkcję do uruchamiania kodu z opóźniemie bez blokowania reszty kodu.

PyQt ma specjalną klasę QTimer aby uruchamiać funkcję jednorazowo w opóźnieniem lub wielokrotnie w jednakowych odstępach czasu.

Jeśli funkcja jest mała i szybka to wtedy nie blokuje ona reszty kodu.

W tym przykładzie QTimer jest użyty do aktualizacji tekstu na QLabel co 1 sekundę (1000ms) i wyświetlania aktualnego czasu.

import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5 import QtWidgets
import datetime


def display_time():

    current_time = datetime.datetime.now().strftime('%Y.%m.%d - %H:%M:%S')
    label.setText(current_time)

    print('current_time:', current_time)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = QtWidgets.QMainWindow()

    # some GUI in window
    label = QtWidgets.QLabel(window, text='???', alignment=Qt.AlignCenter)
    window.setCentralWidget(label)
    window.show()

    # timer which repate function `display_time` every 1000ms (1s)
    timer = QTimer()
    timer.timeout.connect(display_time)  # execute `display_time`
    timer.setInterval(1000)  # 1000ms = 1s
    timer.start()

    sys.exit(app.exec())


EDIT:

Przykład, który próbuje wykorzystywać dwa timery. Normalnie by to działało ale tutuj jedna z funkcji wykonuje długotrwający kod i to blokuje resztę kodu. To by wymagało uruchomia kodu w osobnym wątku (wewnątrz QTimer)

import sys
from PyQt5.QtCore import Qt, QTimer
from PyQt5 import QtWidgets
import datetime
import time


def display_time():

    current_time = datetime.datetime.now().strftime('%Y.%m.%d - %H:%M:%S')
    label.setText(current_time)

    print('current_time:', current_time)


def long_job():
    for x in range(10):
        print('Job:', x)
        time.sleep(1)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = QtWidgets.QMainWindow()

    # some GUI in window
    label = QtWidgets.QLabel(window, text='???', alignment=Qt.AlignCenter)
    window.setCentralWidget(label)
    window.show()

    # timer which repate function `display_time` every 1000ms (1s)
    timer = QTimer()
    timer.timeout.connect(display_time)  # execute `display_time`
    timer.setInterval(1000)  # 1000ms = 1s
    timer.start()

    timer2 = QTimer()
    timer2.timeout.connect(long_job)  # execute `display_time`
    timer2.setInterval(1000)  # 1000ms = 1s
    timer2.start()

    sys.exit(app.exec())
If you like it
Buy a Coffee