使用Python實現(xiàn)一個遠程壁紙設置系統(tǒng)
系統(tǒng)概述
該系統(tǒng)由兩部分組成:
- 發(fā)送端:帶有GUI界面的客戶端,可選擇圖片并發(fā)送到目標計算機
- 接收端:后臺運行的服務端,接收圖片并自動設置為桌面壁紙
完整代碼實現(xiàn)
1. 發(fā)送端代碼
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
# 創(chuàng)建界面
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)
# 目標計算機設置區(qū)域
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))
# 壁紙選擇區(qū)域
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)
# 壁紙預覽區(qū)域
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)
# 發(fā)送壁紙按鈕
send_btn = ttk.Button(btn_frame, text="發(fā)送壁紙",
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)
# 狀態(tài)欄
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)
# 調整圖片大小以適應預覽區(qū)域
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("錯誤", "端口號必須是數(shù)字")
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):
"""發(fā)送壁紙到目標計算機"""
# 獲取目標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("錯誤", "端口號必須是數(shù)字")
return
try:
# 讀取圖片文件
with open(self.current_image_path, 'rb') as f:
image_data = f.read()
# 獲取文件名
filename = os.path.basename(self.current_image_path)
# 創(chuàng)建連接
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10) # 10秒超時
self.status_var.set(f"正在連接到 {ip}:{port}...")
sock.connect((ip, port))
# 發(fā)送文件名和文件大小
file_info = {
'filename': filename,
'filesize': len(image_data)
}
file_info_json = json.dumps(file_info).encode('utf-8')
# 先發(fā)送文件信息長度,然后發(fā)送文件信息
sock.send(len(file_info_json).to_bytes(4, byteorder='big'))
sock.send(file_info_json)
# 發(fā)送圖片數(shù)據(jù)
self.status_var.set("正在發(fā)送壁紙數(shù)據(jù)...")
sock.sendall(image_data)
# 接收響應
response = sock.recv(1024).decode('utf-8')
sock.close()
if response == "SUCCESS":
messagebox.showinfo("成功", f"壁紙已成功發(fā)送到 {ip}")
self.status_var.set(f"壁紙已發(fā)送到 {ip}")
else:
messagebox.showerror("錯誤", f"設置壁紙失敗: {response}")
self.status_var.set("設置壁紙失敗")
except Exception as e:
messagebox.showerror("錯誤", f"發(fā)送壁紙失敗: {str(e)}")
self.status_var.set("發(fā)送失敗")
def main():
# 檢查依賴
try:
from PIL import Image
except ImportError:
print("請先安裝 Pillow 庫: pip install Pillow")
return
# 創(chuàng)建主窗口
root = tk.Tk()
app = RemoteWallpaperClient(root)
# 啟動主循環(huán)
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' # 監(jiān)聽所有接口
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"壁紙服務器已啟動,監(jiān)聽端口 {self.port}")
print("等待客戶端連接...")
while self.running:
try:
client_socket, addr = self.server_socket.accept()
print(f"接收到來自 {addr} 的連接")
# 為每個客戶端創(chuàng)建新線程
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} 字節(jié)")
# 接收文件數(shù)據(jù)
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():
# 檢查操作系統(tǒng)
if os.name != 'nt':
print("此程序僅支持Windows系統(tǒng)")
return
# 創(chuàng)建并啟動服務器
server = WallpaperServer(port=12345)
try:
server.start()
except KeyboardInterrupt:
print("\n正在停止服務器...")
server.stop()
if __name__ == "__main__":
main()
系統(tǒng)效果展示
發(fā)送端界面

發(fā)送端提供直觀的GUI界面,包含以下功能區(qū)域:
目標計算機設置
- IP地址輸入框(默認192.168.1.)
- 端口輸入框(默認12345)
壁紙設置
- 選擇壁紙圖片按鈕
- 圖片預覽區(qū)域
- 支持JPG、JPEG、PNG、BMP格式
操作按鈕
- 發(fā)送壁紙按鈕
- 測試連接按鈕
- 實時狀態(tài)顯示欄
接收端運行效果
接收端在后臺運行,控制臺顯示如下狀態(tài)信息:
壁紙服務器已啟動,監(jiān)聽端口 12345 等待客戶端連接... 接收到來自 192.168.1.100 的連接 接收文件: wallpaper.jpg, 大小: 2048576 字節(jié) 文件已保存到: C:\Users\Username\AppData\Local\Temp\wallpaper.jpg 壁紙設置成功
壁紙設置效果

