Python Forum
Threading timer crashes my App
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Threading timer crashes my App
#1
I want to make an app that will use timer.
A button will set the timer at my pc 's time plus one minute.
The problem is that it crashes.
Run the following code and press button 'set alarm'.
Then try to close the form clicking the close button ('x') of the form.
It freezes.

I guess I'm not using correctly the threading?

Any good working solution?

import sys
from PyQt4 import QtGui
import os
import threading
import datetime
import pygame

class MyApp(QtGui.QWidget):
   def __init__(self):
       QtGui.QMainWindow.__init__(self)
       pygame.init()
       pygame.mixer.init()
       now = datetime.datetime.now()
       hour = now.hour; minute = now.minute; second = now.second

       # add pusbutton
       self.set_alarm_btn = QtGui.QPushButton('set_alarm_btn', self)
       self.set_alarm_btn.clicked.connect(self._set_alarm_btn_clicked)

       layout = QtGui.QVBoxLayout(self)
       layout.addWidget(self.set_alarm_btn)

   def _set_alarm_btn_clicked(self):
       now = datetime.datetime.now()
       hour = now.hour;
       minute = now.minute;
       second = now.second
       self.clock = Clock()
       self.clock.set_alarm(hour, minute + 1, self)
       self.clock.run()

   def _response_to_alert(args):
       print("Alert")

   def ring_ring(self):
       sys.stdout.write('ring ring\n')
       sys.stdout.flush()
       if  hasattr(self, 'clock'):
           self.clock._alarm_thread.cancel()

class Clock:

   def __init__(self):
       self.alarm_time = None
       self._alarm_thread = None
       self.update_interval = 1
       self.event = threading.Event()

   def run(self):
       while True:
           self.event.wait(self.update_interval)
           if self.event.isSet():
               break
           now = datetime.datetime.now()
           if self._alarm_thread and self._alarm_thread.is_alive():
               alarm_symbol = '+'
           else:
               alarm_symbol = ' '
           sys.stdout.write("\r%02d:%02d:%02d %s"
               % (now.hour, now.minute, now.second, alarm_symbol))
           sys.stdout.flush()

   def set_alarm(self, hour, minute, parent):
       now = datetime.datetime.now()
       alarm = now.replace(hour=int(hour), minute=int(minute))
       delta = int((alarm - now).total_seconds())
       if delta <= 0:
           alarm = alarm.replace(day=alarm.day + 1)
           delta = int((alarm - now).total_seconds())
       if self._alarm_thread:
           self._alarm_thread.cancel()
       self._alarm_thread = threading.Timer(delta, parent.ring_ring)
       self._alarm_thread.daemon = True
       self._alarm_thread.start()


if __name__ == '__main__':
   app = QtGui.QApplication(sys.argv)
   window = MyApp()
   window.show()
   sys.exit(app.exec_())
Reply
#2
A windowed application has an "event loop". Conceptually it polls a queue of events (mouse and keyboard, mostly), processes the event, and then polls for the next event. A good deal of the events is processed by the UI support (the Qt library, in your case), but some are forwarded to your app (_set_alarm_btn_clicked). If your code doesn't return quickly, the event loop gets stuck, doesn't poll further events, so you application no longer reacts to events and your UI freezes.

So you have to wonder what happens when you call  clock.run()....

In practice, any code that takes a significant amount of time (>.1 second) should be delegated to a thread. That thread then communicates with the event loop thread by sending it events. Not a PyQt expert, but this looks like the answer.

PS: future-proofing: have you checked that you can use pygame and pyqt4 in the same application without getting conflicts?
Unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
Your one-stop place for all your GIMP needs: gimp-forum.net
Reply
#3
(Jun-04-2017, 12:17 PM)Ofnuts Wrote: PS: future-proofing: have you checked that you can use pygame and pyqt4 in the same application without getting conflicts?
First of all...Your asking for trouble when you mix two GUI libraries. Im not sure specifically about pyqt4 mixed with pygame though. Like I know that pygame and tkinter dont work well together.
Second of all why are you using two libraries? Your using pygame's mixer but pyqt4 GUI for the button. Why not just use pygame for both?
Recommended Tutorials:
Reply
#4
I started using PyQt4 only, without pygame.
Then I added pygame because I wanted to play some mp3 files and looked very easy with pygame.
I didn't know that there might be some conflict between them.
Reply
#5
(Jun-03-2017, 08:30 AM)panoss Wrote:        pygame.init()
       pygame.mixer.init()
You don't use all of pygame, so don't init all of pygame. That'll init the graphics devices, which you specifically don't want to do since you're using Qt. pygame's made pretty modular, so as long as you only init the mixer, you should be able to use just the mixer without issues.

(Jun-03-2017, 08:30 AM)panoss Wrote:    def run(self):
       while True:
           self.event.wait(self.update_interval)
           if self.event.isSet():
               break
Could the reason that it freezes be that you're waiting for the event to be .isSet(), but you never actually set() the event? So it just keeps looping forever.
It's interesting that you're using threading.Event, but you're never actually starting a new thread, except for the alarm_thread, which doesn't seem to serve any purpose other than to eventually get cancelled (ie: it's basically just a True/False that's unnecessarily complicated).
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Concurrent futures threading running at same speed as non-threading billykid999 13 1,636 May-03-2023, 08:22 AM
Last Post: billykid999
  Understanding and debugging memory error crashes with python3.10.10 Arkaik 5 1,795 Apr-18-2023, 03:22 AM
Last Post: Larz60+
  using threading.Timer for function korenron 1 1,113 Dec-20-2022, 01:09 PM
Last Post: ndc85430
  Pydroid3 app crashes on xiaomi poco F3 JMD 2 1,064 Nov-27-2022, 11:56 AM
Last Post: JMD
  HTML file crashes program mikefirth 12 3,579 Dec-31-2021, 03:57 AM
Last Post: Pedroski55
  Tutorials on sockets, threading and multi-threading? muzikman 2 2,031 Oct-01-2021, 08:32 PM
Last Post: muzikman
  Scraping a Flexible Element - works at first, and then crashes JonnyB 0 1,453 Aug-14-2021, 07:25 PM
Last Post: JonnyB
  email timer/rss feed timer ndiniz 1 2,007 Feb-02-2021, 07:18 PM
Last Post: nilamo
  Bug that crashes the Python interpreter 3.7 on Mac OS X Stef 1 3,599 Feb-18-2019, 06:30 PM
Last Post: micseydel
  code keeps running if i use from threading import timer? birddseedd 3 2,519 Jan-25-2019, 05:00 AM
Last Post: stullis

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020