当前位置:   article > 正文

python桌面宠物_python 桌面宠物开发

python 桌面宠物开发

像我这种喜欢动物,但不是 那么 喜欢清理那种……新陈代谢的产物的人,桌面宠物就真的是一大福音了

当然,我可不是一位称职的“铲屎官”(???)

所以我最近就做出了一个功能还算齐全的桌面宠物

功能如下:

1.在桌面走来走去,或者打个盹;

2.左键单击它可以打开功能页;

3.有天气预报

4.有语言微聊(得登录图灵账号,但私信我免费拿账号密码);

5.一些有趣的天气提示。

好了,解析源码↓

  1. import tkinter
  2. import os
  3. import random
  4. from platform import system
  5. import easygui
  6. import requests
  7. from bs4 import BeautifulSoup
  8. import tkinter
  9. from prettytable import PrettyTable

这里是导入一些库↑

  1. def weather(self):
  2. url = f'http://wthrcdn.etouch.cn/weather_mini?citykey=101281601'
  3. res = requests.get(url)
  4. res.encoding = 'utf-8'
  5. res_json = res.json()
  6. # 2、数据格式化
  7. data = res_json['data']
  8. city = f"城市:{data['city']}\n"
  9. # 字符串格式化的一种方式 f"{}" 通过字典传递值
  10. today = data['forecast'][0]
  11. date = f"日期:{today['date']}\n" # \n 换行
  12. now = f"实时温度:{data['wendu']}度\n"
  13. temperature = f"波动范围:{today['high']} {today['low']}\n"
  14. fengxiang = f"风向:{today['fengxiang']}\n"
  15. type = f"天气:{today['type']}\n"
  16. tips = f"提醒:{data['ganmao']}\n"
  17. result = city + date + now + temperature + fengxiang + type + tips
  18. return result

这些就是关于天气小贴士的东西↑

  1. def getHTMLText(self,url,timeout = 30):
  2. try:
  3. r = requests.get(url, timeout = 30) #用requests抓取网页信息
  4. r.raise_for_status() #可以让程序产生异常时停止程序
  5. r.encoding = r.apparent_encoding
  6. return r.text
  7. except:
  8. return '产生异常'
  9. def get_data(self,html):
  10. final_list = []
  11. soup = BeautifulSoup(html,'html.parser') #用BeautifulSoup库解析网页
  12. body = soup.body
  13. data = body.find('div',{'id':'7d'})
  14. ul = data.find('ul')
  15. lis = ul.find_all('li')
  16. for day in lis:
  17. temp_list = []
  18. date = day.find('h1').string #找到日期
  19. temp_list.append(date)
  20. info = day.find_all('p') #找到所有的p标签
  21. temp_list.append(info[0].string)
  22. if info[1].find('span') is None: #找到p标签中的第二个值'span'标签——最高温度
  23. temperature_highest = ' ' #用一个判断是否有最高温度
  24. else:
  25. temperature_highest = info[1].find('span').string
  26. temperature_highest = temperature_highest.replace('℃',' ')
  27. if info[1].find('i') is None: #找到p标签中的第二个值'i'标签——最高温度
  28. temperature_lowest = ' ' #用一个判断是否有最低温度
  29. else:
  30. temperature_lowest = info[1].find('i').string
  31. temperature_lowest = temperature_lowest.replace('℃',' ')
  32. temp_list.append(temperature_highest) #将最高气温添加到temp_list中
  33. temp_list.append(temperature_lowest) #将最低气温添加到temp_list中
  34. wind_scale = info[2].find('i').string #找到p标签的第三个值'i'标签——风级,添加到temp_list中
  35. temp_list.append(wind_scale)
  36. final_list.append(temp_list) #将temp_list列表添加到final_list列表中
  37. return final_list
  38. def print_data(self,final_list,num):
  39. a="{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format('日期','天气','最高温度','最低温度','风级')
  40. for i in range(num):
  41. final = final_list[i]
  42. a=a+"\n"+"{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format(final[0],final[1],final[2],final[3],final[4])
  43. print(a)
  44. #用main()主函数将模块连接
  45. def main(self):
  46. url = 'http://www.weather.com.cn/weather/101281601.shtml'
  47. html = pet.getHTMLText(url)
  48. final_list = pet.get_data(html)
  49. pet.print_data(final_list,7)