使用說明
安裝依賴
在運行程序前,需要安裝必要的Python庫:
pip install Pillow
使用步驟
啟動接收端:
- 在目標計算機上運行接收端程序
- 程序將在后臺監(jiān)聽指定端口(默認12345)
- 僅支持Windows系統(tǒng)
配置發(fā)送端:
- 運行發(fā)送端程序
- 輸入目標計算機的IP地址
- 確保端口號與接收端一致
選擇壁紙:
- 點擊"選擇壁紙圖片"按鈕
- 從本地選擇圖片文件
- 預覽區(qū)域將顯示縮略圖
發(fā)送壁紙:
- 可先點擊"測試連接"驗證網(wǎng)絡連通性
- 點擊"發(fā)送壁紙"開始傳輸
- 狀態(tài)欄顯示發(fā)送進度和結果
技術特點
網(wǎng)絡通信
- TCP協(xié)議:使用可靠的TCP連接傳輸文件
- 多線程處理:服務端為每個客戶端連接創(chuàng)建獨立線程
- JSON數(shù)據(jù)格式:使用JSON傳輸文件元信息
- 大文件支持:分塊傳輸,支持大尺寸圖片
文件處理
- 格式支持:支持常見圖片格式(JPG、PNG、BMP等)
- 預覽功能:發(fā)送端提供圖片預覽
- 臨時存儲:接收端將文件保存在臨時目錄
- 路徑處理:自動處理絕對路徑和相對路徑
Windows集成
- 系統(tǒng)API:使用Windows API設置壁紙
- 即時生效:壁紙設置后立即應用
- 兼容性:支持各種分辨率和圖片比例
應用場景
企業(yè)環(huán)境
- 統(tǒng)一壁紙:為辦公電腦設置統(tǒng)一的公司壁紙
- 活動宣傳:推送活動主題壁紙
- 安全提醒:設置安全提示壁紙
教育場景
- 教室管理:為機房電腦統(tǒng)一設置壁紙
- 課程主題:根據(jù)課程內容推送相關壁紙
家庭使用
- 多設備同步:為家中多臺電腦設置相同壁紙
- 節(jié)日主題:根據(jù)節(jié)日推送相應主題壁紙
個人使用
- 遠程管理:遠程為自己的其他設備更換壁紙
- 自動輪換:結合腳本實現(xiàn)自動壁紙輪換
安全考慮
- 網(wǎng)絡隔離:建議在內部網(wǎng)絡使用,或配置防火墻規(guī)則
- 身份驗證:生產環(huán)境可添加簡單的密碼驗證
- 文件驗證:可添加文件類型和大小檢查
- 訪問控制:可限制允許連接的IP地址范圍
擴展功能
系統(tǒng)可以進一步擴展以下功能:
- 批量發(fā)送到多個目標
- 壁紙定時自動更換
- 壁紙歷史記錄和回滾
- 支持更多圖片格式和特效
- 添加用戶認證機制
這個遠程壁紙設置系統(tǒng)展示了如何使用Python的socket編程和Windows API實現(xiàn)實用的系統(tǒng)集成功能。代碼結構清晰,易于理解和擴展,為跨設備文件傳輸和系統(tǒng)設置提供了很好的參考實現(xiàn)。
以上就是使用Python實現(xiàn)一個遠程壁紙設置系統(tǒng)的詳細內容,更多關于Python遠程壁紙設置的資料請關注腳本之家其它相關文章!
相關文章
NumPy實現(xiàn)廣播機制與廣播規(guī)則的示例
NumPy中的廣播機制,這是一種允許不同形狀數(shù)組之間進行逐元素運算的技術,本文就來詳細的介紹一下NumPy實現(xiàn)廣播機制與廣播規(guī)則的示例,感興趣的可以了解一下2026-05-05
Pycharm配置opencv與numpy的實現(xiàn)
本文總結了兩種方法來導入opencv與numpy包,第一種是直接在Pycharm中導入兩個包,第二種是在官網(wǎng)下載相關文件進行配置,感興趣的小伙伴們可以參考一下2021-07-07
使用jupyter notebook運行python和R的步驟
這篇文章主要介紹了使用jupyter notebook運行python和R的步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08

