赞
踩
像我这种喜欢动物,但不是 那么 喜欢清理那种……新陈代谢的产物的人,桌面宠物就真的是一大福音了
当然,我可不是一位称职的“铲屎官”(???)
所以我最近就做出了一个功能还算齐全的桌面宠物
功能如下:
1.在桌面走来走去,或者打个盹;
2.左键单击它可以打开功能页;
3.有天气预报;
4.有语言微聊(得登录图灵账号,但私信我免费拿账号密码);
5.一些有趣的天气提示。
好了,解析源码↓
- import tkinter
- import os
- import random
- from platform import system
- import easygui
- import requests
- from bs4 import BeautifulSoup
- import tkinter
- from prettytable import PrettyTable
这里是导入一些库↑
- def weather(self):
- url = f'http://wthrcdn.etouch.cn/weather_mini?citykey=101281601'
- res = requests.get(url)
- res.encoding = 'utf-8'
- res_json = res.json()
-
- # 2、数据格式化
- data = res_json['data']
- city = f"城市:{data['city']}\n"
- # 字符串格式化的一种方式 f"{}" 通过字典传递值
-
- today = data['forecast'][0]
- date = f"日期:{today['date']}\n" # \n 换行
- now = f"实时温度:{data['wendu']}度\n"
- temperature = f"波动范围:{today['high']} {today['low']}\n"
- fengxiang = f"风向:{today['fengxiang']}\n"
- type = f"天气:{today['type']}\n"
- tips = f"提醒:{data['ganmao']}\n"
- result = city + date + now + temperature + fengxiang + type + tips
- return result
这些就是关于天气小贴士的东西↑
- def getHTMLText(self,url,timeout = 30):
- try:
- r = requests.get(url, timeout = 30) #用requests抓取网页信息
- r.raise_for_status() #可以让程序产生异常时停止程序
- r.encoding = r.apparent_encoding
- return r.text
- except:
- return '产生异常'
-
-
- def get_data(self,html):
- final_list = []
- soup = BeautifulSoup(html,'html.parser') #用BeautifulSoup库解析网页
- body = soup.body
- data = body.find('div',{'id':'7d'})
- ul = data.find('ul')
- lis = ul.find_all('li')
-
-
- for day in lis:
- temp_list = []
-
- date = day.find('h1').string #找到日期
- temp_list.append(date)
-
- info = day.find_all('p') #找到所有的p标签
- temp_list.append(info[0].string)
-
- if info[1].find('span') is None: #找到p标签中的第二个值'span'标签——最高温度
- temperature_highest = ' ' #用一个判断是否有最高温度
- else:
- temperature_highest = info[1].find('span').string
- temperature_highest = temperature_highest.replace('℃',' ')
-
- if info[1].find('i') is None: #找到p标签中的第二个值'i'标签——最高温度
- temperature_lowest = ' ' #用一个判断是否有最低温度
- else:
- temperature_lowest = info[1].find('i').string
- temperature_lowest = temperature_lowest.replace('℃',' ')
-
- temp_list.append(temperature_highest) #将最高气温添加到temp_list中
- temp_list.append(temperature_lowest) #将最低气温添加到temp_list中
-
- wind_scale = info[2].find('i').string #找到p标签的第三个值'i'标签——风级,添加到temp_list中
- temp_list.append(wind_scale)
-
- final_list.append(temp_list) #将temp_list列表添加到final_list列表中
- return final_list
-
- def print_data(self,final_list,num):
- a="{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format('日期','天气','最高温度','最低温度','风级')
- for i in range(num):
- final = final_list[i]
- a=a+"\n"+"{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format(final[0],final[1],final[2],final[3],final[4])
- print(a)
-
-
- #用main()主函数将模块连接
- def main(self):
- url = 'http://www.weather.com.cn/weather/101281601.shtml'
- html = pet.getHTMLText(url)
- final_list = pet.get_data(html)
- pet.print_data(final_list,7)
这些就是爬虫抓包↑(这是我这的天气抓包,main函数中url地址后面16进制的数字改一改即可)
- def __init__(self):
- self.root = tkinter.Tk() # create window
- self.delay = 200 # delay in ms
- self.pixels_from_right = 200 # change to move the pet's starting position
- self.pixels_from_bottom = 200 # change to move the pet's starting position
- self.move_speed = 6 # change how fast the pet moves in pixels
-
- # initialize frame arrays
- self.animation = dict(
- idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle.gif'), format = 'gif -index %i' % i) for i in range(5)],
- idle_to_sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle-to-sleep.gif'), format = 'gif -index %i' % i) for i in range(8)],
- sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep.gif'), format = 'gif -index %i' % i) for i in range(3)]*3,
- sleep_to_idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep-to-idle.gif'), format = 'gif -index %i' % i) for i in range(8)],
- walk_left = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-left.gif'), format = 'gif -index %i' % i) for i in range(8)],
- walk_right = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-right.gif'),format = 'gif -index %i' % i) for i in range(8)]
- )
-
- # window configuration
- self.root.overrideredirect(True) # remove UI
- if system() == 'Windows':
- self.root.wm_attributes('-transparent','black')
- else: # platform is Mac/Linux
- # https://stackoverflow.com/questions/19080499/transparent-background-in-a-tkinter-window
- self.root.wm_attributes('-transparent', True) # do this for mac, but the bg stays black
- self.root.config(bg='systemTransparent')
-
- self.root.attributes('-topmost', True) # put window on top
- self.root.bind("<Button-1>", self.onLeftClick)
- self.root.bind("<Button-2>", self.onRightClick)
- self.root.bind("<Button-3>", self.onRightClick)
- self.root.bind("<Key>", self.onKeyPress)
- self.label = tkinter.Label(self.root,bd=0,bg='black') # borderless window
- if system() != 'Windows':
- self.label.config(bg='systemTransparent')
- self.label.pack()
-
- screen_width = self.root.winfo_screenwidth() # width of the entire screen
- screen_height = self.root.winfo_screenheight() # height of the entire screen
- self.min_width = 10 # do not let the pet move beyond this point
- self.max_width = screen_width-110 # do not let the pet move beyond this point
-
- # change starting properties of the window
- self.curr_width = screen_width-self.pixels_from_right
- self.curr_height = screen_height-self.pixels_from_bottom
- self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
-
-
- def update(self, i, curr_animation):
- # print("Curently: %s" % curr_animation)
- self.root.attributes('-topmost', True) # put window on top
- animation_arr = self.animation[curr_animation]
- frame = animation_arr[i]
- self.label.configure(image=frame)
-
- # move the pet if needed
- if curr_animation in ('walk_left', 'walk_right'):
- self.move_window(curr_animation)
-
- i += 1
- if i == len(animation_arr):
- # reached end of this animation, decide on the next animation
- next_animation = self.getNextAnimation(curr_animation)
- self.root.after(self.delay, self.update, 0, next_animation)
- else:
- self.root.after(self.delay, self.update, i, curr_animation)
这些就是建一个透明tkinter窗口,把gif塞进去↑
- def onLeftClick(self, event):
- print("detected left click")
- a=easygui.choicebox(msg=pet.weather(),title="",choices=["天气预报","语音微聊"])
- if a =="天气预报":
- pet.main()
-
- elif a=="语音微聊":
- newchat="你好"
- chat="(聊天记录已清空)"
- API_KEY=""#账号要注册
- API_SECRET=""
- person="我"
- while True:
- if not len(chat) >= 100:
- if newchat:
- url=('http://i.itpk.cn/api.php?question='+newchat+"&api_key="+API_KEY+"&api_secret="+API_SECRET)
- file=requests.get(url)#获取网页代码文件
- data=file.text#把代码转换成文字
- chat=chat+"\n"+person+":"+newchat+"\n"+"小睿:"+data#说话
- else:
- pet.run()
- newchat=easygui.textbox(chat,"和小睿的聊天")
- else:
- chat=""
这里就是主控制台,连接一下天气、机器人之类的东西↑
- def onRightClick(self, event):
- self.quit()
- quit()
-
-
- def onKeyPress(self, event):
- if event.char in ('q', 'Q'):
- self.quit()
-
-
- def move_window(self, curr_animation):
- if curr_animation == 'walk_left':
- if self.curr_width > self.min_width:
- self.curr_width -= self.move_speed
-
- elif curr_animation == 'walk_right':
- if self.curr_width < self.max_width:
- self.curr_width += self.move_speed
-
- self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
-
-
- def getNextAnimation(self, curr_animation):
- if curr_animation == 'idle':
- return random.choice(['idle', 'idle_to_sleep', 'walk_left', 'walk_right'])
- elif curr_animation == 'idle_to_sleep':
- return 'sleep'
- elif curr_animation == 'sleep':
- return random.choice(['sleep', 'sleep_to_idle'])
- elif curr_animation == 'sleep_to_idle':
- return 'idle'
- elif curr_animation == 'walk_left':
- return random.choice(['idle', 'walk_left', 'walk_right'])
- elif curr_animation == 'walk_right':
- return random.choice(['idle', 'walk_left', 'walk_right'])
-
-
- def run(self):
- self.root.after(self.delay, self.update, 0, 'idle') # start on idle
- self.root.mainloop()
-
-
- def quit(self):
- self.root.destroy()
这些就是触发事件了(左右键单击)↑
- if __name__ == '__main__':
- print('Initializing your desktop pet...')
- print('To quit, right click on the pet')
- pet = Pet()
- pet.run()
这些就很简单了,主函数召唤class pet↑
源码如下:
- import tkinter
- import os
- import random
- from platform import system
- import easygui
- import requests
- from bs4 import BeautifulSoup
- import tkinter
- from prettytable import PrettyTable
- class Pet:
-
- def weather(self):
- url = f'http://wthrcdn.etouch.cn/weather_mini?citykey=101281601'
- res = requests.get(url)
- res.encoding = 'utf-8'
- res_json = res.json()
-
- # 2、数据格式化
- data = res_json['data']
- city = f"城市:{data['city']}\n"
- # 字符串格式化的一种方式 f"{}" 通过字典传递值
-
- today = data['forecast'][0]
- date = f"日期:{today['date']}\n" # \n 换行
- now = f"实时温度:{data['wendu']}度\n"
- temperature = f"波动范围:{today['high']} {today['low']}\n"
- fengxiang = f"风向:{today['fengxiang']}\n"
- type = f"天气:{today['type']}\n"
- tips = f"提醒:{data['ganmao']}\n"
- result = city + date + now + temperature + fengxiang + type + tips
- return result
-
- def getHTMLText(self,url,timeout = 30):
- try:
- r = requests.get(url, timeout = 30) #用requests抓取网页信息
- r.raise_for_status() #可以让程序产生异常时停止程序
- r.encoding = r.apparent_encoding
- return r.text
- except:
- return '产生异常'
-
-
- def get_data(self,html):
- final_list = []
- soup = BeautifulSoup(html,'html.parser') #用BeautifulSoup库解析网页
- body = soup.body
- data = body.find('div',{'id':'7d'})
- ul = data.find('ul')
- lis = ul.find_all('li')
-
-
- for day in lis:
- temp_list = []
-
- date = day.find('h1').string #找到日期
- temp_list.append(date)
-
- info = day.find_all('p') #找到所有的p标签
- temp_list.append(info[0].string)
-
- if info[1].find('span') is None: #找到p标签中的第二个值'span'标签——最高温度
- temperature_highest = ' ' #用一个判断是否有最高温度
- else:
- temperature_highest = info[1].find('span').string
- temperature_highest = temperature_highest.replace('℃',' ')
-
- if info[1].find('i') is None: #找到p标签中的第二个值'i'标签——最高温度
- temperature_lowest = ' ' #用一个判断是否有最低温度
- else:
- temperature_lowest = info[1].find('i').string
- temperature_lowest = temperature_lowest.replace('℃',' ')
-
- temp_list.append(temperature_highest) #将最高气温添加到temp_list中
- temp_list.append(temperature_lowest) #将最低气温添加到temp_list中
-
- wind_scale = info[2].find('i').string #找到p标签的第三个值'i'标签——风级,添加到temp_list中
- temp_list.append(wind_scale)
-
- final_list.append(temp_list) #将temp_list列表添加到final_list列表中
- return final_list
-
- def print_data(self,final_list,num):
- a="{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format('日期','天气','最高温度','最低温度','风级')
- for i in range(num):
- final = final_list[i]
- a=a+"\n"+"{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format(final[0],final[1],final[2],final[3],final[4])
- print(a)
-
-
- #用main()主函数将模块连接
- def main(self):
- url = 'http://www.weather.com.cn/weather/101281601.shtml'
- html = pet.getHTMLText(url)
- final_list = pet.get_data(html)
- pet.print_data(final_list,7)
-
- def __init__(self):
- self.root = tkinter.Tk() # create window
- self.delay = 200 # delay in ms
- self.pixels_from_right = 200 # change to move the pet's starting position
- self.pixels_from_bottom = 200 # change to move the pet's starting position
- self.move_speed = 6 # change how fast the pet moves in pixels
-
- # initialize frame arrays
- self.animation = dict(
- idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle.gif'), format = 'gif -index %i' % i) for i in range(5)],
- idle_to_sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle-to-sleep.gif'), format = 'gif -index %i' % i) for i in range(8)],
- sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep.gif'), format = 'gif -index %i' % i) for i in range(3)]*3,
- sleep_to_idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep-to-idle.gif'), format = 'gif -index %i' % i) for i in range(8)],
- walk_left = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-left.gif'), format = 'gif -index %i' % i) for i in range(8)],
- walk_right = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-right.gif'),format = 'gif -index %i' % i) for i in range(8)]
- )
-
- # window configuration
- self.root.overrideredirect(True) # remove UI
- if system() == 'Windows':
- self.root.wm_attributes('-transparent','black')
- else: # platform is Mac/Linux
- # https://stackoverflow.com/questions/19080499/transparent-background-in-a-tkinter-window
- self.root.wm_attributes('-transparent', True) # do this for mac, but the bg stays black
- self.root.config(bg='systemTransparent')
-
- self.root.attributes('-topmost', True) # put window on top
- self.root.bind("<Button-1>", self.onLeftClick)
- self.root.bind("<Button-2>", self.onRightClick)
- self.root.bind("<Button-3>", self.onRightClick)
- self.root.bind("<Key>", self.onKeyPress)
- self.label = tkinter.Label(self.root,bd=0,bg='black') # borderless window
- if system() != 'Windows':
- self.label.config(bg='systemTransparent')
- self.label.pack()
-
- screen_width = self.root.winfo_screenwidth() # width of the entire screen
- screen_height = self.root.winfo_screenheight() # height of the entire screen
- self.min_width = 10 # do not let the pet move beyond this point
- self.max_width = screen_width-110 # do not let the pet move beyond this point
-
- # change starting properties of the window
- self.curr_width = screen_width-self.pixels_from_right
- self.curr_height = screen_height-self.pixels_from_bottom
- self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
-
-
- def update(self, i, curr_animation):
- # print("Curently: %s" % curr_animation)
- self.root.attributes('-topmost', True) # put window on top
- animation_arr = self.animation[curr_animation]
- frame = animation_arr[i]
- self.label.configure(image=frame)
-
- # move the pet if needed
- if curr_animation in ('walk_left', 'walk_right'):
- self.move_window(curr_animation)
-
- i += 1
- if i == len(animation_arr):
- # reached end of this animation, decide on the next animation
- next_animation = self.getNextAnimation(curr_animation)
- self.root.after(self.delay, self.update, 0, next_animation)
- else:
- self.root.after(self.delay, self.update, i, curr_animation)
-
-
- def onLeftClick(self, event):
- print("detected left click")
- a=easygui.choicebox(msg=pet.weather(),title="",choices=["天气预报","语音微聊"])
- if a =="天气预报":
- pet.main()
- elif a=="语音微聊":
- newchat="你好"
- chat="(聊天记录已清空)"
- API_KEY=""#记得登录,否则报错
- API_SECRET=""
- while True:
- if newchat:
- url=('http://i.itpk.cn/api.php?question='+newchat+"&api_key="+API_KEY+"&api_secret="+API_SECRET)
- file=requests.get(url)#获取网页代码文件
- data=file.text#把代码转换成文字
- chat=chat+"\n"+person+":"+newchat+"\n"+"机器人:"+data#说话
- else:
- onLeftClick(event)
- newchat=easygui.textbox(chat,"和智能机器人的聊天")
-
-
-
- def onRightClick(self, event):
- self.quit()
- quit()
-
-
- def onKeyPress(self, event):
- if event.char in ('q', 'Q'):
- self.quit()
-
-
- def move_window(self, curr_animation):
- if curr_animation == 'walk_left':
- if self.curr_width > self.min_width:
- self.curr_width -= self.move_speed
-
- elif curr_animation == 'walk_right':
- if self.curr_width < self.max_width:
- self.curr_width += self.move_speed
-
- self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
-
-
- def getNextAnimation(self, curr_animation):
- if curr_animation == 'idle':
- return random.choice(['idle', 'idle_to_sleep', 'walk_left', 'walk_right'])
- elif curr_animation == 'idle_to_sleep':
- return 'sleep'
- elif curr_animation == 'sleep':
- return random.choice(['sleep', 'sleep_to_idle'])
- elif curr_animation == 'sleep_to_idle':
- return 'idle'
- elif curr_animation == 'walk_left':
- return random.choice(['idle', 'walk_left', 'walk_right'])
- elif curr_animation == 'walk_right':
- return random.choice(['idle', 'walk_left', 'walk_right'])
-
-
- def run(self):
- self.root.after(self.delay, self.update, 0, 'idle') # start on idle
- self.root.mainloop()
-
-
- def quit(self):
- self.root.destroy()
-
-
- if __name__ == '__main__':
- print('Initializing your desktop pet...')
- print('To quit, right click on the pet')
- pet = Pet()
- pet.run()
拿(留)走(下)不(评)谢(论)
记得关注鸭
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。