Create a Timer using PyQt5 and Playing alarm sound in Python

In this post, I will be teaching you an application in Python that can be used as a “TIMER” for setting alarms for under 1 hour or so. And by doing this small project, you are not only creating your personal platform-independent “Timer” but also you can learn how to play sounds using Python. I have also used the concept of threading in PyQt5, which is a “must learn thing” for intermediate Python developers and also helps to run any of your applications seamlessly!

The Python version and the modules I have used:

‘3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)]’

Overview of the Logic of the Code

I try to write codes that are short and easy to understand. First, let’s understand how to think before you create this “Timer”

  1. You have to give an input time duration, for which your timer will count.
  2. You have to add seconds to 0 hr, 0 min and 0 seconds to reach the time you have set in the previous step. For example (5 mins)
  3. As I have promised that I will demonstrate the playing of a sound file using Python! I’ll surely fulfill that. As the countdown completes, trigger the playing of the sound (I’ll be using pydub for this action).
  4. And also you have to remember that, sometimes alarm clocks that are not stopping become irritating, but I will not let you get irritated on the “Timer”. I’ll also implement code to stop the trrrrring! sound on your will.

Moving on to the design part

As always, I will prefer to use Qt Designer for the designing purpose. And the catch of the application will be it’s:

  1. A Nice colorful appearance
  2. Excellent layout management
  3. Smooth working on both Windows and Linux

And the Design will look like this:

Timer PyQT
It has 5 Qlabel widgets.
4 Horizontal spacers and 2 vertical spacers
1 spin box
1 push button

Now to look exactly like my application you have to make some changes. You have to select the spinbox widget, then change buttonSymbols to NoButtons from the property editor in Qt designer. Select “set timer” and “From Now” labels one by one and change their vertical alignment to AlignTop and select the label placed in the middle of the screen then edit the style sheet from the property editor. Then add a gradient , select your gradient and press “ok” to confirm.

Now select the spin box and minutes label and right-click to set layout and layout vertically. Then select, the Set Timer label the vertical layout widget and the “From Now” label and right-click to set layout Horizontally.
Now select the Topmost Horizontal Layout, middle label(one that is red-colored), “Time Spent” label, and the push button and again right-click to set layout vertically.

Now setting layout is one of the most important parts, as when you scale your window the inner widgets get automatically aligned.

save as timer.ui and then convert the .ui file from Qt Designer’s XML file to Python code using
pyuic5 timer.ui -o timer.py

Now create another Python file in the same directory and save it as call_timer.py and edit this file to implement your timer logic!

I have written this code that works fine, you can just relate to it:

import sys
from my_timer import *
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import QtCore
from pydub import AudioSegment
from pydub.playback import play
from PyQt5.QtCore import pyqtSignal, QThread


class CloneThread(QThread):
    signal = pyqtSignal('PyQt_PyObject')

    def __init__(self):
        QThread.__init__(self)

    def run(self):
        music = AudioSegment.from_mp3(
            "C:\\Users\\tuhin Mitra\\Desktop\\All Python Resources\\gui_project\\alarm.mp3")  # path to the audio file that will play after time is over
        play(music)
        self.signal.emit('')  # signal for main thread to understand this thread working has finished!


class Mytimer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.thread1 = CloneThread()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.timer = QtCore.QTimer()
        self.curr_time = QtCore.QTime(0, 0, 0) # initialize to 0
        self.Reach_timer = self.curr_time
        self.thread1.signal.connect(self.thread1.terminate)
        self.time = QtCore.QTime(self.curr_time)
        self.timer.timeout.connect(self.TimerEvent) 
        self.ui.pushButton.clicked.connect(self.terminal)  # action for push button click

    def TimerEvent(self):
        self.time = self.time.addSecs(1)  # add seconds to running time
        if self.time.toString() == self.Reach_timer.toString():  # check if destination is reached
            print('Time Reached')
            self.timer.stop()
            self.thread1.start()
            self.thread1.start()
        self.ui.label.setText(self.time.toString("hh:mm:ss"))  # to display the count

    def terminal(self):
        button_text = self.ui.pushButton.text()
        if button_text == 'START':
            # self.ui.pushButton.setDisabled(True)
            minutes = int(self.ui.spinBox.text())  # get text from spin box
            self.set_timer = minutes * 60  # converted into seconds
            self.Reach_timer = self.curr_time.addSecs(minutes * 60)  # set the destination
            self.ui.pushButton.setText('STOP')  # set button text for stop
            self.timer.start(1000)  # start timer, after every 1000 ms it will call TimerEvent to increase the counting
        else:
            self.thread1.terminate()  # this will terminate the playing of the audio file
            self.curr_time = QtCore.QTime(0, 0, 0)
            self.time = self.curr_time  # re-initialize to 0
            self.ui.pushButton.setText('START')  # show push button text as "start"
            self.timer.stop()  # when stop is pressed, stop the timer


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Mytimer()
    w.show()
    sys.exit(app.exec_())

And I have imported the my_timer file, this is simply the python code generated from the UI file.
You can see my_timer.py: my_timer.py (Just unzip this file)

and the call_my_timer.py file (Unzip this file)

And you have to place the alarm.mp3 file in the same directory to play the alarm sound at the end of the countdown!

Leave a Reply

Your email address will not be published.