带有线程循环的StatusIcon:循环不循环

时间:2013-12-20 10:01:41

标签: multithreading python-3.x while-loop trayicon

我创建了一个简单的状态图标。 其目的是检查给定时间间隔内文件的存在。

显示状态图标,并启动线程。 但是,循环不循环:它进入循环,但是在event.wait它停止,并且永远不会继续。

我尝试用time.sleep(5)替换,但结果相同。

我在任何地方搜索过,但我找不到答案。 我错过了什么?

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

from gi.repository import Gtk
import threading


class CheckStatus(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.event = threading.Event()

    def run(self):
        cnt = 0
        while not self.event.is_set():
            cnt += 1
            print((">>> check %d" % cnt)) # This shows just once
            self.event.wait(5)
        print(">>> done")

    def stop(self):
        self.event.set()


class MyStatusIcon(object):

    def __init__(self):
        self.statusIcon = Gtk.StatusIcon()
        self.statusIcon.set_from_stock(Gtk.STOCK_ABOUT)

        # Build status icon menu
        menu = Gtk.Menu()
        menuQuit = Gtk.MenuItem("Quit")
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)

        self.statusIcon.connect('popup-menu', self.popup_menu, menu)

        # Start thread
        self.check = CheckStatus()
        self.check.start()

    def popup_menu(self, widget, button, time, data):
        data.show_all()
        data.popup(None, None, None, None, button, time)

    def quit_tray(self, widget):
        # Stop the thread and quit
        self.check.stop()
        self.check.join()
        Gtk.main_quit()

if __name__ == '__main__':
    # Create an instance of our GTK application
    try:
        MyStatusIcon()
        Gtk.main()
    except:
        pass

[编辑1]

我用计数器循环替换了while循环(而cnt <10),虽然这没有改变行为,但是一旦我退出状态图标,它就会每5秒显示一次打印的计数器。

似乎线程正在等待状态图标中的事件。

[编辑2] 我需要从不同的角度看待这个问题,并想知道GObject.timeout_add是否可以解决这个问题......好吧,确实如此,但我不知道这是否是最优雅的方式。

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

from gi.repository import Gtk, GObject


class MyStatusIcon(object):

    def __init__(self):
        self.quit = False
        self.counter = 0
        self.service = GObject.timeout_add(5000, self.checkStatus)

        self.statusIcon = Gtk.StatusIcon()
        self.statusIcon.set_from_stock(Gtk.STOCK_ABOUT)

        # Build status icon menu
        menu = Gtk.Menu()
        menuQuit = Gtk.MenuItem("Quit")
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)

        self.statusIcon.connect('popup-menu', self.popup_menu, menu)

    def checkStatus(self):
        self.counter += 1
        if not self.quit:
            print((">>> check %d" % self.counter))
            return True
        print("Done")
        return False

    def popup_menu(self, widget, button, time, data):
        data.show_all()
        data.popup(None, None, None, None, button, time)

    def quit_tray(self, widget):
        # Stop the thread and quit
        self.quit = True
        Gtk.main_quit()

if __name__ == '__main__':
    # Create an instance of our GTK application
    try:
        MyStatusIcon()
        Gtk.main()
    except:
        pass

0 个答案:

没有答案