在Python中访问非全局变量

时间:2012-01-26 09:19:21

标签: python multithreading gtk

我正在尝试从下面的MailThread.run()中指定的线程更改Gtk状态图标的状态,但我不知道如何从方法中访问状态图标对象以更改set_visible无论是对还是对。

基本上我想知道要写什么代替“#set status icon visible off / on”。

#!/usr/bin/env python

import gtk, sys, pynotify, imaplib, time, threading
from email import parser

class Mail:

    def check_mail(self):
        obj = imaplib.IMAP4_SSL('imap.gmail.com','993')
        acc = 'email'
        pwrd = 'pass'
        obj.login(acc, pwrd)
        obj.select()
        num = str(len(obj.search(None,'UnSeen')[1][0].split()))
        return acc, num

class MailThread(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        gtk.gdk.threads_init()

    def run(self):
        while True:
            print "hello"
            mail = Mail()
            num = mail.check_mail()[1]
            if num < 1:
                # set status icon visible off
            else:
                # set status icon visible on
            time.sleep(60)

class StatusIcon:

    # activate callback
    def activate( self, widget, data=None):
        mail = Mail()
        acc, num = mail.check_mail()
        pynotify.init("myapp")
        n = pynotify.Notification(acc, "You have " + num + " unread e-mails.", "emblem-mail")
        n.show()

   # Show_Hide callback
    def  show_hide(self, widget,response_id, data= None):
        if response_id == gtk.RESPONSE_YES:
            widget.hide()
        else:
            widget.hide()

    # destroyer callback
    def  destroyer(self, widget,response_id, data= None):
        if response_id == gtk.RESPONSE_OK:
            gtk.main_quit()
        else:
            widget.hide()

    # popup callback
    def popup(self, button, widget, data=None):
        dialog = gtk.MessageDialog(
        parent         = None,
        flags          = gtk.DIALOG_DESTROY_WITH_PARENT,
        type           = gtk.MESSAGE_INFO,
        buttons        = gtk.BUTTONS_OK_CANCEL,
        message_format = "Do you want to close e-mail notifications?")
        dialog.set_title('Exit')
        dialog.connect('response', self.destroyer)
        dialog.show()

    def __init__(self):
        # create a new Status Icon
        self.staticon = gtk.StatusIcon()
        self.staticon.set_from_icon_name("emblem-mail")
        self.staticon.connect("activate", self.activate)
        self.staticon.connect("popup_menu", self.popup)
        self.staticon.set_visible(True)
        # starting thread
        thread = MailThread()
        thread.setDaemon(True)
        thread.start()
        # invoking the main()
        gtk.main()        

if __name__ == "__main__":

    # status icon
    statusicon = StatusIcon()

1 个答案:

答案 0 :(得分:4)

您可以接受主题__init__()中的状态图标:

class MailThread(threading.Thread):
    def __init__(self, status_icon = None):
        threading.Thread.__init__(self)
        gtk.gdk.threads_init()
        self.status_icon = status_icon

然后您可以在run()中使用它。

此外,您需要从主线程完成所有GUI工作。主线程有一个由GTK维护的队列,你可以用来告诉它做一些GUI工作。这是它的工作原理:

def run(self):
    # <...>
    if num < 1:
        gobject.idle_add(self.set_status_icon, False)
    else:
        gobject.idle_add(self.set_status_icon, True)
    # <...>

def set_status_icon(self, state = False):
    # code that changes icon state goes here
    pass

idle_add基本上意味着“将其添加到队列中并在有空闲时间时执行此操作”。