Обновление GTK + MenuItem Countdown каждую секунду и вызов периодической функции

Это мой показатель Международной космической станции. Я пытаюсь создать GTK MenuItem, который отображает обратный отсчет. Это будет индикатор Ubuntu Unity с помощью AppIndicator3. Я хочу, чтобы этот MenuItem ( futpass ) futpass каждую секунду (т. futpass Обратный отсчет показывался в реальном времени), но также нужно, чтобы он оставался неактивным, когда меню не выбрано, чтобы не потреблять системные ресурсы. Проблема в том, что я не могу ее обновить самостоятельно.

Поскольку между каждым checkiss требуется длительный период ожидания, мне также нужно знать правильный подход к вызову этой функции в заданное время с минимальными пробуждениями процессора.

Вот мой (грубый) код:

 #!/usr/bin/env python #print time.localtime( time.time() ) import json, urllib2, time, math #indicator from gi.repository import Gtk from gi.repository import AppIndicator3 as appindicator class indicator(): def __init__(self): #create indicator self.ind = appindicator.Indicator.new ( "issindicator", "indicator-messages", #"indicator-messages", appindicator.IndicatorCategory.APPLICATION_STATUS) self.ind.set_status (appindicator.IndicatorStatus.ACTIVE) self.ind.set_attention_icon ("indicator-messages-new") #dropdown menu #now items self.menu = Gtk.Menu() self.curpass = Gtk.MenuItem("not refreshed") self.curpass.connect("activate", self.checkiss) self.menu.append(self.curpass) self.curpassdur = Gtk.MenuItem(" ") self.menu.append(self.curpassdur) self.curpassrise = Gtk.MenuItem(" ") self.menu.append(self.curpassrise) self.curpassset = Gtk.MenuItem(" ") self.menu.append(self.curpassset) self.sep1 = Gtk.SeparatorMenuItem() self.menu.append(self.sep1) #future items self.futpass = Gtk.MenuItem(" ") self.menu.append(self.futpass) self.sep2 = Gtk.SeparatorMenuItem() self.menu.append(self.sep2) #Options self.aboutmenu = Gtk.MenuItem("About") self.aboutmenu.connect("activate", self.onabout) self.menu.append(self.aboutmenu) self.quit = Gtk.MenuItem("Quit") self.quit.connect("activate", self.quitnow) self.menu.append(self.quit) self.curpass.show() self.sep1.show() self.futpass.show() self.sep2.show() self.aboutmenu.show() self.quit.show() self.ind.set_menu(self.menu) #get iss data self.updatecache() self.checkiss() Gtk.main() #define code to hide or show icon def hideicon(self, w=None): self.ind.set_status (appindicator.IndicatorStatus.PASSIVE) def showicon(self, w=None): self.ind.set_status (appindicator.IndicatorStatus.ACTIVE) def quitnow(self, w=None): Gtk.main_quit() def onabout(self,widget): widget.set_sensitive(False) ad=Gtk.AboutDialog() ad.set_name("aboutdialog") ad.set_version("0.1") ad.set_copyright('Copyrignt (c) 2013 mh00h') ad.set_comments('Indicating ISS Zarya') ad.set_license(''+ 'This program is free software: you can redistribute it and/or modify it\n'+ 'under the terms of the GNU General Public License as published by the\n'+ 'Free Software Foundation, either version 3 of the License, or (at your option)\n'+ 'any later version.\n\n'+ 'This program is distributed in the hope that it will be useful, but\n'+ 'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n'+ 'or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n'+ 'more details.\n\n'+ 'You should have received a copy of the GNU General Public License along with\n'+ 'this program. If not, see <http://www.gnu.org/licenses/>.') ad.set_website('https://launchpad.net/~mh00h/+archive/issindicator') ad.set_website_label('ISSIndicator Homepage') ad.set_authors(['mh00h']) ad.run() ad.destroy() widget.set_sensitive(True) def updatecache(self, w=None): self.passingstatus = 'not set yet' #get ISS data from api self.ip = urllib2.urlopen("http://api.exip.org/?call=ip").read() self.geoip = json.load(urllib2.urlopen("http://freegeoip.net/json/"+self.ip)) self.data = json.load(urllib2.urlopen("http://api.open-notify.org/iss/?lat="+str(self.geoip["latitude"])+"&lon="+str(self.geoip["longitude"])+"&alt=280&n=27")) def checkiss(self, w=None): self.n = 0 self.passingstatus = "The ISS is not overhead." #check if cache is out of date and update if needed if time.time() > self.data['response'][len(self.data['response'])-1]['risetime']: self.updatecache for k in self.data['response']: duration = self.data['response'][self.n]['duration'] risetime = self.data['response'][self.n]['risetime'] settime = risetime + duration #print risetime, time.time(), settime if risetime <= time.time() <= settime: self.showicon() self.passingstatus = "The ISS is overhead" self.curpass.get_child().set_text(self.passingstatus) self.curpassdur.get_child().set_text("Duration: "+ str(time.strftime('%M:%S', time.gmtime(duration)))+" ("+ str(time.strftime('%M:%S', time.gmtime(time.time()-duration)))+" remaining)") self.curpassdur.show() self.curpassrise.get_child().set_text("Rise time: "+time.strftime('%H:%M:%S', time.gmtime(risetime))) self.curpassrise.show() self.curpassset.get_child().set_text("Set time: "+time.strftime('%H:%M:%S', time.gmtime(settime))) self.curpassset.show() break else: self.n += 1 if self.passingstatus != "The ISS is overhead": self.curpass.get_child().set_text(self.passingstatus) self.curpassdur.hide() self.curpassrise.hide() self.curpassset.hide() #self.hideicon() #regardless of isspass, show the next pass time if self.n != len(self.data['response']): self.futpass.get_child().set_text("Next Pass: "+str(time.strftime('%H:%M:%S', time.gmtime(self.data['response'][self.n]['risetime'])))+" ("+str(time.strftime('%H:%M:%S', time.gmtime(self.data['response'][self.n+1]['risetime']-time.time())))+")") else: self.futpass.get_child().set_text("Next Pass: "+str(time.strftime('%H:%M:%S', time.gmtime(self.data['response'][0]['risetime'])))+" ("+str(time.strftime('%H:%M:%S', time.gmtime(self.data['response'][0]['risetime']-time.time())))+")") if __name__ == '__main__': issindicator = indicator() 

