最近工作比较闲,做点东西娱乐一下。
之前看到酷狗的动态壁纸,挺炫酷的,还能自定义,可惜我不会html,于是查了查发现python也能做,嘿嘿!
原理基本就是用windowsAPI获取桌面窗口句柄,然后用自己的程序窗口替换掉就行,代码如下:
def getWindowHandle():
hwnd = win32.win32gui.FindWindow("Progman", "Program Manager")
win32.win32gui.SendMessageTimeout(hwnd, 0x052C, 0, None, 0, 0x03E8)
hwnd_WorkW = None
while 1:
hwnd_WorkW = win32.win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
# print('hwmd_workw: ', hwnd_WorkW)
if not hwnd_WorkW:
continue
hView = win32.win32gui.FindWindowEx(hwnd_WorkW, None, "SHELLDLL_DefView", None)
# print('hwmd_hView: ', hView)
if not hView:
continue
h = win32.win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
# print('h_1: ',h)
while h:
win32.win32gui.SendMessage(h, 0x0010, 0, 0) # WM_CLOSE
h = win32.win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
# print(h)
break
return hwnd
动态准备用gif图像,简单,相关资源还多一些。
窗口用pyqt来做,可以方便的加载gif图像,还可以顺便加个托盘,方便退出,主要代码如下:
class QtWindow(QMainWindow):
def __init__(self, parent=None):
super(QtWindow, self).__init__(parent)
self.setWindowFlags(Qt.FramelessWindowHint)
#self.setAttribute(Qt.WA_TranslucentBackground)
self.main_layout = QGridLayout()
self.setLayout(self.main_layout)
self.gif_label = QLabel(self)
win_hwnd = int(self.winId())
h = win32.win32gui.FindWindow(("Progman"), ("Program Manager"))
win32.win32gui.SetParent(win_hwnd, h)
然后就是获取当地的实时天气了,这个困扰了我一段时间,网上基本是两种方式,一种是申请一些开放平台的api来获取天气,一种是访问一些天气网站然后来爬取数据分析。本来不想用第一种方式,因为还得申请,可是用第二种方式折腾了好久,不是网址失效,就是被限制,最终还是用了开放平台的api。
申请了高德的,还是比较方便的,个人开发者也够用了。使用python的requests库访问对应网址获取天气。由于高德要求使用城市的adcode来获取对应的天气,所以要先获取当地城市adcode,再获取天气,代码如下:
def get_weather(self):
url = "https://restapi.amap.com/v3/ip"
params = {
'key': 'your key',
}
response = requests.get(url, params=params)
result = response.json()
city_code = result['adcode']
params = {
'key': 'your key',
'city': city_code
}
response = requests.get('https://restapi.amap.com/v3/weather/weatherInfo?parameters', params=params)
result = response.json()
# 提取所需的天气信息
if result['status'] == '1' and int(result['count']) >= 1:
weather_info = result['lives'][0]
weather_info = weather_info['weather']
if weather_info not in gaode_weathers:
self.weather_info_signal.emit('未知')
#print("天气状态:", weather_info['weather'])
else:
self.weather_info_signal.emit(weather_info)
else:
#print("无法获取到天气信息!")
self.weather_info_signal.emit('未知')
由高德得到的天气状态是个中文字符,比如“晴”,“多云”,“小雪”等等,查了下,高德一共有68种天气状态,我们要为每一种天气状态都配一个gif图(找gif图简直是个噩梦),然后获取到天气状态后显示对应的gif图即可。
然后就是用qt的QTimer做定时器,每半个小时获取一次天气,然后更新壁纸;做一个托盘,方便退出。
所有代码都贴一下:
#weather_wallpaper.py
import sys
import os
import win32.win32gui
from PyQt5.QtWidgets import *
from qtwindow import QtWindow
from Weather import Weather
from PyQt5.QtWidgets import QApplication, QWidget, QSystemTrayIcon, QAction, QMenu
from PyQt5.QtGui import QIcon, QPixmap, QColor
class TaryWiondw(QWidget):
def __init__(self):
super().__init__()
# 创建托盘对象
self.tray = QSystemTrayIcon()
#self.trayIconPix = QPixmap(16,16)
#self.trayIconPix.fill(QColor(255,0,123))
icopath = 'res//天气.png'
bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(icopath)))
path = os.path.join(bundle_dir, icopath)
self.trayIconPix = QPixmap(path)
self.Icon = QIcon(self.trayIconPix)
self.tray.setIcon(self.Icon)
#showAction = QAction("&Show", self, triggered = self.Show)
quitAction = QAction("&Quit", self, triggered = self.Exit)
self.trayMenu = QMenu(self)
#self.trayMenu.addAction(showAction)
self.trayMenu.addSeparator()
self.trayMenu.addAction(quitAction)
self.tray.setContextMenu(self.trayMenu)
self.tray.show()
def Exit(self):
self.tray = None
sys.exit(app.exec_())
def Show(self):
#self.show()
a = 0
def getWindowHandle():
hwnd = win32.win32gui.FindWindow("Progman", "Program Manager")
win32.win32gui.SendMessageTimeout(hwnd, 0x052C, 0, None, 0, 0x03E8)
hwnd_WorkW = None
while 1:
hwnd_WorkW = win32.win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
# print('hwmd_workw: ', hwnd_WorkW)
if not hwnd_WorkW:
continue
hView = win32.win32gui.FindWindowEx(hwnd_WorkW, None, "SHELLDLL_DefView", None)
# print('hwmd_hView: ', hView)
if not hView:
continue
h = win32.win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
# print('h_1: ',h)
while h:
win32.win32gui.SendMessage(h, 0x0010, 0, 0) # WM_CLOSE
h = win32.win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
# print(h)
break
return hwnd
if __name__ == "__main__":
app = QApplication(sys.argv)
getWindowHandle()
weather = Weather()
myWin = QtWindow()
weather.weather_info_signal.connect(myWin.recvWeather_slot)
myWin.showFullScreen()
weather.get_weather()
w = TaryWiondw()
sys.exit(app.exec_())
#Weather.py
import requests
from PyQt5.QtCore import QObject, pyqtSignal, QTimer
gaode_weathers = ['晴', '少云', '晴间多云', '多云', '阴', '有风', '平静',
'微风','和风','清风','强风-劲风','疾风','大风','烈风','风暴','狂爆风','飓风','热带风暴','霾','中度霾','重度霾','严重霾',
'阵雨','雷阵雨','雷阵雨并伴有冰雹','小雨','中雨','大雨','暴雨','大暴雨','特大暴雨','强阵雨','强雷阵雨','极端降雨','毛毛雨-细雨',
'雨','小雨-中雨','中雨-大雨','大雨-暴雨','暴雨-大暴雨','大暴雨-特大暴雨','雨雪天气','雨夹雪','阵雨夹雪','冻雨','雪','阵雪',
'小雪','中雪','大雪','暴雪','小雪-中雪','中雪-大雪','大雪-暴雪','浮尘','扬沙','沙尘暴','强沙尘暴','龙卷风','雾','浓雾','强浓雾',
'轻雾','大雾','特强浓雾','热','冷','未知']
class Weather(QObject):
weather_info_signal = pyqtSignal(str)
def __init__(self, parent=None) -> None:
super().__init__(parent)
self.weatherTimer = QTimer()
self.weatherTimer.timeout.connect(self.get_weather)
self.weatherTimer.start(1800000)
def get_weather(self):
url = "https://restapi.amap.com/v3/ip"
params = {
'key': 'your key',
}
response = requests.get(url, params=params)
result = response.json()
city_code = result['adcode']
params = {
'key': 'your key',
'city': city_code
}
response = requests.get('https://restapi.amap.com/v3/weather/weatherInfo?parameters', params=params)
result = response.json()
# 提取所需的天气信息
if result['status'] == '1' and int(result['count']) >= 1:
weather_info = result['lives'][0]
weather_info = weather_info['weather']
if weather_info not in gaode_weathers:
self.weather_info_signal.emit('未知')
#print("天气状态:", weather_info['weather'])
else:
self.weather_info_signal.emit(weather_info)
else:
#print("无法获取到天气信息!")
self.weather_info_signal.emit('未知')
#qtWindow.py
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QMovie
import win32.win32gui
import sys
import os
class QtWindow(QMainWindow):
def __init__(self, parent=None):
super(QtWindow, self).__init__(parent)
self.setWindowFlags(Qt.FramelessWindowHint)
#self.setAttribute(Qt.WA_TranslucentBackground)
self.main_layout = QGridLayout()
self.setLayout(self.main_layout)
self.gif_label = QLabel(self)
win_hwnd = int(self.winId())
h = win32.win32gui.FindWindow(("Progman"), ("Program Manager"))
win32.win32gui.SetParent(win_hwnd, h)
def recvWeather_slot(self, weather_info):
gifpath = 'res//' + weather_info + '.gif'
bundle_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(gifpath)))
path = os.path.join(bundle_dir, gifpath)
self.startGif(path)
def startGif(self, path):
self.gif = QMovie(path)
if self.gif is not None:
self.gif_label.setMovie(self.gif)
screen = QDesktopWidget().screenGeometry()
desktop_size = screen.size()
self.gif.setScaledSize(screen.size())
self.gif_label.setGeometry(0,0,desktop_size.width(),desktop_size.height())
self.gif.start()
def stopGif(self):
self.gif.stop()
打包exe可以用pyinstaller将gif图也打包进去,具体可以参考https://blog.csdn.net/fullback555/article/details/104621530,还可以设置把命令行窗口也去掉,基本就完美了。
懒得找资源的可以从这里(https://download.csdn.net/download/ntw516/88628658)下载,只是需要申请高德平台的api-key填到key.txt里。另外,我找到的资源也不咋好,分辨率低,有的还有水印。