完成0.01版本

This commit is contained in:
2026-04-05 22:43:43 +08:00
parent 104dfe9693
commit 77f718cca6
10 changed files with 268 additions and 110 deletions
+20 -11
View File
@@ -1,4 +1,5 @@
import sys
import os
import time
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication
@@ -8,6 +9,17 @@ from ui.ball import FloatBall, BALL_SIZE
import ui.theme as theme
from db import database
__VERSION__ = "0.0.1"
# ===================== 打包兼容核心函数 =====================
def get_resource_path(relative_path):
"""
打包 EXE 后获取资源路径,开发环境也能用
"""
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS, relative_path)
return os.path.join(os.path.abspath("."), relative_path)
# ==========================================================
def _wake_existing_or_exit() -> bool:
"""
@@ -22,7 +34,7 @@ def _wake_existing_or_exit() -> bool:
import ctypes.wintypes
mutex_name = r"Global\CleanDesktopOrganizerSingleton"
title = "牛马软件柜"
title = "牛马软件柜 v" + __VERSION__
kernel32 = ctypes.windll.kernel32
user32 = ctypes.windll.user32
@@ -34,16 +46,14 @@ def _wake_existing_or_exit() -> bool:
last_err = kernel32.GetLastError()
if last_err == ERROR_ALREADY_EXISTS:
# 轮询一小段时间,避免首次窗口尚未创建
hwnd = None
for _ in range(8): # ~2.4s
for _ in range(8):
hwnd = user32.FindWindowW(None, title)
if hwnd:
break
time.sleep(0.3)
if hwnd:
# SW_SHOW = 5
user32.ShowWindow(hwnd, 5)
user32.SetForegroundWindow(hwnd)
return False
@@ -52,42 +62,41 @@ def _wake_existing_or_exit() -> bool:
def main():
# 必须在创建 QApplication 之前:不按各显示器缩放,逻辑像素固定(跨分辨率/跨屏拖动宽高保持一致)
if not _wake_existing_or_exit():
return
QApplication.setAttribute(Qt.ApplicationAttribute.AA_Use96Dpi, True)
# 这个策略同样要求在创建 QApplication 前设置
try:
QApplication.setHighDpiScaleFactorRoundingPolicy(
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough
)
except Exception:
pass
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
init_db()
theme.load() # 从数据库读取上次主题
theme.load()
_set_autostart(True)
panel = PanelWindow()
ball = FloatBall()
panel._ball_ref = ball
panel._apply_pin_window_layer()
ball.clicked.connect(lambda: panel.show_near(ball.pos(), BALL_SIZE))
ball.right_clicked.connect(lambda pos: panel.tray.contextMenu().exec(pos))
# 判断是否有保存的位置:有则直接在原位显示,没有则用悬浮球旁边
has_saved = bool(database.get_setting("panel_x", ""))
if has_saved:
# _restore_geometry 已在 PanelWindow.__init__ 里执行,直接 show
panel.setWindowOpacity(0)
panel.show()
panel.raise_()
if hasattr(panel, "_ball_ref"):
panel._ball_ref.hide()
# 淡入
from PyQt6.QtCore import QPropertyAnimation
anim = QPropertyAnimation(panel, b"windowOpacity")
anim.setDuration(180)
@@ -103,4 +112,4 @@ def main():
if __name__ == "__main__":
main()
main()