Marek Möhling
Marek Möhling

Reputation: 152

Python GTK: label.set_text() doesn't work as expected

[Update: I answered and explained this better below]

Test case -- this creates a button and a label. After clicking on the button I expect the label text to be changed to "11" immediately and to "22" two seconds later. However, while print(self.msg.get_text()) prints the expected result right away, the label doesn't get updated till after the timeout.

#!/usr/bin/python
import gi, time
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

class MyWindow(Gtk.Window):
  def __init__(self):
    Gtk.Window.__init__(self, title="test")

    self.grid = Gtk.Grid()
    self.add(self.grid)
    self.grid.set_border_width(10)

    self.button = Gtk.Button.new_with_label("change label")
    self.button.connect("clicked", self.change_label)
    self.grid.attach(self.button, 0, 0, 1, 1)

    self.label = Gtk.Label(label = '00')
    self.grid.attach(self.label, 0, 1, 1, 1)

  def change_label(self, button):
    self.label.set_text('11')
    print(self.label.get_text())

    time.sleep(2)

    self.label.set_text('22')

win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

Upvotes: 0

Views: 693

Answers (2)

Marek Möhling
Marek Möhling

Reputation: 152

I didn't explain myself well--sleep() stands for a call to a server that is needed in the script I'm working on. Using Niels' suggestion this helped, I changed the example to make it clearer:

#!/usr/bin/python
import gi, time
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
from gi.repository import GLib

class MyWindow(Gtk.Window):
  def __init__(self):
    Gtk.Window.__init__(self, title="test")

    self.grid = Gtk.Grid()
    self.add(self.grid)
    self.set_border_width(15)
    self.set_default_size(300, 100)

    self.button = Gtk.Button.new_with_label("connect to server")
    self.button.connect("clicked", self.change_label)
    self.grid.attach(self.button, 0, 0, 1, 1)

    self.label = Gtk.Label(label = '')
    self.grid.attach(self.label, 0, 1, 1, 1)

  def connect_to_server(self):
    time.sleep(2) # placeholder for a server call waiting for response
    self.label.set_text('Success, server stuff done!')
    return False

  def change_label(self, button):
    self.label.set_text('Please wait...')
    GLib.timeout_add(20, self.connect_to_server) # unreliable with 10 or less

win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

Upvotes: 0

nielsdg
nielsdg

Reputation: 2743

By running time.sleep(), you're blocking the main thread, in which the UI is also running. Since it's blocked, the UI can't do the necessary work to actually render the changes you made to your label.

To change your label in a non-blocking way, you can use API such as GLib.timeout_add_seconds().

Upvotes: 1

Related Questions