这些就是爬虫抓包↑(这是我这的天气抓包,main函数中url地址后面16进制的数字改一改即可)

  1. def __init__(self):
  2. self.root = tkinter.Tk() # create window
  3. self.delay = 200 # delay in ms
  4. self.pixels_from_right = 200 # change to move the pet's starting position
  5. self.pixels_from_bottom = 200 # change to move the pet's starting position
  6. self.move_speed = 6 # change how fast the pet moves in pixels
  7. # initialize frame arrays
  8. self.animation = dict(
  9. idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle.gif'), format = 'gif -index %i' % i) for i in range(5)],
  10. idle_to_sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle-to-sleep.gif'), format = 'gif -index %i' % i) for i in range(8)],
  11. sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep.gif'), format = 'gif -index %i' % i) for i in range(3)]*3,
  12. sleep_to_idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep-to-idle.gif'), format = 'gif -index %i' % i) for i in range(8)],
  13. walk_left = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-left.gif'), format = 'gif -index %i' % i) for i in range(8)],
  14. walk_right = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-right.gif'),format = 'gif -index %i' % i) for i in range(8)]
  15. )
  16. # window configuration
  17. self.root.overrideredirect(True) # remove UI
  18. if system() == 'Windows':
  19. self.root.wm_attributes('-transparent','black')
  20. else: # platform is Mac/Linux
  21. # https://stackoverflow.com/questions/19080499/transparent-background-in-a-tkinter-window
  22. self.root.wm_attributes('-transparent', True) # do this for mac, but the bg stays black
  23. self.root.config(bg='systemTransparent')
  24. self.root.attributes('-topmost', True) # put window on top
  25. self.root.bind("<Button-1>", self.onLeftClick)
  26. self.root.bind("<Button-2>", self.onRightClick)
  27. self.root.bind("<Button-3>", self.onRightClick)
  28. self.root.bind("<Key>", self.onKeyPress)
  29. self.label = tkinter.Label(self.root,bd=0,bg='black') # borderless window
  30. if system() != 'Windows':
  31. self.label.config(bg='systemTransparent')
  32. self.label.pack()
  33. screen_width = self.root.winfo_screenwidth() # width of the entire screen
  34. screen_height = self.root.winfo_screenheight() # height of the entire screen
  35. self.min_width = 10 # do not let the pet move beyond this point
  36. self.max_width = screen_width-110 # do not let the pet move beyond this point
  37. # change starting properties of the window
  38. self.curr_width = screen_width-self.pixels_from_right
  39. self.curr_height = screen_height-self.pixels_from_bottom
  40. self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
  41. def update(self, i, curr_animation):
  42. # print("Curently: %s" % curr_animation)
  43. self.root.attributes('-topmost', True) # put window on top
  44. animation_arr = self.animation[curr_animation]
  45. frame = animation_arr[i]
  46. self.label.configure(image=frame)
  47. # move the pet if needed
  48. if curr_animation in ('walk_left', 'walk_right'):
  49. self.move_window(curr_animation)
  50. i += 1
  51. if i == len(animation_arr):
  52. # reached end of this animation, decide on the next animation
  53. next_animation = self.getNextAnimation(curr_animation)
  54. self.root.after(self.delay, self.update, 0, next_animation)
  55. else:
  56. self.root.after(self.delay, self.update, i, curr_animation)

这些就是建一个透明tkinter窗口,把gif塞进去↑

  1. def onLeftClick(self, event):
  2. print("detected left click")
  3. a=easygui.choicebox(msg=pet.weather(),title="",choices=["天气预报","语音微聊"])
  4. if a =="天气预报":
  5. pet.main()
  6. elif a=="语音微聊":
  7. newchat="你好"
  8. chat="(聊天记录已清空)"
  9. API_KEY=""#账号要注册
  10. API_SECRET=""
  11. person="我"
  12. while True:
  13. if not len(chat) >= 100:
  14. if newchat:
  15. url=('http://i.itpk.cn/api.php?question='+newchat+"&api_key="+API_KEY+"&api_secret="+API_SECRET)
  16. file=requests.get(url)#获取网页代码文件
  17. data=file.text#把代码转换成文字
  18. chat=chat+"\n"+person+":"+newchat+"\n"+"小睿:"+data#说话
  19. else:
  20. pet.run()
  21. newchat=easygui.textbox(chat,"和小睿的聊天")
  22. else:
  23. chat=""

