- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我决定对天气托盘小程序进行一些修改 found here 。
经过多次测试,我发现update_tray()在我的计算机休眠一段时间后停止更新。只有手动更新才有效。
检查代码后,我发现负责更新的行是这样的:
gobject.timeout_add_seconds(self.args.delta * 60, self.update_tray)
gobject documentation 表示这个函数会被重复调用,直到返回FALSE,此时超时会自动销毁,并且该函数不会再次被调用。但似乎计数器被销毁了,因为系统时钟变化太突然了。
我想知道发生此问题时如何重新启动计时器。完整代码如下:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Released under the terms of the GNU GPLv2.
#
import gtk
import gobject
import time
import webbrowser
from urllib2 import urlopen, URLError
from argparse import ArgumentParser
from xml.dom import minidom
parser = ArgumentParser(description='Simple weather applet', epilog='Written by Roman Komkov and updated at 06.06.2012.\nPlease, report bugs to <r.komkov@gmail.com>')
parser.add_argument('-l', '--location', required=True, metavar='WOEID', help='location WOEID (more on http://developer.yahoo.com/weather/)')
parser.add_argument('-u', '--units', choices=['c','f'], default='c', metavar='c|f', help='units to display')
parser.add_argument('-d', '--delta', default='10', type=int, metavar='N', help='timeout in minutes between next weather data query')
parser.add_argument('-a', '--advanced', action = 'store_true', default=False, help='Advanced tooltip')
class Api:
def __init__(self, location, units):
self.params = (location,units)
self.url = 'http://xml.weather.yahoo.com/forecastrss?w=%s&u=%s'
self.namespace = 'http://xml.weather.yahoo.com/ns/rss/1.0'
self.website = 'http://weather.yahoo.com/'
self.codes = { #code:icon name
'0':'weather-severe-alert',
'1':'weather-severe-alert',
'2':'weather-severe-alert',
'3':'weather-severe-alert',
'4':'weather-storm',
'5':'weather-snow-rain',
'6':'weather-snow-rain',
'7':'weather-snow',
'8':'weather-freezing-rain',
'9':'weather-fog',
'10':'weather-freezing-rain',
'11':'weather-showers',
'12':'weather-showers',
'13':'weather-snow',
'14':'weather-snow',
'15':'weather-snow',
'16':'weather-snow',
'17':'weather-snow',
'18':'weather-snow',
'19':'weather-fog',
'20':'weather-fog',
'21':'weather-fog',
'22':'weather-fog',
'23':'weather-few-clouds',
'24':'weather-few-clouds',
'25':'weather-few-clouds',
'26':'weather-overcast',
'27':'weather-clouds-night',
'28':'weather-clouds',
'29':'weather-few-clouds-night',
'30':'weather-few-clouds',
'31':'weather-clear-night',
'32':'weather-clear',
'33':'weather-clear-night',
'34':'weather-clear',
'35':'weather-snow-rain',
'36':'weather-clear',
'37':'weather-storm',
'38':'weather-storm',
'39':'weather-storm',
'40':'weather-showers-scattered',
'41':'weather-snow',
'42':'weather-snow',
'43':'weather-snow',
'44':'weather-few-clouds',
'45':'weather-storm',
'46':'weather-snow',
'47':'weather-storm',
'3200':'stock-unknown'
}
def conv_direction(self, value):
value = int(value)
if value >= 0 and value < 45:
return u'\u2191 (N)'
elif value >= 45 and value < 90:
return u'\u2197 (NE)'
elif value >= 90 and value < 135:
return u'\u2192 (E)'
elif value >= 135 and value < 180:
return u'\u2198 (SE)'
elif value >= 180 and value < 225:
return u'\u2193 (S)'
elif value >= 225 and value < 270:
return u'\u2199 (SW)'
elif value >= 270 and value < 315:
return u'\u2190 (W)'
elif value >= 315 and value < 360:
return u'\u2196 (NW)'
else:
return u'\u2191 (N)'
def get_data(self):
try:
url = self.url % self.params
dom = minidom.parse(urlopen(url))
units_node = dom.getElementsByTagNameNS(self.namespace, 'units')[0]
units = {'temperature': units_node.getAttribute('temperature'),
'distance': units_node.getAttribute('distance'),
'pressure': units_node.getAttribute('pressure'),
'speed': units_node.getAttribute('speed')}
forecasts = []
for node in dom.getElementsByTagNameNS(self.namespace, 'forecast'):
forecasts.append({
'date': node.getAttribute('date'),
'low': node.getAttribute('low')+u'\u00B0 '+units['temperature'],
'high': node.getAttribute('high')+u'\u00B0 '+units['temperature'],
'condition': node.getAttribute('text'),
'icon': self.codes.get(node.getAttribute('code'))
})
condition = dom.getElementsByTagNameNS(self.namespace, 'condition')[0]
location = dom.getElementsByTagNameNS(self.namespace, 'location')[0]
wind = dom.getElementsByTagNameNS(self.namespace, 'wind')[0]
atmosphere = dom.getElementsByTagNameNS(self.namespace, 'atmosphere')[0]
return {
'current_condition': condition.getAttribute('text'),
'current_icon': self.codes.get(condition.getAttribute('code')),
'current_temp': condition.getAttribute('temp')+u'\u00B0 '+units['temperature'],
'extra':{
'wind': {'direction':self.conv_direction(wind.getAttribute('direction')),
'speed':wind.getAttribute('speed')+' '+units['speed']},
'atmosphere': {'humidity':atmosphere.getAttribute('humidity')+'%',
'visibility':atmosphere.getAttribute('visibility')+' '+units['distance'],
'pressure':atmosphere.getAttribute('pressure')+' '+units['pressure']}},
'forecasts': forecasts,
'location' : {'city' : location.getAttribute('city'),'country' : location.getAttribute('country')}
}
except URLError, ex:
return None
class MainApp:
def __init__(self,args):
self.args = args
self.weather = None
self.tooltip = None
self.tray = gtk.StatusIcon()
self.tray.connect('popup-menu', self.on_right_click)
self.tray.connect('activate', self.on_left_click)
self.tray.set_has_tooltip(True)
if self.args.advanced:
self.tray.connect('query-tooltip', self.on_tooltip_advanced)
self.api = Api(self.args.location, self.args.units)
self.update_tray()
gobject.timeout_add_seconds(self.args.delta * 60, self.update_tray)
def on_tooltip_advanced(self, widget, x, y, keyboard_mode, tooltip):
#if self.tooltip:
#tooltip.set_text(self.tooltip)
if self.weather:
weather = self.weather
tooltip_text = '%s\n%s' % (self.weather['current_temp'],self.weather['current_condition'])
vbox = gtk.VBox()
header = gtk.Label()
header.set_markup('<u><b>'+self.weather['location']['city']+', '+self.weather['location']['country']+'</b></u>')
header.set_alignment(1.0, 0.5)
separator_h = gtk.HSeparator()
hbox = gtk.HBox()
now_image = gtk.Image()
now_image.set_padding(0,5)
now_image.set_pixel_size(48)
now_image.set_from_icon_name(weather['current_icon'],48)
now_label = gtk.Label()
now_label.set_markup('<b>'+tooltip_text+'</b>')
now_label.set_padding(5,5)
table = gtk.Table(columns=2, homogeneous=False)
u = 0
l = 1
for k,v in self.weather['extra'].iteritems():
h_label = gtk.Label()
h_label.set_markup('<b>'+k+'</b>')
h_label.set_alignment(0.0, 0.5)
h_label.set_padding(5,0)
table.attach(h_label,0,1,u,l)
for i,j in v.iteritems():
u +=1
l +=1
k_label = gtk.Label(i)
k_label.set_alignment(0.0, 0.5)
v_label = gtk.Label(j)
v_label.set_alignment(0.0, 0.5)
table.attach(k_label,0,1,u,l)
table.attach(v_label,1,2,u,l)
u +=1
l +=1
hbox.pack_start(now_image, False, False, 0)
hbox.pack_start(now_label, False, False, 0)
vbox.pack_start(header, True, False, 0)
vbox.pack_start(separator_h, False, False, 0)
vbox.pack_start(hbox, False, False, 0)
vbox.pack_start(table, False, False, 0)
vbox.show_all()
tooltip.set_custom(vbox)
else:
tooltip.set_text('Connection error!')
return True
def on_refresh(self,widget):
self.update_tray()
def on_right_click(self, icon, event_button, event_time):
menu = gtk.Menu()
refresh = gtk.MenuItem('Refresh')
refresh.show()
refresh.connect('activate', self.on_refresh)
quit = gtk.MenuItem('Quit')
quit.show()
quit.connect('activate', gtk.main_quit)
menu.append(refresh)
menu.append(quit)
menu.popup(None, None, gtk.status_icon_position_menu,
event_button, event_time, self.tray)
def on_left_click(self, widget):
webbrowser.open(self.api.website)
def update_tray(self):
self.weather = self.api.get_data()
if self.weather != None:
self.tray.set_from_icon_name(self.weather['current_icon'])
if not self.args.advanced:
tooltip_text = '%s / %s' % (self.weather['current_temp'],self.weather['current_condition'])
self.tray.set_tooltip_markup(tooltip_text)
else:
if not self.args.advanced:
self.tray.set_tooltip_text('Connection error!')
self.tray.set_from_stock('gtk-dialog-error')
return True
if __name__ == "__main__":
try:
args = parser.parse_args()
MainApp(args)
gtk.main()
except KeyboardInterrupt:
pass
根据 @J.F.Sebastian 的要求,这里是一个较小的代码示例:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import gtk, gobject, time
from datetime import datetime
class MainApp:
def __init__(self):
self.update_tray()
gobject.timeout_add_seconds(15 * 60, self.update_tray)
def update_tray(self):
print time.strftime('%c')
return True
if __name__ == "__main__":
try:
MainApp()
gtk.main()
except KeyboardInterrupt:
pass
更新:我将其设置为每分钟更新一次,处于休眠状态,并且当返回时,脚本继续工作。 10 分钟后,我收到了 socket.error 消息,但它不再更新了。我认为问题不在于互联网连接,因为我无法通过拔掉电缆来重现它。现在,我的问题是:由于 get_data 已经有 try:
语句,因此如何在发现此错误后重新启动计数器,或避免此错误?
Traceback (most recent call last):
File "weatherboy", line 333, in update_tray
self.weather = self.api.get_data()
File "weatherboy", line 145, in get_data
dom = minidom.parse(urlopen(url))
File "/usr/lib/python2.7/urllib2.py", line 127, in urlopen
return _opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 401, in open
response = self._open(req, data)
File "/usr/lib/python2.7/urllib2.py", line 419, in _open
'_open', req)
File "/usr/lib/python2.7/urllib2.py", line 379, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 1211, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "/usr/lib/python2.7/urllib2.py", line 1184, in do_open
r = h.getresponse(buffering=True)
File "/usr/lib/python2.7/httplib.py", line 1034, in getresponse
response.begin()
File "/usr/lib/python2.7/httplib.py", line 407, in begin
version, status, reason = self._read_status()
File "/usr/lib/python2.7/httplib.py", line 365, in _read_status
line = self.fp.readline()
File "/usr/lib/python2.7/socket.py", line 447, in readline
data = self._sock.recv(self._rbufsize)
socket.error: [Errno 104] Connection reset by peer
最佳答案
如果您希望调用
update_tray()
,则应返回 True。未处理的 socket.error
会阻止这种情况。您可以使用 except EnvironmentError
而不是 except URLError
来捕获 get_data()
内更广泛的错误。
要忽略其他类型的错误,您可以将 try: ... except Exception: log_it()
添加到 update_tray()
。
关于python - 在 socket.error 后重新启动 gobject.timeout_add_seconds 计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19882390/
我在leetcode上看到这段代码,是一道求众数的题,下面是题目描述: 给定一个大小为 n 的数组,找到多数元素。众数元素是出现次数超过 ⌊ n/2 ⌋ 次的元素。 你可以假设数组是非空的并且多数元素
每次在 JavaScript 中执行特定操作时,例如: $(function() { $('#typing').keyup(function () { switch($(this)
我一直在为网页设计一个计数器,但我一直被这个我无法解决的功能所困扰。 我有一个 4 个 div 的计数器,因为其中两个是小数字,另外两个是大数字,所以第一个运行得很快,我看不到它们的功能。 有人知道如
我已经在文档中进行了一些搜索,并在网上花了一段时间,但找不到解决方案!我希望警报告诉我单击 .thumb 时它处于each() 的哪一次迭代。 EG:有六个.thumb,我点击数字3,浏览器弹出3!
在 Handlebars 中,假设我有 names 的集合.我能怎么做 {{#each names}} {{position}} {{name}} {{/each}} 在哪里 {{position}}
这个问题在这里已经有了答案: Numbering rows within groups in a data frame (9 个回答) 4年前关闭。 我们如何在数据帧的每组中生成唯一的 ID 号?以下
我正在努力解决以下问题。我希望为给定的“一”序列创建一个计数器。例如,我有以下内容: 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 鉴于该序列,我希望为 1 的每个序列设置一个计数器直到
我正在努力解决以下问题。我希望为给定的“一”序列创建一个计数器。例如,我有以下内容: 1 1 1 1 0 0 1 1 1 0 0 1 1 1 1 鉴于该序列,我希望为 1 的每个序列设置一个计数器直到
我有一个jsfiddle here 这是一个简单的 JavaScript 函数,可以计算出设定的数字。 是否可以进行这种计数,但也保留一位小数 所以它算 1.1、1.2、1.3 等。 func
我正在构建一个计数器,当我按下鼠标时,它应该增加到 maxValue 并且减少不超过 0。我还可以选择将计数器重置为其初始值:0。另外,如果 maxValue 是偶数,它应该计数到该数字。但是,如果
所以我成功地为字母和单词构建了其他计数器,但现在我只能用这个来计算句子。我的代码如下,当我运行它时,它会返回很多错误消息: #include #include #include int main
Closed. This question is off-topic。它当前不接受答案。
我需要一个计数器,它会随着某些任务的完成而递增。我们只需要最后一小时的值,即窗口将移动而不是静态时间。 解决此问题的最佳方法是什么?我能想到的一种方法是拥有一个大小为 60 的数组,每分钟一个,并更新
我希望使用计数器来为我提供独特的引用系统。我想单击一个按钮,然后检查一个字段/文件中的最后一个数字,然后简单地向其添加 1,然后将其插入到屏幕上的字段中? 不确定执行此操作的最佳方法或具体如何执行此操
我有一个用 php 制作的表格,在该表格内我显示了数据库中的一些内容。我在每个 td 中创建了一个简单的按钮(类似于 Like),我希望每次点击它都会增加 1。这是带有按钮的行: echo "
如何将数据库中的值转换为可用于 if else 函数的 int 值? 例如:在我的数据库“armnumber = 3”中,如何在 if else 函数中使用它? 代码 string myConnect
我需要生成唯一的“ids”,问题是,它只能在 1 - 99999 之间。 “好”的是,它仅在与另一列组合时必须是唯一的。 我们有组,每个组都有自己的“group_id”,每个组都需要类似 unique
有这个简单的代码: UPDATE counter SET c= c +1 where id = 1; 并且它在开头的 c 字段中为 null 的情况下不起作用。它只有在已经输入了一些数字时才有效,也就
我正在尝试在 python 中构建一个具有闭包属性的计数器。以下工作中的代码: def generate_counter(): CNT = [0] def add_one():
我使用 CSS 来计算 HTML 文档中的部分: body {counter-reset: sect;} section:before { counter-increment: sect;
我是一名优秀的程序员,十分优秀!