Python clock does not update

Asked

Viewed 698 times

3

I am trying to create a clock in Pygtk. But it seems that there was some semantic error here:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import pygtk
pygtk.require('2.0')
import gtk
from datetime import *

def relogio():
    janela = gtk.Window()
    janela.set_title("Relógio digital")

    label = gtk.Label()
    janela.add(label)

    janela.connect("destroy", gtk.main_quit)
    janela.show_all()

    while 1:
        label.set_markup("<big>" + str(datetime.now().hour) + ":" + str(datetime.now().minute) + ":" + str(datetime.now().second) + "</big>")
if __name__ == '__main__':
    relogio()
    gtk.mainloop()

Could you help me fix it? Notice that when you run the code with the interpreter, the window just doesn’t appear!

  • 4

    It would be the case to change the clock update to another function called by a timer. As it is, the infinite loop does not allow the return of the clock() function, never reaching the gtk.mainloop(), which would anyway disturb the refresh of the screen even if it appeared. Also, with an infinite loop of these without any gap or anything, your watch will be a beautiful CPU consumer...

  • Right... what do I do to fix, then?

  • Good morning, always use titles referring to the problem, "What’s wrong", "Help", "Help", "Please" do not define anything and do not help at all to understand the problem, are redundant, since when someone posts a doubt here is that probably the code is not even working as expected. Take this comment as a constructive criticism.

2 answers

2


I imagine this code is blocking everything in an endless loop and no loophole for anything else to run:

while 1:
    label.set_markup("<big>" + str(datetime.now().hour) + ":" + str(datetime.now().minute) + ":" + str(datetime.now().second) + "</big>")

I would move this second line to another method and use it to create a timer to call it repeatedly. I also converted to a class to be more encapsulated:

import pygtk
pygtk.require('2.0')
import gtk
from datetime import *

class Relogio():
    def __init__(self):
        janela = gtk.Window()
        janela.set_title("Relógio digital")

        self.label = gtk.Label()
        janela.add(self.label)

        janela.connect("destroy", gtk.main_quit)
        janela.show_all()
        gtk.timeout_add(1000, self.atualiza)

    def atualiza(self):
        self.label.set_markup(datetime.now().strftime('<big>%H:%M:%S</big>'))
        return True

if __name__ == '__main__':
    relogio = Relogio()
    gtk.mainloop()
  • 1

    Seria __initi__ or __init__?

  • I fixed it. I changed the question code without testing ;)

  • Look, guys... the code updates only once:

  • Good morning @Gabriel I didn’t get your comment here in Sergiopereira’s reply, you mean his answer doesn’t work? Explain better.

  • Sorry. I had no time to test during the week and forgot the return True at the end of atualiza. I just fixed.

1

You have to give a chance to the GTK redesign the updates on label and also create a thread to get the current time.

Look at your code:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

import threading
import logging
import pygtk
pygtk.require('2.0')
import gtk
from datetime import *

class Relogio():
    def __init__(self):
        janela = gtk.Window()
        janela.set_title("Relógio digital")

        self.label = gtk.Label()
        janela.add(self.label)

        janela.connect("destroy", gtk.main_quit)
        janela.show_all()
        gtk.timeout_add(1, self.atualiza) #Mude o timeout para 1

    def atualiza(self):            
        while gtk.events_pending(): #Verifica os eventos pedentes.
            gtk.main_iteration() #Aqui esta fazendo as interações.
            self.label.set_text(datetime.now().strftime('%H:%M:%S')) #Defini para a metodo set_text.        

if __name__ == '__main__':                
    logging.basicConfig(level=logging.DEBUG, format='[%(levelname)s] (%(threadName)-10s) %(message)s',)
    relogio = Relogio()
    t1 = threading.Thread(name='Hora', target=relogio.atualiza())
    t1.start()
    gtk.main()

Sources: Thread working. Getting interactions to update the label.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.