这里就是主控制台,连接一下天气、机器人之类的东西↑

  1. def onRightClick(self, event):
  2. self.quit()
  3. quit()
  4. def onKeyPress(self, event):
  5. if event.char in ('q', 'Q'):
  6. self.quit()
  7. def move_window(self, curr_animation):
  8. if curr_animation == 'walk_left':
  9. if self.curr_width > self.min_width:
  10. self.curr_width -= self.move_speed
  11. elif curr_animation == 'walk_right':
  12. if self.curr_width < self.max_width:
  13. self.curr_width += self.move_speed
  14. self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
  15. def getNextAnimation(self, curr_animation):
  16. if curr_animation == 'idle':
  17. return random.choice(['idle', 'idle_to_sleep', 'walk_left', 'walk_right'])
  18. elif curr_animation == 'idle_to_sleep':
  19. return 'sleep'
  20. elif curr_animation == 'sleep':
  21. return random.choice(['sleep', 'sleep_to_idle'])
  22. elif curr_animation == 'sleep_to_idle':
  23. return 'idle'
  24. elif curr_animation == 'walk_left':
  25. return random.choice(['idle', 'walk_left', 'walk_right'])
  26. elif curr_animation == 'walk_right':
  27. return random.choice(['idle', 'walk_left', 'walk_right'])
  28. def run(self):
  29. self.root.after(self.delay, self.update, 0, 'idle') # start on idle
  30. self.root.mainloop()
  31. def quit(self):
  32. self.root.destroy()

这些就是触发事件了(左右键单击)↑

  1. if __name__ == '__main__':
  2. print('Initializing your desktop pet...')
  3. print('To quit, right click on the pet')
  4. pet = Pet()
  5. pet.run()

这些就很简单了,主函数召唤class pet↑

