2015-09-20 74 views
1

我在寫一個從網頁獲取信息並在Gnome Shell的Notification中顯示的Python程序。我使用的是Arch,所以我想在啓動時啓動此程序,如果網頁上有任何更改,它會通知我。這裏是我的代碼:在Gnome Shell中使用通知的Python程序不起作用

import time 
import webbrowser 
import requests 
from bs4 import BeautifulSoup 
from gi.repository import Notify, GLib 


IPS = {'Mobifone': True, 'Viettel': False, 'Vinaphone': False} 
LINK = "https://id.vtc.vn/tin-tuc/chuyen-muc-49/tin-khuyen-mai.html" 


def set_ips_state(ips_name, state): 
    global IPS 
    for key in IPS.iterkeys(): 
     if key == ips_name: 
      IPS[key] = state 


def call_webbrowser(notification, action_name, link): 
    webbrowser.get('firefox').open_new_tab(link) 


def create_notify(summary, body, link): 
    Notify.init("Offer") 
    noti = Notify.Notification.new(summary, body, 'dialog-information') 
    noti.add_action('action_click', 'Read more...', call_webbrowser, link) 
    noti.show() 
    # GLib.MainLoop().run() 


def save_to_file(path_to_file, string): 
    file = open(path_to_file, 'w') 
    file.write(string) 
    file.close() 


def main(): 
    global IPS 
    global LINK 

    result = [] 

    offer_news = open('offer_news.txt') 
    tag_in_file = BeautifulSoup(offer_news.readline(), 'html.parser') 
    tag = tag_in_file.a 
    offer_news.close() 

    page = requests.get(LINK) 
    soup = BeautifulSoup(page.text, 'html.parser') 
    for div in soup.find_all('div', 'tt_dong1'): 
     # first_a = div.a 
     # main_content = first_a.find_next_subling('a') 
     main_content = div.find_all('a')[1] 
     for k, v in IPS.iteritems(): 
      if v: 
       if main_content.text.find(k) != -1: 
        result.append(main_content) 
    print result[1].encode('utf-8') 
    if tag_in_file == '': 
     pass 
    else: 
     try: 
      old_news_index = result.index(tag) 
      print old_news_index 
      for idx in range(old_news_index): 
       create_notify('Offer News', result[idx].text.encode('utf-8'), result[idx].get('href')) 
      print "I'm here" 
     except ValueError: 
      pass 
    offer_news = open('offer_news.txt', 'w') 
    offer_news.write(result[0].__str__()) 
    offer_news.close() 


if __name__ == '__main__': 
    while 1: 
     main() 
     time.sleep(10) 

問題是,當我點擊「更多信息」的通知按鈕,它不打開Firefox的,除非我在create_notify功能取消註釋GLib.MainLoop().run(),但是這使得程序凍結。任何人都可以幫忙嗎?

回答

2

GUI應用程序通常使用三個主要組件:小部件,事件循環和回調。當您啓動該應用程序時,您將創建小部件,註冊回調並啓動事件循環。事件循環是無限循環,它從小部件(例如'clicked button')查找事件並觸發相應的回調。

現在,在你的應用程序中你有另一個無限循環,所以這兩個不會一起玩。相反,你應該利用GLib.MainLoop().run()來觸發事件。您可以使用GLib.timeout_add_seconds來觸發週期性事件,例如每10秒鐘發生一次。

第二個問題是您需要保持對應該調用回調的通知的引用。當您在noti.show()之後添加GLib.MainLoop().run()時,noti的引用仍然存在,但是如果您按照前面的建議進行更改,則無效。如果您確定始終只有一個通知處於活動狀態,則可以保留對最後通知的引用。否則,您需要一個列表並定期清除它,或者沿着這條線清理它。

下面的例子應該設置你在正確的方向:

from gi.repository import GLib, Notify 


class App(): 
    def __init__(self): 
     self.last_notification = None 
     Notify.init('Test') 
     self.check() 

    def check(self): 
     self.last_notification = Notify.Notification.new('Test') 
     self.last_notification.add_action('clicked', 'Action', 
              self.notification_callback, None) 
     self.last_notification.show() 
     GLib.timeout_add_seconds(10, self.check) 

    def notification_callback(self, notification, action_name, data): 
     print(action_name) 


app = App() 
GLib.MainLoop().run() 
相關問題