В PyGTK, как запустить поток и продолжить вызов функции только после завершения потока - PullRequest
0 голосов
/ 12 апреля 2020

Прочитав много вопросов о потоках и функции .join(), я все еще не могу найти, как адаптировать пример потоков basi c pygobject из документации , чтобы он соответствовал моему сценарию использования:

#!/bin/python3

import threading
import time
from gi.repository import GLib, Gtk, GObject

def app_main():
    win = Gtk.Window(default_height=50, default_width=300)
    win.connect("destroy", Gtk.main_quit)

    def update_progess(i):
        progress.pulse()
        progress.set_text(str(i))
        return False

    def example_target():
        for i in range(50):
            GLib.idle_add(update_progess, i)
            time.sleep(0.2)

    def start_actions(self):
        print("do a few thing before thread starts")
        thread = threading.Thread(target=example_target)
        thread.daemon = True
        thread.start()
        print("do other things after thread finished")

    mainBox = Gtk.Box(spacing=20, orientation="vertical")
    win.add(mainBox)
    btn = Gtk.Button(label="start actions")
    btn.connect("clicked", start_actions)
    mainBox.pack_start(btn, False, False, 0)
    progress = Gtk.ProgressBar(show_text=True)
    mainBox.pack_start(progress, False, False, 0)
    win.show_all()


if __name__ == "__main__":
    app_main()
    Gtk.main()

Как заставить этот код печатать "do other things after thread finished" только после того, как моя нить прервется и без замораживания главного окна?

1 Ответ

0 голосов
/ 12 апреля 2020

Во-первых, просто чтобы прояснить, поток не завершен после вызова его start метода.

Посмотрите на определение кода, выполняющегося в потоке:

def example_target():
    for i in range(50):
        GLib.idle_add(update_progess, i)
        time.sleep(0.2)

В основном это повторяет следующие 50 раз:

  • говорит GTK выполнить update_progress в следующий раз, когда система не используется (нет событий для обработки).
  • спит в течение 0,2 секунд.

Вы можете определить функцию after_thread и запланировать ее на конец потока:

def example_target():
    for i in range(50):
        GLib.idle_add(update_progess, i)
        time.sleep(0.2)
    # loop is finished, thread will end.
    GLib.idle_add(after_thread)
...