源码如下:

  1. import tkinter
  2. import os
  3. import random
  4. from platform import system
  5. import easygui
  6. import requests
  7. from bs4 import BeautifulSoup
  8. import tkinter
  9. from prettytable import PrettyTable
  10. class Pet:
  11. def weather(self):
  12. url = f'http://wthrcdn.etouch.cn/weather_mini?citykey=101281601'
  13. res = requests.get(url)
  14. res.encoding = 'utf-8'
  15. res_json = res.json()
  16. # 2、数据格式化
  17. data = res_json['data']
  18. city = f"城市:{data['city']}\n"
  19. # 字符串格式化的一种方式 f"{}" 通过字典传递值
  20. today = data['forecast'][0]
  21. date = f"日期:{today['date']}\n" # \n 换行
  22. now = f"实时温度:{data['wendu']}度\n"
  23. temperature = f"波动范围:{today['high']} {today['low']}\n"
  24. fengxiang = f"风向:{today['fengxiang']}\n"
  25. type = f"天气:{today['type']}\n"
  26. tips = f"提醒:{data['ganmao']}\n"
  27. result = city + date + now + temperature + fengxiang + type + tips
  28. return result
  29. def getHTMLText(self,url,timeout = 30):
  30. try:
  31. r = requests.get(url, timeout = 30) #用requests抓取网页信息
  32. r.raise_for_status() #可以让程序产生异常时停止程序
  33. r.encoding = r.apparent_encoding
  34. return r.text
  35. except:
  36. return '产生异常'
  37. def get_data(self,html):
  38. final_list = []
  39. soup = BeautifulSoup(html,'html.parser') #用BeautifulSoup库解析网页
  40. body = soup.body
  41. data = body.find('div',{'id':'7d'})
  42. ul = data.find('ul')
  43. lis = ul.find_all('li')
  44. for day in lis:
  45. temp_list = []
  46. date = day.find('h1').string #找到日期
  47. temp_list.append(date)
  48. info = day.find_all('p') #找到所有的p标签
  49. temp_list.append(info[0].string)
  50. if info[1].find('span') is None: #找到p标签中的第二个值'span'标签——最高温度
  51. temperature_highest = ' ' #用一个判断是否有最高温度
  52. else:
  53. temperature_highest = info[1].find('span').string
  54. temperature_highest = temperature_highest.replace('℃',' ')
  55. if info[1].find('i') is None: #找到p标签中的第二个值'i'标签——最高温度
  56. temperature_lowest = ' ' #用一个判断是否有最低温度
  57. else:
  58. temperature_lowest = info[1].find('i').string
  59. temperature_lowest = temperature_lowest.replace('℃',' ')
  60. temp_list.append(temperature_highest) #将最高气温添加到temp_list中
  61. temp_list.append(temperature_lowest) #将最低气温添加到temp_list中
  62. wind_scale = info[2].find('i').string #找到p标签的第三个值'i'标签——风级,添加到temp_list中
  63. temp_list.append(wind_scale)
  64. final_list.append(temp_list) #将temp_list列表添加到final_list列表中
  65. return final_list
  66. def print_data(self,final_list,num):
  67. a="{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format('日期','天气','最高温度','最低温度','风级')
  68. for i in range(num):
  69. final = final_list[i]
  70. a=a+"\n"+"{:^10}\t{:^8}\t{:^8}\t{:^8}\t{:^8}".format(final[0],final[1],final[2],final[3],final[4])
  71. print(a)
  72. #用main()主函数将模块连接
  73. def main(self):
  74. url = 'http://www.weather.com.cn/weather/101281601.shtml'
  75. html = pet.getHTMLText(url)
  76. final_list = pet.get_data(html)
  77. pet.print_data(final_list,7)
  78. def __init__(self):
  79. self.root = tkinter.Tk() # create window
  80. self.delay = 200 # delay in ms
  81. self.pixels_from_right = 200 # change to move the pet's starting position
  82. self.pixels_from_bottom = 200 # change to move the pet's starting position
  83. self.move_speed = 6 # change how fast the pet moves in pixels
  84. # initialize frame arrays
  85. self.animation = dict(
  86. idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle.gif'), format = 'gif -index %i' % i) for i in range(5)],
  87. idle_to_sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/idle-to-sleep.gif'), format = 'gif -index %i' % i) for i in range(8)],
  88. sleep = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep.gif'), format = 'gif -index %i' % i) for i in range(3)]*3,
  89. sleep_to_idle = [tkinter.PhotoImage(file=os.path.abspath('gifs/sleep-to-idle.gif'), format = 'gif -index %i' % i) for i in range(8)],
  90. walk_left = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-left.gif'), format = 'gif -index %i' % i) for i in range(8)],
  91. walk_right = [tkinter.PhotoImage(file=os.path.abspath('gifs/walk-right.gif'),format = 'gif -index %i' % i) for i in range(8)]
  92. )
  93. # window configuration
  94. self.root.overrideredirect(True) # remove UI
  95. if system() == 'Windows':
  96. self.root.wm_attributes('-transparent','black')
  97. else: # platform is Mac/Linux
  98. # https://stackoverflow.com/questions/19080499/transparent-background-in-a-tkinter-window
  99. self.root.wm_attributes('-transparent', True) # do this for mac, but the bg stays black
  100. self.root.config(bg='systemTransparent')
  101. self.root.attributes('-topmost', True) # put window on top
  102. self.root.bind("<Button-1>", self.onLeftClick)
  103. self.root.bind("<Button-2>", self.onRightClick)
  104. self.root.bind("<Button-3>", self.onRightClick)
  105. self.root.bind("<Key>", self.onKeyPress)
  106. self.label = tkinter.Label(self.root,bd=0,bg='black') # borderless window
  107. if system() != 'Windows':
  108. self.label.config(bg='systemTransparent')
  109. self.label.pack()
  110. screen_width = self.root.winfo_screenwidth() # width of the entire screen
  111. screen_height = self.root.winfo_screenheight() # height of the entire screen
  112. self.min_width = 10 # do not let the pet move beyond this point
  113. self.max_width = screen_width-110 # do not let the pet move beyond this point
  114. # change starting properties of the window
  115. self.curr_width = screen_width-self.pixels_from_right
  116. self.curr_height = screen_height-self.pixels_from_bottom
  117. self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
  118. def update(self, i, curr_animation):
  119. # print("Curently: %s" % curr_animation)
  120. self.root.attributes('-topmost', True) # put window on top
  121. animation_arr = self.animation[curr_animation]
  122. frame = animation_arr[i]
  123. self.label.configure(image=frame)
  124. # move the pet if needed
  125. if curr_animation in ('walk_left', 'walk_right'):
  126. self.move_window(curr_animation)
  127. i += 1
  128. if i == len(animation_arr):
  129. # reached end of this animation, decide on the next animation
  130. next_animation = self.getNextAnimation(curr_animation)
  131. self.root.after(self.delay, self.update, 0, next_animation)
  132. else:
  133. self.root.after(self.delay, self.update, i, curr_animation)
  134. def onLeftClick(self, event):
  135. print("detected left click")
  136. a=easygui.choicebox(msg=pet.weather(),title="",choices=["天气预报","语音微聊"])
  137. if a =="天气预报":
  138. pet.main()
  139. elif a=="语音微聊":
  140. newchat="你好"
  141. chat="(聊天记录已清空)"
  142. API_KEY=""#记得登录,否则报错
  143. API_SECRET=""
  144. while True:
  145. if newchat:
  146. url=('http://i.itpk.cn/api.php?question='+newchat+"&api_key="+API_KEY+"&api_secret="+API_SECRET)
  147. file=requests.get(url)#获取网页代码文件
  148. data=file.text#把代码转换成文字
  149. chat=chat+"\n"+person+":"+newchat+"\n"+"机器人:"+data#说话
  150. else:
  151. onLeftClick(event)
  152. newchat=easygui.textbox(chat,"和智能机器人的聊天")
  153. def onRightClick(self, event):
  154. self.quit()
  155. quit()
  156. def onKeyPress(self, event):
  157. if event.char in ('q', 'Q'):
  158. self.quit()
  159. def move_window(self, curr_animation):
  160. if curr_animation == 'walk_left':
  161. if self.curr_width > self.min_width:
  162. self.curr_width -= self.move_speed
  163. elif curr_animation == 'walk_right':
  164. if self.curr_width < self.max_width:
  165. self.curr_width += self.move_speed
  166. self.root.geometry('%dx%d+%d+%d' % (100, 100, self.curr_width, self.curr_height))
  167. def getNextAnimation(self, curr_animation):
  168. if curr_animation == 'idle':
  169. return random.choice(['idle', 'idle_to_sleep', 'walk_left', 'walk_right'])
  170. elif curr_animation == 'idle_to_sleep':
  171. return 'sleep'
  172. elif curr_animation == 'sleep':
  173. return random.choice(['sleep', 'sleep_to_idle'])
  174. elif curr_animation == 'sleep_to_idle':
  175. return 'idle'
  176. elif curr_animation == 'walk_left':
  177. return random.choice(['idle', 'walk_left', 'walk_right'])
  178. elif curr_animation == 'walk_right':
  179. return random.choice(['idle', 'walk_left', 'walk_right'])
  180. def run(self):
  181. self.root.after(self.delay, self.update, 0, 'idle') # start on idle
  182. self.root.mainloop()
  183. def quit(self):
  184. self.root.destroy()
  185. if __name__ == '__main__':
  186. print('Initializing your desktop pet...')
  187. print('To quit, right click on the pet')
  188. pet = Pet()
  189. pet.run()

拿(留)走(下)不(评)谢(论)

记得关注鸭

注:模板来自GitHub - tommyli3318/desktop-pet: An animated pet that moves around on your desktop, using tkinter in Pythonhttps://github.com/tommyli3318/desktop-pet

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/682407
推荐阅读
相关标签
  

闽ICP备14008679号