Background Timer in PyQt Python Applicatiion
Question: I am Building an application in python using PyQt4. I want to add a background
timer to my application so that when the timer runs out, the text editor in my
application stops receiving input and freezes up. I have tried the following
method so far:

    
    
    def main():
        app = QtGui.QApplication(sys.argv)
        main = Main()
        main.show()  
        start = time.time()
        #this loop is for the time interval within which the text area of
        #the editor will accept inputs.   
        while time.time() - start < 120:
            pass
        #this will set the text area to a read only state after and will not
        #any more inputs.    
        main.text.setReadOnly(True)
        sys.exit(app.exec_())
    

But whenever I run this the application stops responding. I have also tried
running the timer through a thread but in that case also the application stops
responding.

How can I implement this functionality?

P.S. - I am a Beginner in PyQt.

    
    
    class Main(QtGui.QMainWindow):
        def __init__(self,parent = None):
            QtGui.QMainWindow.__init__(self,parent)
            self.init_ui()
    
        def init_ui(self):
            self.text = QtGui.QTextEdit(self)
            self.setCentralWidget(self.text)
            self.statusbar = self.statusBar()        
            self.setGeometry(100,100,1080,720)
            self.setWindowTitle("Text Editor")
    

This is the watered down version of the main class code. Hope this helps.


Answer: Your application is not responding because you are blocking the event handler.
It is processed by `app.exec_()`. This call is only checking for events and
handling these in a infinite loop.

Use QTimer with **signal** and **slot**.

[Signals and Slots
(wikipedia)](https://en.wikipedia.org/wiki/Signals_and_slots)

For using signals and slots in pyqt see
[this](http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html).

The timer is initialized with a duration and a signal-slot connection. After
`app.exec_()` is called, it will wait for the `input_timer` signal `timeout`.
If this is raised, the event loop will call lambda function, that disables the
textbox, because it is connected to the signal.

    
    
    def main():
        app = QtGui.QApplication(sys.argv)
        main = Main()
        main.show()  
    
        input_timer = QTimer(self)
        input_timer.timeout.connect(lambda : main.text.setReadOnly(True))
        input_timer.setSingleShot(True)
        input_timer.start(2000)
    
        sys.exit(app.exec_())
    

This will disable the textbox after 2000 milliseconds. Adjust as you need. I
would move the timer and behaviour to `Main` class.

    
    
    import sys
    from PyQt4 import QtCore, QtGui
    
    class Main(QtGui.QMainWindow):
        def __init__(self,parent = None):
            QtGui.QMainWindow.__init__(self,parent)
            self.init_ui()
    
            self.disable_edit_text_timer = QtCore.QTimer(self)
            self.disable_edit_text_timer.timeout.connect(self.disable_edit_text)
            self.disable_edit_text_timer.setSingleShot(True)
            self.disable_edit_text_timer.start(2000)
    
        def init_ui(self):
            self.text = QtGui.QTextEdit(self)
            self.setCentralWidget(self.text)
            self.statusbar = self.statusBar()        
            self.setGeometry(100,100,1080,720)
            self.setWindowTitle("Text Editor")
    
        def disable_edit_text(self):
            self.text.setReadOnly(True)
    
    def main():
        app = QtGui.QApplication(sys.argv)
        main = Main()
        main.show()  
    
        sys.exit(app.exec_())
    
    if __name__ == "__main__":
        main()
    

