系统概述
该系统由两部分组成:
- 发送端:带有gui界面的客户端,可选择图片并发送到目标计算机
- 接收端:后台运行的服务端,接收图片并自动设置为桌面壁纸
完整代码实现
1. 发送端代码
import os
import socket
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from pil import image, imagetk
import json
class remotewallpaperclient:
def __init__(self, root):
self.root = root
self.root.title("远程壁纸设置客户端")
self.root.geometry("500x450")
self.root.resizable(false, false)
# 默认服务器端口
self.default_port = 12345
# 当前选择的图片路径
self.current_image_path = none
# 创建界面
self.create_widgets()
def create_widgets(self):
# 主框架
main_frame = ttk.frame(self.root, padding="20")
main_frame.pack(fill=tk.both, expand=true)
# 标题
title_label = ttk.label(main_frame, text="远程壁纸设置客户端",
font=("arial", 16, "bold"))
title_label.pack(pady=10)
# 目标计算机设置区域
target_frame = ttk.labelframe(main_frame, text="目标计算机设置", padding="10")
target_frame.pack(fill=tk.x, pady=10)
# ip地址输入
ip_frame = ttk.frame(target_frame)
ip_frame.pack(fill=tk.x, pady=5)
ttk.label(ip_frame, text="目标ip地址:").pack(side=tk.left)
self.ip_entry = ttk.entry(ip_frame, width=15)
self.ip_entry.pack(side=tk.left, padx=5)
self.ip_entry.insert(0, "192.168.1.")
# 端口输入
port_frame = ttk.frame(target_frame)
port_frame.pack(fill=tk.x, pady=5)
ttk.label(port_frame, text="端口:").pack(side=tk.left)
self.port_entry = ttk.entry(port_frame, width=10)
self.port_entry.pack(side=tk.left, padx=5)
self.port_entry.insert(0, str(self.default_port))
# 壁纸选择区域
wallpaper_frame = ttk.labelframe(main_frame, text="壁纸设置", padding="10")
wallpaper_frame.pack(fill=tk.x, pady=10)
# 选择壁纸按钮
select_btn = ttk.button(wallpaper_frame, text="选择壁纸图片",
command=self.select_wallpaper)
select_btn.pack(pady=5)
# 壁纸预览区域
preview_frame = ttk.frame(wallpaper_frame)
preview_frame.pack(fill=tk.x, pady=5)
self.preview_label = tk.label(preview_frame, text="未选择图片",
relief=tk.sunken, bg='white',
width=50, height=12)
self.preview_label.pack(fill=tk.both, expand=true)
# 按钮框架
btn_frame = ttk.frame(main_frame)
btn_frame.pack(pady=10)
# 发送壁纸按钮
send_btn = ttk.button(btn_frame, text="发送壁纸",
command=self.send_wallpaper)
send_btn.pack(side=tk.left, padx=5)
# 测试连接按钮
test_btn = ttk.button(btn_frame, text="测试连接",
command=self.test_connection)
test_btn.pack(side=tk.left, padx=5)
# 状态栏
self.status_var = tk.stringvar()
self.status_var.set("就绪")
status_bar = ttk.label(main_frame, textvariable=self.status_var,
relief=tk.sunken, anchor=tk.w)
status_bar.pack(fill=tk.x, side=tk.bottom)
def select_wallpaper(self):
"""选择壁纸图片"""
file_types = [
("图片文件", "*.jpg *.jpeg *.png *.bmp"),
("所有文件", "*.*")
]
file_path = filedialog.askopenfilename(
title="选择壁纸图片",
filetypes=file_types
)
if file_path:
self.current_image_path = file_path
self.preview_wallpaper(file_path)
self.status_var.set(f"已选择: {os.path.basename(file_path)}")
def preview_wallpaper(self, image_path):
"""预览壁纸"""
try:
# 打开图片
image = image.open(image_path)
# 调整图片大小以适应预览区域
preview_width = 400
preview_height = 200
image.thumbnail((preview_width, preview_height), image.resampling.lanczos)
# 转换为tkinter可用的格式
photo = imagetk.photoimage(image)
# 更新预览标签
self.preview_label.configure(image=photo, text="")
self.preview_label.image = photo # 保持引用
except exception as e:
self.preview_label.configure(image=none, text="预览加载失败")
print(f"预览图片失败: {e}")
def test_connection(self):
"""测试与目标计算机的连接"""
ip = self.ip_entry.get().strip()
port = self.port_entry.get().strip()
if not ip:
messagebox.showerror("错误", "请输入目标ip地址")
return
try:
port = int(port)
except valueerror:
messagebox.showerror("错误", "端口号必须是数字")
return
try:
# 尝试连接
sock = socket.socket(socket.af_inet, socket.sock_stream)
sock.settimeout(5) # 5秒超时
result = sock.connect_ex((ip, port))
sock.close()
if result == 0:
messagebox.showinfo("成功", f"成功连接到 {ip}:{port}")
self.status_var.set(f"已连接到 {ip}:{port}")
else:
messagebox.showerror("错误", f"无法连接到 {ip}:{port},请检查目标计算机是否运行了服务端程序")
self.status_var.set("连接失败")
except exception as e:
messagebox.showerror("错误", f"连接测试失败: {str(e)}")
self.status_var.set("连接测试失败")
def send_wallpaper(self):
"""发送壁纸到目标计算机"""
# 获取目标ip和端口
ip = self.ip_entry.get().strip()
port = self.port_entry.get().strip()
if not ip:
messagebox.showerror("错误", "请输入目标ip地址")
return
if not self.current_image_path:
messagebox.showerror("错误", "请先选择壁纸图片")
return
try:
port = int(port)
except valueerror:
messagebox.showerror("错误", "端口号必须是数字")
return
try:
# 读取图片文件
with open(self.current_image_path, 'rb') as f:
image_data = f.read()
# 获取文件名
filename = os.path.basename(self.current_image_path)
# 创建连接
sock = socket.socket(socket.af_inet, socket.sock_stream)
sock.settimeout(10) # 10秒超时
self.status_var.set(f"正在连接到 {ip}:{port}...")
sock.connect((ip, port))
# 发送文件名和文件大小
file_info = {
'filename': filename,
'filesize': len(image_data)
}
file_info_json = json.dumps(file_info).encode('utf-8')
# 先发送文件信息长度,然后发送文件信息
sock.send(len(file_info_json).to_bytes(4, byteorder='big'))
sock.send(file_info_json)
# 发送图片数据
self.status_var.set("正在发送壁纸数据...")
sock.sendall(image_data)
# 接收响应
response = sock.recv(1024).decode('utf-8')
sock.close()
if response == "success":
messagebox.showinfo("成功", f"壁纸已成功发送到 {ip}")
self.status_var.set(f"壁纸已发送到 {ip}")
else:
messagebox.showerror("错误", f"设置壁纸失败: {response}")
self.status_var.set("设置壁纸失败")
except exception as e:
messagebox.showerror("错误", f"发送壁纸失败: {str(e)}")
self.status_var.set("发送失败")
def main():
# 检查依赖
try:
from pil import image
except importerror:
print("请先安装 pillow 库: pip install pillow")
return
# 创建主窗口
root = tk.tk()
app = remotewallpaperclient(root)
# 启动主循环
root.mainloop()
if __name__ == "__main__":
main()
2. 接收端代码
import os
import socket
import threading
import ctypes
import json
import tempfile
class wallpaperserver:
def __init__(self, port=12345):
self.port = port
self.host = '0.0.0.0' # 监听所有接口
self.running = false
self.server_socket = none
def start(self):
"""启动服务器"""
try:
self.server_socket = socket.socket(socket.af_inet, socket.sock_stream)
self.server_socket.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1)
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(5)
self.running = true
print(f"壁纸服务器已启动,监听端口 {self.port}")
print("等待客户端连接...")
while self.running:
try:
client_socket, addr = self.server_socket.accept()
print(f"接收到来自 {addr} 的连接")
# 为每个客户端创建新线程
client_thread = threading.thread(
target=self.handle_client,
args=(client_socket, addr)
)
client_thread.daemon = true
client_thread.start()
except exception as e:
if self.running:
print(f"接受连接时出错: {e}")
except exception as e:
print(f"启动服务器失败: {e}")
def handle_client(self, client_socket, addr):
"""处理客户端连接"""
try:
# 接收文件信息长度
file_info_len = int.from_bytes(client_socket.recv(4), byteorder='big')
# 接收文件信息
file_info_json = client_socket.recv(file_info_len).decode('utf-8')
file_info = json.loads(file_info_json)
filename = file_info['filename']
filesize = file_info['filesize']
print(f"接收文件: {filename}, 大小: {filesize} 字节")
# 接收文件数据
received_data = b''
while len(received_data) < filesize:
chunk = client_socket.recv(min(4096, filesize - len(received_data)))
if not chunk:
break
received_data += chunk
# 保存文件到临时目录
temp_dir = tempfile.gettempdir()
temp_file_path = os.path.join(temp_dir, filename)
with open(temp_file_path, 'wb') as f:
f.write(received_data)
print(f"文件已保存到: {temp_file_path}")
# 设置壁纸
if self.set_windows_wallpaper(temp_file_path):
print("壁纸设置成功")
client_socket.send("success".encode('utf-8'))
else:
print("壁纸设置失败")
client_socket.send("failed: 无法设置壁纸".encode('utf-8'))
except exception as e:
print(f"处理客户端请求时出错: {e}")
try:
client_socket.send(f"failed: {str(e)}".encode('utf-8'))
except:
pass
finally:
client_socket.close()
def set_windows_wallpaper(self, image_path):
"""设置windows壁纸"""
try:
# 转换为绝对路径
abs_path = os.path.abspath(image_path)
# windows api 常量
spi_setdeskwallpaper = 20
spif_updateinifile = 0x01
spif_sendwininichange = 0x02
# 设置壁纸
result = ctypes.windll.user32.systemparametersinfow(
spi_setdeskwallpaper,
0,
abs_path,
spif_updateinifile | spif_sendwininichange
)
return bool(result)
except exception as e:
print(f"设置壁纸失败: {e}")
return false
def stop(self):
"""停止服务器"""
self.running = false
if self.server_socket:
self.server_socket.close()
print("壁纸服务器已停止")
def main():
# 检查操作系统
if os.name != 'nt':
print("此程序仅支持windows系统")
return
# 创建并启动服务器
server = wallpaperserver(port=12345)
try:
server.start()
except keyboardinterrupt:
print("\n正在停止服务器...")
server.stop()
if __name__ == "__main__":
main()
系统效果展示
发送端界面

