以下是一个实现上述要求的 Python 代码示例:

import tkinter as tk
from PIL import Image, ImageTk
import threading
import time
import sys
from tkinter import messagebox
import win32api
import win32con
import win32gui
from ctypes import windll
import os

class CarMoveThread(threading.Thread):
    def __init__(self, canvas, car_image, speed):
        threading.Thread.__init__(self)
        self.canvas = canvas
        self.car_image = car_image
        self.speed = speed
        self.is_running = True

    def run(self):
        x = 0
        y = 0
        while self.is_running and x < self.canvas.winfo_width() and y < self.canvas.winfo_height():
            self.canvas.delete('car')
            self.canvas.create_image(x, y, image=self.car_image, anchor=tk.NW, tags='car')
            x += self.speed
            y += self.speed
            time.sleep(0.01)

    def stop(self):
        self.is_running = False

class CarWindow(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title('Car Move')
        self.geometry('400x300')
        self.protocol('WM_DELETE_WINDOW', self.on_close)
        self.iconbitmap('car_icon.ico')  # 设置程序图标
        self.tray_icon = None
        self.tray_menu = None

        self.canvas = tk.Canvas(self, width=400, height=300)
        self.canvas.pack()

        self.car_image = ImageTk.PhotoImage(Image.open('car_image.png').convert('RGBA'))  # 载入小车图片
        self.car_thread = CarMoveThread(self.canvas, self.car_image, 2)  # 默认速度为2

        self.menu = tk.Menu(self, tearoff=0)
        self.menu.add_command(label='恢复', command=self.restore)
        self.menu.add_command(label='退出', command=self.exit)
        self.bind('<Button-3>', self.show_menu)

        self.tray_icon = self.create_tray_icon()
        self.tray_menu = self.create_tray_menu()

    def on_close(self):
        self.withdraw()
        self.iconify()

    def restore(self):
        self.deiconify()
        self.tray_icon.destroy()
        self.tray_menu.destroy()

    def exit(self):
        self.car_thread.stop()
        self.quit()

    def show_menu(self, event):
        self.menu.post(event.x_root, event.y_root)

    def create_tray_icon(self):
        icon_path = os.path.abspath('car_icon.ico')
        hwnd = self.winfo_id()
        taskbar_icon_flags = win32con.NIF_ICON | win32con.NIF_MESSAGE | win32con.NIF_TIP
        taskbar_icon = (
            hwnd,
            0,
            win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
            win32con.WM_USER + 20,
            win32gui.LoadIcon(win32gui.GetModuleHandle(None), icon_path),
            'Car Move',
        )
        win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, taskbar_icon)
        return taskbar_icon

    def create_tray_menu(self):
        menu = win32gui.CreatePopupMenu()
        win32gui.AppendMenu(menu, win32con.MF_STRING, 1023, '恢复')
        win32gui.AppendMenu(menu, win32con.MF_STRING, 1024, '退出')
        win32gui.SetMenuDefaultItem(menu, 1023)
        win32gui.SetForegroundWindow(self.winfo_id())
        win32gui.TrackPopupMenu(
            menu,
            win32con.TPM_LEFTALIGN | win32con.TPM_LEFTBUTTON,
            win32api.GetCursorPos()[0],
            win32api.GetCursorPos()[1],
            0,
            self.winfo_id(),
            None,
        )
        win32gui.PostMessage(self.winfo_id(), win32con.WM_NULL, 0, 0)

        return menu

if __name__ == '__main__':
    # 设置程序图标
    myappid = 'my_car_move'
    windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

    app = CarWindow()
    app.car_thread.start()
    app.mainloop()

请确保在运行代码前已安装tkinterPIL库,并将小车图片保存为'car_image.png',将程序图标保存为'car_icon.ico',与代码文件放在同一目录下。

此代码使用tkinter库创建窗口并绘制小车,使用PIL库载入小车图片,并使用多线程实现小车的匀速移动。通过右键点击窗口或托盘区图标,可以弹出菜单进行操作。点击关闭按钮后,程序会转入后台执行,并在任务栏托盘区显示程序图标。右键点击托盘区图标,可以选择恢复程序运行或退出程序。

Python 小车动画:窗口移动、速度控制、托盘菜单

原文地址: https://www.cveoy.top/t/topic/bemO 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录