import
ctypes
import
os
import
random
import
sys
import
time
from
PyQt5.QtCore
import
Qt, QTimer, QPoint, QByteArray
from
PyQt5.QtGui
import
QPainter, QColor, QPixmap, QCursor
from
PyQt5.QtWidgets
import
QApplication, QWidget
def
add_to_startup():
try
:
import
winshell
from
win32com.client
import
Dispatch
except
ImportError:
print
(
"请安装依赖库:pip install pywin32 winshell"
)
return
startup_folder
=
winshell.startup()
print
(
"添加到启动项:"
, startup_folder)
shortcut_path
=
os.path.join(startup_folder,
"小朋友.lnk"
)
if
not
os.path.exists(shortcut_path):
shell
=
Dispatch(
'WScript.Shell'
)
shortcut
=
shell.CreateShortCut(shortcut_path)
if
getattr
(sys,
'frozen'
,
False
):
executable_path
=
sys.executable
else
:
executable_path
=
os.path.abspath(__file__)
shortcut.Targetpath
=
executable_path
shortcut.Arguments
=
''
shortcut.WorkingDirectory
=
os.path.dirname(executable_path)
shortcut.save()
print
(
"已添加到开机启动项"
)
else
:
print
(
"已存在开机启动项"
)
def
get_desktop_window():
progman
=
ctypes.windll.user32.FindWindowW(
'ProgMan'
,
None
)
ctypes.windll.user32.SendMessageW(progman,
0x052C
,
0
,
0
)
hwnd
=
ctypes.windll.user32.FindWindowExW(
None
,
None
,
'WorkerW'
,
None
)
while
hwnd:
shell_view
=
ctypes.windll.user32.FindWindowExW(hwnd,
None
,
'SHELLDLL_DefView'
,
None
)
if
shell_view:
return
hwnd
hwnd
=
ctypes.windll.user32.FindWindowExW(
None
, hwnd,
'WorkerW'
,
None
)
return
None
class
Snowflake:
def
__init__(
self
, max_width, max_height):
self
.x
=
random.randint(
0
, max_width)
self
.y
=
random.randint(
-
max_height,
0
)
self
.vx
=
random.uniform(
-
1
,
1
)
self
.vy
=
random.uniform(
0.5
,
1.5
)
self
.radius
=
random.randint(
5
,
10
)
self
.color
=
QColor(
255
,
255
,
255
,
200
)
self
.pixmap
=
QPixmap(
"素材.png"
)
self
.pixmap
=
self
.pixmap.scaled(
self
.radius
*
2
,
self
.radius
*
2
, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def
move(
self
, max_width, max_height, mouse_pos
=
None
):
if
mouse_pos:
mouse_x, mouse_y
=
mouse_pos
distance
=
((
self
.x
-
mouse_x)
*
*
2
+
(
self
.y
-
mouse_y)
*
*
2
)
*
*
0.5
if
distance <
100
:
self
.vx
=
(
self
.x
-
mouse_x)
*
0.2
self
.vy
=
-
(
self
.y
-
mouse_y)
*
0.2
self
.x
+
=
self
.vx
*
3
self
.y
+
=
self
.vy
*
3
else
:
self
.x
+
=
self
.vx
self
.y
+
=
self
.vy
else
:
self
.x
+
=
self
.vx
self
.y
+
=
self
.vy
if
self
.y >
=
max_height
or
self
.x <
0
or
self
.x > max_width:
return
False
return
True
def
draw(
self
, painter):
painter.drawPixmap(QPoint(
int
(
self
.x
-
self
.radius),
int
(
self
.y
-
self
.radius)),
self
.pixmap)
class
DynamicWallpaper(QWidget):
def
__init__(
self
):
super
().__init__()
self
.broom_pixmap_list
=
[
QPixmap(os.path.join(
"img"
, f)).scaled(
100
,
100
, Qt.KeepAspectRatio, Qt.SmoothTransformation)
for
f
in
sorted
(
[f
for
f
in
os.listdir(
"img"
)
if
f.endswith(
".png"
)],
key
=
lambda
x:
int
(os.path.splitext(x)[
0
])
)
]
self
.current_broom_index
=
0
self
.broom_timer
=
QTimer(
self
)
self
.broom_effect_duration
=
6000
self
.last_collision_time
=
0
self
.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowTransparentForInput)
self
.setAttribute(Qt.WA_TranslucentBackground)
self
.setGeometry(
0
,
0
, QApplication.desktop().screenGeometry().width(),
QApplication.desktop().screenGeometry().height())
self
.snowflakes
=
[Snowflake(
self
.width(),
self
.height())
for
_
in
range
(
50
)]
self
.timer
=
QTimer(
self
)
self
.timer.timeout.connect(
self
.update_snowflakes)
self
.timer.start(
30
)
self
.snow_timer
=
QTimer(
self
)
self
.snow_timer.timeout.connect(
self
.adjust_snow_amount)
self
.snow_timer.start(
60000
)
self
.snow_state
=
0
desktop_hwnd
=
get_desktop_window()
if
desktop_hwnd:
self
.winId()
ctypes.windll.user32.SetParent(
int
(
self
.windowHandle().winId()), desktop_hwnd)
self
.mouse_pos
=
None
self
.broom_pixmap
=
QPixmap("")
self
.broom_pixmap
=
self
.broom_pixmap.scaled(
100
,
100
, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def
start_random_broom_switch(
self
):
current_time
=
self
.get_current_time()
if
current_time
-
self
.last_collision_time >
self
.broom_effect_duration:
return
next_delay
=
random.randint(
150
,
250
)
QTimer.singleShot(next_delay,
self
.random_switch_broom)
def
random_switch_broom(
self
):
current_time
=
self
.get_current_time()
if
current_time
-
self
.last_collision_time >
self
.broom_effect_duration:
return
self
.current_broom_index
=
random.randint(
0
,
len
(
self
.broom_pixmap_list)
-
1
)
self
.update()
self
.start_random_broom_switch()
def
get_current_time(
self
):
return
int
(time.time()
*
1000
)
def
adjust_snow_amount(
self
):
if
self
.snow_state
=
=
0
:
self
.snowflakes.extend([Snowflake(
self
.width(),
self
.height())
for
_
in
range
(
50
)])
self
.snow_state
=
1
elif
self
.snow_state
=
=
1
:
self
.snowflakes.extend([Snowflake(
self
.width(),
self
.height())
for
_
in
range
(
100
)])
self
.snow_state
=
2
elif
self
.snow_state
=
=
2
:
self
.snowflakes
=
self
.snowflakes[:
150
]
self
.snow_state
=
3
elif
self
.snow_state
=
=
3
:
self
.snowflakes
=
self
.snowflakes[:
100
]
self
.snow_state
=
4
elif
self
.snow_state
=
=
4
:
self
.snowflakes
=
self
.snowflakes[:
50
]
self
.snow_state
=
0
def
update_snowflakes(
self
):
for
flake
in
self
.snowflakes[:]:
if
not
flake.move(
self
.width(),
self
.height(),
self
.mouse_pos):
self
.snowflakes.remove(flake)
self
.snowflakes.append(Snowflake(
self
.width(),
self
.height()))
self
.update()
def
paintEvent(
self
, event):
painter
=
QPainter(
self
)
painter.setRenderHint(QPainter.Antialiasing)
mouse_pos
=
QCursor.pos()
mouse_pos
=
self
.mapFromGlobal(mouse_pos)
current_broom
=
self
.broom_pixmap_list[
self
.current_broom_index]
painter.drawPixmap(
mouse_pos.x()
-
current_broom.width()
/
/
2
+
40
,
mouse_pos.y()
+
20
,
current_broom
)
for
flake
in
self
.snowflakes:
distance
=
((flake.x
-
mouse_pos.x())
*
*
2
+
(flake.y
-
mouse_pos.y())
*
*
2
)
*
*
0.5
if
distance <
60
:
flake.vx
=
(flake.x
-
mouse_pos.x())
*
0.2
flake.vy
=
-
(flake.y
-
mouse_pos.y())
*
0.2
flake.x
+
=
flake.vx
*
3
flake.y
+
=
flake.vy
*
3
flake.color.setAlpha(
255
)
current_time
=
self
.get_current_time()
if
current_time
-
self
.last_collision_time >
self
.broom_effect_duration:
self
.last_collision_time
=
current_time
self
.start_random_broom_switch()
else
:
flake.color.setAlpha(
200
)
flake.draw(painter)
painter.drawPixmap(
mouse_pos.x()
-
self
.broom_pixmap.width()
/
/
2
+
40
,
mouse_pos.y()
+
20
,
self
.broom_pixmap
)
def
mouseMoveEvent(
self
, event):
self
.mouse_pos
=
(event.x(), event.y())
if
__name__
=
=
'__main__'
:
add_to_startup()
mutex
=
ctypes.windll.kernel32.CreateMutexW(
None
,
True
,
"Local/SnowfallProgramMutex"
)
if
ctypes.windll.kernel32.GetLastError()
=
=
0x00000010
:
print
(
"检测到程序已在运行,即将退出..."
)
sys.exit(
-
1
)
app
=
QApplication(sys.argv)
w
=
DynamicWallpaper()
w.show()
sys.exit(app.exec_())