Как изменить курсор на песочные часы в приложении Python GTK3

У меня есть функция, выполнение которой занимает достаточно много времени, и я пытаюсь изменить курсор на песочные часы во время выполнения функции. Но это работает только при первом вызове функции. Я делаю это (это в обработчике события on_click кнопки):

from gi.repository import Gtk, Gdk, GObject
import time

def on_grabbtn_clicked(self, button):
    # Change the cursor to hour Glass
    cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH)
    self.window.get_root_window().set_cursor(cursor)

    # lenghty process here
    time.sleep(10)

     # Set the cursor to normal Arrow
    cursor = Gdk.Cursor.new(Gdk.CursorType.ARROW)
    self.window.get_root_window().set_cursor(cursor)

окно - это сборка окна с Glade / GtkBuilder и named ... window. Я получаю указатель на него в __init__() класса окна следующим образом:

self.window = self.builder.get_object('window')

Как я уже говорил, песочные часы появляются только при первом нажатии на кнопку. Во второй раз это больше не работает. Так что я делаю это неправильно. Но что я делаю не так?

4
задан 17 May 2012 в 14:52

1 ответ

Вот рабочий пример того, что вы хотите.

Вам нужно понять концепцию того, что делает основной цикл GTK, чтобы понять, почему важно отделить код манипуляции GUI от длинного кода блокировки. Надеемся, что комментарии и отладочные утверждения в моем примере помогут вам понять. Эта статья часто задаваемых вопросов PyGTK полезна, и эта концепция применима также к Python с самоанализом GTK3 и GObject.

Пример кода:

Этот код создает окно с простой кнопкой с надписью «Нажми меня». Как только вы щелкнете по нему, он изменится на «Работающий», курсор станет песочными часами, а графический интерфейс останется отзывчивым. По истечении десяти секунд метка кнопки изменится на «Готово», а курсор вернется в нормальное состояние.

import time
import threading

from gi.repository import Gtk, Gdk, GObject

window = None

def main():
    GObject.threads_init()
    Gdk.threads_init()

    # Build GUI:
    global window
    window = Gtk.Window()
    button = Gtk.Button(label="Click me")
    window.add(button)
    window.set_default_size(200, 200)
    window.show_all()

    # Connect signals:
    window.connect("delete-event", Gtk.main_quit)
    button.connect("clicked", on_button_click)

    Gtk.main()

def on_button_click(button):
    print "Debug on_button_click: current_thread name:", threading.current_thread().name

    # This is a callback called by the main loop, so it's safe to
    # manipulate GTK objects:
    watch_cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
    window.get_window().set_cursor(watch_cursor)
    button.set_label("Working...")
    button.set_sensitive(False)

    def lengthy_process():
        print "Debug lengthy_process: current_thread name:", threading.current_thread().name
        # We're in a new thread, so we can run lengthy processes without
        # freezing the GUI, but we can't manipulate GTK objects except
        # through GObject.idle_add
        time.sleep(10)
        def done():
            print "Debug done: current_thread name:", threading.current_thread().name
            window.get_window().set_cursor(None)
            button.set_label("Done!")
            return False
        GObject.idle_add(done)

    thread = threading.Thread(target=lengthy_process)
    thread.start()

if __name__ == "__main__":
    main()
0
ответ дан 17 May 2012 в 14:52

Другие вопросы по тегам:

Похожие вопросы: