QQ音乐歌词窗口记录/移动

张开发
2026/4/16 13:15:47 15 分钟阅读

分享文章

QQ音乐歌词窗口记录/移动
由于我的电脑接了一个小副长条屏1920*440专门用来放桌面歌词。但是很可惜QQ音乐和我这个副屏不是很兼容导致软件无法记录上一次的歌词位置每次打开QQ音乐都要重新调整一下歌词窗口的位置。痛定思痛的我借助AI写下了这段python代码用来记录/移动歌词窗口。代码import os import sys import time import json import psutil import win32gui import win32con import win32process import keyboard import ctypes import pygetwindow as gw from datetime import datetime def get_script_dir(): 获取脚本所在目录 if getattr(sys, frozen, False): return os.path.dirname(sys.executable) return os.path.dirname(os.path.abspath(__file__)) def write_log(messages, successTrue): 写入日志 script_dir get_script_dir() log_dir os.path.join(script_dir, log) os.makedirs(log_dir, exist_okTrue) log_file os.path.join(log_dir, ok.txt if success else fail.txt) timestamp datetime.now().strftime(%Y-%m-%d %H:%M:%S) log_content [] for msg in messages: log_content.append(f[{timestamp}] {msg}) with open(log_file, w, encodingutf-8) as f: f.write(\n.join(log_content)) if success: f.write(\n) def check_qqmusic_running(): 检查QQ音乐是否在运行 for proc in psutil.process_iter([name]): try: if proc.info[name] and proc.info[name].lower() qqmusic.exe: return True except (psutil.NoSuchProcess, psutil.AccessDenied): pass return False def find_lyrics_window(): 查找歌词窗口 def callback(hwnd, windows): if win32gui.IsWindowVisible(hwnd): title win32gui.GetWindowText(hwnd) if 桌面歌词 in title or DesktopLyrics in title: windows.append(hwnd) return True windows [] win32gui.EnumWindows(callback, windows) return windows[0] if windows else None def wait_for_window_stable(hwnd, timeout3.0, stable_time0.5): 等待窗口初始化完成大小稳定且非零 start_time time.time() last_rect None stable_start None while time.time() - start_time timeout: try: left, top, right, bottom win32gui.GetWindowRect(hwnd) width right - left height bottom - top # 检查窗口是否有效非零大小 if width 0 and height 0: current_rect (left, top, right, bottom) # 检查是否稳定 if current_rect last_rect: if stable_start is None: stable_start time.time() elif time.time() - stable_start stable_time: return True # 窗口已稳定 else: stable_start None last_rect current_rect else: stable_start None last_rect None except Exception: stable_start None last_rect None time.sleep(0.05) return False # 超时 def get_window_rect(hwnd): 获取窗口位置和大小 - 使用 pygetwindow 更精确 title win32gui.GetWindowText(hwnd) try: win gw.getWindowsWithTitle(title)[0] return (win.left, win.top, win.right, win.bottom) except Exception: return win32gui.GetWindowRect(hwnd) def set_window_pos(hwnd, left, top, width, height): 设置窗口位置和大小 - 使用 pygetwindow 更可靠 title win32gui.GetWindowText(hwnd) try: win gw.getWindowsWithTitle(title)[0] win.moveTo(left, top) win.resizeTo(width, height) except Exception: win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, left, top, width, height, win32con.SWP_SHOWWINDOW) def load_or_create_shortcut(): 加载或创建快捷键配置文件 script_dir get_script_dir() config_path os.path.join(script_dir, Address_and_ShortcutKeys.txt) if os.path.exists(config_path): with open(config_path, r, encodingutf-8) as f: shortcut f.read().strip() return config_path, shortcut, True default_shortcut ctrlaltw with open(config_path, w, encodingutf-8) as f: f.write(default_shortcut) return config_path, default_shortcut, False def load_or_save_position(hwnd, music_txt_path): 加载或保存窗口位置 if os.path.exists(music_txt_path): with open(music_txt_path, r, encodingutf-8) as f: pos json.load(f) return pos, True else: left, top, right, bottom get_window_rect(hwnd) pos { left: left, top: top, width: right - left, height: bottom - top } with open(music_txt_path, w, encodingutf-8) as f: json.dump(pos, f) return pos, False def run(): # 设置DPI感知 try: ctypes.windll.user32.SetProcessDPIAware() except: pass log_messages [] script_dir get_script_dir() window_opened_by_script False # 标记是否由脚本打开窗口 try: # 加载配置文件 config_path, shortcut, config_exists load_or_create_shortcut() log_messages.append(f已加载配置文件: {config_path}) # 检查QQ音乐是否运行 if not check_qqmusic_running(): log_messages.append(QQ音乐未启动请手动启动后再尝试程序退出) write_log(log_messages, successFalse) sys.exit(1) log_messages.append(QQ音乐已启动) # 查找歌词窗口 lyrics_hwnd find_lyrics_window() if lyrics_hwnd: log_messages.append(已找到歌词窗口: 桌面歌词) else: log_messages.append(未找到歌词窗口准备使用快捷键打开) window_opened_by_script True if not config_exists: log_messages.append(配置文件已创建使用默认快捷键) else: log_messages.append(配置文件已存在正在加载...) # 发送快捷键打开歌词窗口 keyboard.send(shortcut) log_messages.append(f已发送快捷键: {shortcut}) # 等待窗口出现 for i in range(50): time.sleep(0.1) lyrics_hwnd find_lyrics_window() if lyrics_hwnd: break if not lyrics_hwnd: log_messages.append(发送快捷键后仍未找到歌词窗口程序退出) write_log(log_messages, successFalse) sys.exit(1) log_messages.append(歌词窗口已通过快捷键打开) # 关键等待窗口初始化完成 log_messages.append(等待窗口初始化完成...) if wait_for_window_stable(lyrics_hwnd): log_messages.append(窗口已初始化完成) else: log_messages.append(窗口初始化超时继续执行...) # 处理music.txt music_txt_path os.path.join(script_dir, music.txt) pos, pos_exists load_or_save_position(lyrics_hwnd, music_txt_path) if pos_exists: # 恢复位置 set_window_pos(lyrics_hwnd, pos[left], pos[top], pos[width], pos[height]) log_messages.append(f已设置窗口位置: {pos}) log_messages.append(歌词窗口位置已恢复) else: # 保存当前位置 log_messages.append(f已记录当前窗口位置: {pos}) log_messages.append(歌词窗口位置已保存) log_messages.append(程序执行成功) write_log(log_messages, successTrue) except Exception as e: log_messages.append(f程序执行出错: {str(e)}) write_log(log_messages, successFalse) sys.exit(1) if __name__ __main__: run()它的执行逻辑是1.检测QQ音乐是否运行QQMusic.exe若没有运行则程序自动退出2.检测歌词窗口是否打开桌面歌词若没有打开则读取当前地址下的Address_and_ShortcutKeys.txt文件里面记录了歌词窗口打开的快捷键如果没有该文件则自动创建并写入默认快捷键“ctrlaltw”且用户后续可以自定义快捷键然后使用快捷键打开窗口3.检测当前地址下是否存在music.txt文件。如果没有则记录当前歌词窗口的位置并创建/写入music.txt文件如果有则读取之前所记录的窗口位置并将歌词窗口位置调整到之前的位置需要考虑到副屏情况4.所有操作被记录成日志程序运行成功则将日志写进当前地址下的log/ok.txt文件程序运行失败则将日志写进当前地址下的log/fail.txt文件。所有日志都以覆盖旧文本的形式写入若发生运行错误可依据最新日志直接快速定位问题经过我的测试与调整目前我的电脑上没有运行问题了文件地址结构--|当前文件夹------|运行程序.py------|Address_and_ShortcutKeys.txt------|music.txt------|log文件夹----------|ok.txt----------|fail.txt由于无法直接分享.exe文件我就不在此放置打包后的.exe程序有需要的可以自取代码自行打包程序部分库需要pip下载不会的可以拿着这段代码去问AI

更多文章