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”
- You have to give an input time duration, for which your timer will count.
- 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 (
- 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).
- 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:
- A Nice colorful appearance
- Excellent layout management
- Smooth working on both Windows and Linux
And the Design will look like this:
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!