import
sys
import
os
import
json
from
PyQt5.QtWidgets
import
(QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QPushButton, QLabel, QSpinBox,
QComboBox, QFileDialog)
from
PyQt5.QtCore
import
QTimer, Qt
import
winreg
import
win32gui
import
win32con
import
random
from
pathlib
import
Path
from
cx_Freeze
import
setup, Executable
class
LockscreenChanger(QMainWindow):
def
__init__(
self
):
super
().__init__()
self
.setWindowTitle(
"锁屏壁纸自动更换器"
)
self
.setFixedSize(
400
,
300
)
self
.settings
=
{
'folder_path'
: '',
'interval'
:
30
,
'fit_mode'
:
'fill'
}
self
.load_settings()
self
.init_ui()
self
.setup_autostart()
self
.timer
=
QTimer()
self
.timer.timeout.connect(
self
.change_lockscreen)
self
.start_timer()
def
init_ui(
self
):
central_widget
=
QWidget()
self
.setCentralWidget(central_widget)
layout
=
QVBoxLayout(central_widget)
folder_layout
=
QHBoxLayout()
self
.folder_label
=
QLabel(
self
.settings[
'folder_path'
]
or
"未选择文件夹"
)
folder_btn
=
QPushButton(
"选择文件夹"
)
folder_btn.clicked.connect(
self
.select_folder)
folder_layout.addWidget(
self
.folder_label)
folder_layout.addWidget(folder_btn)
layout.addLayout(folder_layout)
interval_layout
=
QHBoxLayout()
interval_layout.addWidget(QLabel(
"更换间隔(秒):"
))
self
.interval_spin
=
QSpinBox()
self
.interval_spin.setRange(
5
,
3600
)
self
.interval_spin.setValue(
self
.settings[
'interval'
])
self
.interval_spin.valueChanged.connect(
self
.update_interval)
interval_layout.addWidget(
self
.interval_spin)
layout.addLayout(interval_layout)
fit_layout
=
QHBoxLayout()
fit_layout.addWidget(QLabel(
"适应模式:"
))
self
.fit_combo
=
QComboBox()
self
.fit_combo.addItems([
'填充'
,
'适应'
,
'拉伸'
,
'平铺'
,
'居中'
])
self
.fit_combo.setCurrentText(
self
.get_fit_mode_text(
self
.settings[
'fit_mode'
]))
self
.fit_combo.currentTextChanged.connect(
self
.update_fit_mode)
fit_layout.addWidget(
self
.fit_combo)
layout.addLayout(fit_layout)
self
.status_label
=
QLabel(
"程序已启动"
)
layout.addWidget(
self
.status_label)
def
select_folder(
self
):
folder
=
QFileDialog.getExistingDirectory(
self
,
"选择壁纸文件夹"
)
if
folder:
self
.settings[
'folder_path'
]
=
folder
self
.folder_label.setText(folder)
self
.save_settings()
def
update_interval(
self
, value):
self
.settings[
'interval'
]
=
value
self
.save_settings()
self
.start_timer()
def
update_fit_mode(
self
, text):
mode_map
=
{
'填充'
:
'fill'
,
'适应'
:
'fit'
,
'拉伸'
:
'stretch'
,
'平铺'
:
'tile'
,
'居中'
:
'center'
}
self
.settings[
'fit_mode'
]
=
mode_map[text]
self
.save_settings()
def
get_fit_mode_text(
self
, mode):
mode_map
=
{
'fill'
:
'填充'
,
'fit'
:
'适应'
,
'stretch'
:
'拉伸'
,
'tile'
:
'平铺'
,
'center'
:
'居中'
}
return
mode_map.get(mode,
'填充'
)
def
save_settings(
self
):
settings_path
=
Path.home()
/
'lockscreen_settings.json'
with
open
(settings_path,
'w'
, encoding
=
'utf-8'
) as f:
json.dump(
self
.settings, f)
def
load_settings(
self
):
settings_path
=
Path.home()
/
'lockscreen_settings.json'
if
settings_path.exists():
with
open
(settings_path,
'r'
, encoding
=
'utf-8'
) as f:
self
.settings.update(json.load(f))
def
setup_autostart(
self
):
app_path
=
sys.executable
key_path
=
r
'Software\Microsoft\Windows\CurrentVersion\Run'
try
:
key
=
winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path,
0
,
winreg.KEY_ALL_ACCESS)
winreg.SetValueEx(key,
'LockscreenChanger'
,
0
, winreg.REG_SZ, app_path)
winreg.CloseKey(key)
except
Exception as e:
self
.status_label.setText(f
"设置开机自启动失败: {str(e)}"
)
def
start_timer(
self
):
self
.timer.stop()
if
self
.settings[
'folder_path'
]:
self
.timer.start(
self
.settings[
'interval'
]
*
1000
)
def
change_lockscreen(
self
):
if
not
self
.settings[
'folder_path'
]:
return
valid_extensions
=
{
'.jpg'
,
'.jpeg'
,
'.png'
,
'.bmp'
}
images
=
[f
for
f
in
Path(
self
.settings[
'folder_path'
]).iterdir()
if
f.suffix.lower()
in
valid_extensions]
if
not
images:
self
.status_label.setText(
"文件夹中没有有效的图片文件"
)
return
image_path
=
str
(random.choice(images))
try
:
key
=
winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
r
'SOFTWARE\Microsoft\Windows\CurrentVersion\PersonalizationCSP'
,
0
, winreg.KEY_ALL_ACCESS)
winreg.SetValueEx(key,
'LockScreenImagePath'
,
0
, winreg.REG_SZ,
image_path)
winreg.SetValueEx(key,
'LockScreenImageUrl'
,
0
, winreg.REG_SZ,
image_path)
winreg.SetValueEx(key,
'LockScreenImageStatus'
,
0
, winreg.REG_DWORD,
1
)
self
.status_label.setText(f
"成功更换锁屏壁纸: {Path(image_path).name}"
)
except
Exception as e:
self
.status_label.setText(f
"更换壁纸失败: {str(e)}"
)
def
create_executable():
setup(
name
=
"锁屏壁纸更换器"
,
version
=
"1.0"
,
description
=
"Windows锁屏壁纸自动更换程序"
,
executables
=
[Executable(
"lockscreen_changer.py"
, base
=
"Win32GUI"
)],
options
=
{
"build_exe"
: {
"packages"
: [
"sys"
,
"os"
,
"json"
,
"PyQt5"
,
"winreg"
,
"win32gui"
,
"win32con"
,
"random"
,
"pathlib"
],
}
}
)
if
__name__
=
=
'__main__'
:
if
len
(sys.argv) >
1
and
sys.argv[
1
]
=
=
'--build'
:
create_executable()
else
:
app
=
QApplication(sys.argv)
window
=
LockscreenChanger()
window.show()
sys.exit(app.exec_())