One Solution collect form web for “Обновление GTK + MenuItem Countdown каждую секунду и вызов периодической функции”

Используйте gobject.timeout_add чтобы запланировать обратный вызов через равные промежутки времени. Например:

 gobject.timeout_add(3600 * 1000, self.checkiss) 

Функция будет вызываться из основного цикла через равные промежутки времени, пока она вернет истинное значение. Если вам нужна функция с одним выстрелом, просто верните False или позвольте ей неявно вернуть None . Чтобы запланировать функцию в определенный момент времени, вычислите время между текущей и этой точкой и вызовите timeout_add с этим периодом.

Когда меню активировано, перенесите функцию быстрее, при деактивации планируйте его медленнее. Чтобы перенести функцию, вызовите gobject.source_remove со значением, возвращаемым gobject.timeout_add , затем вызовите timeout_add с новым значением таймаута.

Основной цикл gtk гарантирует, что процесс не разбудится, если он не принимает события или истекает время ожидания.

Interesting Posts

Преобразование всех файлов csv из кодирования ansi в utf8 с помощью python

Где хранить общие строки strftime типа («% d /% m /% Y»)

Как пропустить pytest с помощью внешнего прибора?

Который является большими накладными расходами: каждый раз создавайте новый сокет или поддерживая один сокет для передачи данных

Не удалось импортировать _winreg в виртуальной среде Python 2.7.9

Приоритет оператора Python

Ленивые переменные модуля – это можно сделать?

Как извлечь определенные несколько значений в JSON с помощью python?

Flask-login AttributeError: объект 'Пользователь' не имеет атрибута 'is_active'

Почему мои правила Scraw CrawlSpider не работают?

Как я могу сделать массив B из массива A без бесконечностей, включенных в Python 2.7?

Regex найти все предложения текста?

Построение многозначной поверхности в майави

Последовательное получение ImportError: не удалось импортировать настройки «myapp.settings»

Tensorflow: Как написать op с градиентом в python?

Python - лучший язык программирования в мире.