发送端提供直观的gui界面,包含以下功能区域:
目标计算机设置
- ip地址输入框(默认192.168.1.)
- 端口输入框(默认12345)
壁纸设置
- 选择壁纸图片按钮
- 图片预览区域
- 支持jpg、jpeg、png、bmp格式
操作按钮
- 发送壁纸按钮
- 测试连接按钮
- 实时状态显示栏
接收端运行效果
接收端在后台运行,控制台显示如下状态信息:
壁纸服务器已启动,监听端口 12345 等待客户端连接... 接收到来自 192.168.1.100 的连接 接收文件: wallpaper.jpg, 大小: 2048576 字节 文件已保存到: c:\users\username\appdata\local\temp\wallpaper.jpg 壁纸设置成功
壁纸设置效果

使用说明
安装依赖
在运行程序前,需要安装必要的python库:
pip install pillow
使用步骤
启动接收端:
- 在目标计算机上运行接收端程序
- 程序将在后台监听指定端口(默认12345)
- 仅支持windows系统
配置发送端:
- 运行发送端程序
- 输入目标计算机的ip地址
- 确保端口号与接收端一致
选择壁纸:
- 点击"选择壁纸图片"按钮
- 从本地选择图片文件
- 预览区域将显示缩略图
发送壁纸:
- 可先点击"测试连接"验证网络连通性
- 点击"发送壁纸"开始传输
- 状态栏显示发送进度和结果
技术特点
网络通信
- tcp协议:使用可靠的tcp连接传输文件
- 多线程处理:服务端为每个客户端连接创建独立线程
- json数据格式:使用json传输文件元信息
- 大文件支持:分块传输,支持大尺寸图片
文件处理
- 格式支持:支持常见图片格式(jpg、png、bmp等)
- 预览功能:发送端提供图片预览
- 临时存储:接收端将文件保存在临时目录
- 路径处理:自动处理绝对路径和相对路径
windows集成
- 系统api:使用windows api设置壁纸
- 即时生效:壁纸设置后立即应用
- 兼容性:支持各种分辨率和图片比例
应用场景
企业环境
- 统一壁纸:为办公电脑设置统一的公司壁纸
- 活动宣传:推送活动主题壁纸
- 安全提醒:设置安全提示壁纸
教育场景
- 教室管理:为机房电脑统一设置壁纸
- 课程主题:根据课程内容推送相关壁纸
家庭使用
- 多设备同步:为家中多台电脑设置相同壁纸
- 节日主题:根据节日推送相应主题壁纸
个人使用
- 远程管理:远程为自己的其他设备更换壁纸
- 自动轮换:结合脚本实现自动壁纸轮换
安全考虑
- 网络隔离:建议在内部网络使用,或配置防火墙规则
- 身份验证:生产环境可添加简单的密码验证
- 文件验证:可添加文件类型和大小检查
- 访问控制:可限制允许连接的ip地址范围
扩展功能
系统可以进一步扩展以下功能:
- 批量发送到多个目标
- 壁纸定时自动更换
- 壁纸历史记录和回滚
- 支持更多图片格式和特效
- 添加用户认证机制
这个远程壁纸设置系统展示了如何使用python的socket编程和windows api实现实用的系统集成功能。代码结构清晰,易于理解和扩展,为跨设备文件传输和系统设置提供了很好的参考实现。
以上就是使用python实现一个远程壁纸设置系统的详细内容,更多关于python远程壁纸设置的资料请关注代码网其它相关文章!
发表评论