python实现一个浮动窗口随机显示四级单词在桌面跑来跑去

实现一个浮动窗体随机显示四级单词在windows桌面置顶移动

tkinter库来创建窗口和显示单词,以及random库来随机选择单词。 使用after方法来定时更新窗口的位置,实现单词窗口的慢慢移动效果

使用pandas读取Excel文件,并将每行的单词和释义对应关系存储在一个字典中

实现鼠标悬停时显示对应的解释,或者直接显示对应解释FloatingWordWindow类中添加一个标签来显示解释,并在鼠标进入标签时更新解释内容

鼠标悬停的时候显示对应的解释,也就是对应键的值 不悬停的时候,不显示解释,返回显示随机单词 wraplength是自动换行

使用虚拟环境执行 E:\pycharm\anaconda\python.exe vocabulary.py

后台执行 E:\pycharm\anaconda\python.exe vocabulary.py & win不可用 在Linux或Mac系统下,你可以使用&符号

在Windows系统下,你可以使用start命令来启动一个新的窗口并在其中运行脚本,然后关闭该窗口,脚本将在后台继续执行。例如:

start /B E:\pycharm\anaconda\python.exe vocabulary.py 也不行

powershell可以

 cd "E:\pythonProject\other"
Start-Process -FilePath "E:\pycharm\anaconda\python.exe" -ArgumentList "vocabulary.py" -WindowStyle Hidden

Powershell 编写和运行脚本 后缀.ps1

一个Powershell仅仅是一个包含Powershell代码的文本文件。如果这个文本文件执行,Powershell解释器会逐行解释并执行它的的语句。Powershell脚本非常像以前CMD控制台上的批处理文件。您可以通过非常简单的文本编辑工具创建Powershell脚本。

通过重定向创建脚本

如果您的脚本不是很长,您甚至可以直接在控制台中要执行的语句重定向给一个脚本文件。

PS E:> '"Hello,Powershell Script"' > MyScript.ps1
PS E:> .\MyScript.ps1
Hello,Powershell Script

这样有个缺点,就是您的代码必须放在闭合的引号中。这样的书写方式一旦在脚本内部也有引号时,是一件很痛苦的事。甚至您还可能希望在脚本中换行。下面的Here-strings例子不错,也就是将脚本文件通过@‘ ’@闭合起来。

PS E:> @'
>> Get-Date
>> $Env:CommonProgramFiles
>> #Script End
>> "files count"
>> (ls).Count
>> #Script Really End
>>
>> '@ > myscript.ps1
>>
PS E:> .MyScript.ps1

2012年4月27日 8:15:10
C:\Program Files\Common Files
files count
20

Here-String以 @‘开头,以’@结束.任何文本都可以存放在里面,哪怕是一些特殊字符,空号,白空格。但是如果您不小心将单引号写成了双引号,Powershell将会把里面的变量进行解析。

通过编辑器创建脚本

其实非常方便的还是最地道的文版编辑器Notepad,您可以直接在Powershell控制台中打开Notepad

PS E:> notepad.exe .\MyScript.ps1
PS E:> notepad.exe

编辑完记得保存即可。

运行Powershell脚本

当您的脚本编写成功后您可能第一次会像下面的方式运行它,也就是只输入脚本的文件名,会报错。

PS E:> MyScript.ps1
无法将“MyScript.ps1”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括
路径,请确保路径正确,然后重试。
所在位置 行:1 字符: 13
+ MyScript.ps1 < <<<
    + CategoryInfo          : ObjectNotFound: (MyScript.ps1:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Suggestion [3,General]: 未找到命令 MyScript.ps1,但它确实存在于当前位置。Windows PowerShell 默认情况
下不从当前位置加载命令。如果信任此命令,请改为键入 ".MyScript.ps1"。有关更多详细信息,请参阅 "get-h
elp about_Command_Precedence"。

除非您使用相对路径,或者绝对路径

PS E:> .\MyScript.ps1

2012年4月27日 8:33:03
C:\Program Files\Common Files
files count
20

PS E:> E:MyScript.ps1

2012年4月27日 8:33:11
C:\Program Files\Common Files
files count
20

执行策略限制

Powershell一般初始化情况下都会禁止脚本执行。脚本能否执行取决于Powershell的执行策略。

PS E:> .\MyScript.ps1
无法加载文件 E:MyScript.ps1,因为在此系统中禁止执行脚本。有关详细信息,请参阅 "get-help about_sign
ing"。
所在位置 行:1 字符: 15
+ .MyScript.ps1 < <<<
    + CategoryInfo          : NotSpecified: (:) [], PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

只有管理员才有权限更改这个策略。非管理员会报错。

查看脚本执行策略,可以通过:

PS E:> Get-ExecutionPolicy

更改脚本执行策略,可以通过

PS E:> Get-ExecutionPolicy
Restricted
PS E:> Set-ExecutionPolicy UnRestricted
执行策略更改
执行策略可以防止您执行不信任的脚本。更改执行策略可能会使您面临 about_Execution_Policies
帮助主题中所述的安全风险。是否要更改执行策略?
[Y] 是(Y)  [N] 否(N)  [S] 挂起(S)  [?] 帮助 (默认值为“Y”): y

脚本执行策略类型为:Microsoft.PowerShell.ExecutionPolicy 查看所有支持的执行策略:

PS E:>  [System.Enum]::GetNames([Microsoft.PowerShell.ExecutionPolicy])
Unrestricted
RemoteSigned
AllSigned
Restricted
Default
Bypass
Undefined

**Unrestricted:**权限最高,可以不受限制执行任何脚本。 **Default:**为Powershell默认的策略:Restricted,不允许任何脚本执行。 **AllSigned:**所有脚本都必须经过签名才能在运行。 **RemoteSigned:**本地脚本无限制,但是对来自网络的脚本必须经过签名。

关于Powershell脚本的签名在后续会谈到。

像命令一样执行脚本

怎样像执行一个命令一样执行一个脚本,不用输入脚本的相对路径或者绝对路径,甚至*.ps1扩展名。 那就将脚本的执行语句保存为别名吧:

PS E:> Set-Alias Invok-MyScript .MyScript.ps1
PS E:> Invok-MyScript

2012年4月28日 0:24:22
C:\Program Files\Common Files
files count
20

初始版本

import tkinter as tk
import random
import pandas as pd

class FloatingWordWindow:
    def __init__(self, master):
        self.master = master
        self.master.overrideredirect(True)  # 隐藏标题栏和边框
        self.master.attributes('-topmost', True)  # 置顶窗口
        self.master.attributes('-alpha', 0.7)  # 设置透明度
        self.master.geometry('200x50+100+100')  # 初始位置和大小
        self.word_label = tk.Label(self.master, font=('Arial', 20))
        self.word_label.pack(expand=True)
        self.move_window()

    def move_window(self):
        x = random.randint(0, self.master.winfo_screenwidth() - self.master.winfo_width())
        y = random.randint(0, self.master.winfo_screenheight() - self.master.winfo_height())
        self.master.geometry(f'+{x}+{y}')
        self.master.after(3000, self.move_window)  # 每隔3秒更新一次位置

    def update_word(self):
        words = ['apple', 'banana', 'orange', 'grape', 'watermelon']  # 替换为你的四级单词列表
        df=pd.read_excel("大学英语四级词汇完整版带音标-顺序版.xlsx")
        # 提取单词和释义列的内容
        word_column = df.columns[0]  # 第一列是单词列
        meaning_column = df.columns[1]  # 第二列是释义列
        # 创建一个字典,将单词和释义对应关系存储起来
        word_meaning_dict = dict(zip(df[word_column], df[meaning_column]))
        # 将字典的键转换为列表
        words_list = list(word_meaning_dict.keys())
        # 随机选择一个单词
        random_word = random.choice(words_list)
        self.word_label.config(text=random_word)
        # 绑定鼠标悬停事件
        self.word_label.bind("<Enter>",
                             lambda event, word=random_word: self.show_meaning(event, word, word_meaning_dict))
        self.word_label.bind("<Leave>", lambda event: self.hide_meaning(random_word))  # 绑定鼠标移出事件
        self.master.after(3000, self.update_word)  # 每隔3秒更新一次单词
    def show_meaning(self, event, word, word_meaning_dict):
        meaning = word_meaning_dict.get(word, "Meaning not found")
        self.word_label.config(text=f"{meaning}",font=('Arial', 10),wraplength=150)

    def hide_meaning(self,random_word):
        self.word_label.config(text=random_word,font=('Arial', 20),wraplength=150)  # 清空文本
def main():
    root = tk.Tk()
    root.attributes('-toolwindow', True)  # 隐藏任务栏图标
    root.attributes('-alpha', 0.7)  # 设置透明度
    root.geometry('200x50+150+150')  # 初始位置和大小
    app = FloatingWordWindow(root)
    app.update_word()
    root.mainloop()

if __name__ == '__main__':
    main()

优化这个代码让excel读取只运行一次

import tkinter as tk
import random
import pandas as pd

class FloatingWordWindow:
    def __init__(self, master):
        self.master = master
        self.master.overrideredirect(True)  # 隐藏标题栏和边框
        self.master.attributes('-topmost', True)  # 置顶窗口
        self.master.attributes('-alpha', 0.7)  # 设置透明度
        self.master.geometry('200x50+100+100')  # 初始位置和大小
        self.word_label = tk.Label(self.master, font=('Arial', 20))
        self.word_label.pack(expand=True)
        self.load_word_meanings()  # 加载单词和释义
        self.move_window()

    def load_word_meanings(self):
        df = pd.read_excel("大学英语四级词汇完整版带音标-顺序版.xlsx")
        self.word_meaning_dict = dict(zip(df[df.columns[0]], df[df.columns[1]]))  # 单词和释义对应的字典

    def move_window(self):
        x = random.randint(0, self.master.winfo_screenwidth() - self.master.winfo_width())
        y = random.randint(0, self.master.winfo_screenheight() - self.master.winfo_height())
        self.master.geometry(f'+{x}+{y}')
        self.master.after(3000, self.move_window)  # 每隔3秒更新一次位置

    def update_word(self):
        random_word = random.choice(list(self.word_meaning_dict.keys()))  # 随机选择一个单词
        self.word_label.config(text=random_word)
        # 绑定鼠标悬停事件
        self.word_label.bind("<Enter>",
                             lambda event, word=random_word: self.show_meaning(event, word))
        self.word_label.bind("<Leave>", lambda event: self.hide_meaning(random_word))  # 绑定鼠标移出事件
        self.master.after(3000, self.update_word)  # 每隔3秒更新一次单词

    def show_meaning(self, event, word):
        meaning = self.word_meaning_dict.get(word, "Meaning not found")
        self.word_label.config(text=f"{meaning}", font=('Arial', 10), wraplength=150)

    def hide_meaning(self, word):
        self.word_label.config(text=word, font=('Arial', 20), wraplength=150)  # 清空文本

def main():
    root = tk.Tk()
    root.attributes('-toolwindow', True)  # 隐藏任务栏图标
    root.attributes('-alpha', 0.7)  # 设置透明度
    root.geometry('200x50+150+150')  # 初始位置和大小
    app = FloatingWordWindow(root)
    app.update_word()
    root.mainloop()

if __name__ == '__main__':
    main()

优化二 悬停显示

import tkinter as tk
import random
import pandas as pd

class FloatingWordWindow:
    def __init__(self, master):
        self.master = master
        self.master.overrideredirect(True)  # 隐藏标题栏和边框
        self.master.attributes('-topmost', True)  # 置顶窗口
        self.master.attributes('-alpha', 0.7)  # 设置透明度
        self.master.geometry('200x50+100+100')  # 初始位置和大小
        self.word_label = tk.Label(self.master, font=('Arial', 20))
        self.word_label.pack(expand=True)
        self.move_window()

        # 读取 Excel 数据
        self.load_excel_data()

    def move_window(self):
        x = random.randint(0, self.master.winfo_screenwidth() - self.master.winfo_width())
        y = random.randint(0, self.master.winfo_screenheight() - self.master.winfo_height())
        self.master.geometry(f'+{x}+{y}')
        self.master.after(3000, self.move_window)  # 每隔3秒更新一次位置

    def load_excel_data(self):
        self.df = pd.read_excel("大学英语四级词汇完整版带音标-顺序版.xlsx")
        self.word_column = self.df.columns[0]  # 第一列是单词列
        self.meaning_column = self.df.columns[1]  # 第二列是释义列
        # 创建一个字典,将单词和释义对应关系存储起来
        self.word_meaning_dict = dict(zip(self.df[self.word_column], self.df[self.meaning_column]))
        # 将字典的键转换为列表
        self.words_list = list(self.word_meaning_dict.keys())

    def update_word(self):
        # 随机选择一个单词
        random_word = random.choice(self.words_list)
        self.word_label.config(text=random_word)
        # 绑定鼠标悬停事件
        self.word_label.bind("<Enter>",
                             lambda event, word=random_word: self.show_meaning(event, word))
        self.word_label.bind("<Leave>", lambda event: self.hide_meaning(random_word))  # 绑定鼠标移出事件
        self.master.after(3000, self.update_word)  # 每隔3秒更新一次单词

    def show_meaning(self, event, word):
        meaning = self.word_meaning_dict.get(word, "Meaning not found")
        self.word_label.config(text=f"{meaning}", font=('Arial', 10), wraplength=150)

    def hide_meaning(self, random_word):
        self.word_label.config(text=random_word, font=('Arial', 20), wraplength=150)  # 清空文本

def main():
    root = tk.Tk()
    root.attributes('-toolwindow', True)  # 隐藏任务栏图标
    root.attributes('-alpha', 0.7)  # 设置透明度
    root.geometry('200x50+150+150')  # 初始位置和大小
    app = FloatingWordWindow(root)
    app.update_word()
    root.mainloop()

if __name__ == '__main__':
    main()

优化三 直接显示

import tkinter as tk
import random
import pandas as pd

class FloatingWordWindow:
    def __init__(self, master):
        self.master = master
        self.master.overrideredirect(True)  # 隐藏标题栏和边框
        self.master.attributes('-topmost', True)  # 置顶窗口
        self.master.attributes('-alpha', 0.7)  # 设置透明度
        self.word_label = tk.Label(self.master, font=('Arial', 18))
        self.word_label.pack(expand=True, padx=0, pady=0)
        self.load_word_meanings()  # 加载单词和释义
        self.move_window()

    def load_word_meanings(self):
        df = pd.read_excel("大学英语四级词汇完整版带音标-顺序版.xlsx")
        self.word_meaning_dict = dict(zip(df[df.columns[0]], df[df.columns[1]]))  # 单词和释义对应的字典

    def move_window(self):
        x = random.randint(0, self.master.winfo_screenwidth() - self.master.winfo_width())
        y = random.randint(0, self.master.winfo_screenheight() - self.master.winfo_height())
        self.master.geometry(f'100x25+{x}+{y}')  # 初始窗口大小为200x50
        self.master.after(3000, self.move_window)  # 每隔3秒更新一次位置

    def update_word(self):
        random_word = random.choice(list(self.word_meaning_dict.keys()))  # 随机选择一个单词
        meaning = self.word_meaning_dict.get(random_word, "Meaning not found")
        # meaning = meaning.replace("\n", "--")
        str=random_word+"\n"+meaning;
        num_newlines = str.count("\n")
        self.word_label.config(text=random_word+"\n"+meaning,justify="left",padx=0, pady=0) 
        self.word_label.config(height=(num_newlines+1)*25)  # Set height based on number of newlines
        # 根据单词长度和字体大小调整窗口大小
        word_length = len(random_word+meaning)
        font_size = 18
        window_width = max(18, word_length * font_size)
        self.master.geometry(f'{window_width}x{(num_newlines+1)*25}')  # 调整窗口宽度
        # # 绑定鼠标悬停事件
        # self.master.bind("<Enter>",
        #                      lambda event, word=random_word: self.show_meaning(event, word))
        # self.master.bind("<Leave>", lambda event: self.hide_meaning(random_word))  # 绑定鼠标移出事件
        # # 绑定左键单击事件
        self.master.bind("<Button-1>", lambda event: self.update_word())
        self.master.after(3000, self.update_word)  # 每隔3秒更新一次单词

    def show_meaning(self, event, word):
        meaning = self.word_meaning_dict.get(word, "Meaning not found")
        meaning = meaning.replace("\n", "--")
        self.word_label.config(text=f"{meaning}", font=('Arial', 10),padx=0, pady=0)
        word_length = len(meaning)
        font_size = 20
        window_width = max(20, word_length * font_size)
        self.master.geometry(f'{window_width}x30')  # 调整窗口宽度

    def hide_meaning(self, word):
        self.word_label.config(text=word, font=('Arial', 20), wraplength=150,padx=0, pady=0)  # 清空文本

def main():
    root = tk.Tk()
    root.attributes('-toolwindow', True)  # 隐藏任务栏图标
    root.attributes('-alpha', 0.7)  # 设置透明度
    app = FloatingWordWindow(root)
    app.update_word()
    root.mainloop()

if __name__ == '__main__':
    main()

优化四

随机不重复

import tkinter as tk
import random
import pandas as pd

class FloatingWordWindow:
    def __init__(self, master):
        self.master = master
        self.master.overrideredirect(True)  # 隐藏标题栏和边框
        self.master.attributes('-topmost', True)  # 置顶窗口
        self.master.attributes('-alpha', 0.7)  # 设置透明度
        self.word_label = tk.Label(self.master, font=('Arial', 20))
        self.word_label.pack(expand=True, padx=0, pady=0)
        self.load_word_meanings()  # 加载单词和释义
        self.move_window()

    def load_word_meanings(self):
        df = pd.read_excel("大学英语四级词汇完整版带音标-顺序版.xlsx")
        self.word_meaning_dict = dict(zip(df[df.columns[0]], df[df.columns[1]]))  # 单词和释义对应的字典
        self.available_words = list(self.word_meaning_dict.keys())  # 可选择的单词列表

    def move_window(self):
        x = random.randint(0, self.master.winfo_screenwidth() - self.master.winfo_width())
        y = random.randint(0, self.master.winfo_screenheight() - self.master.winfo_height())
        self.master.geometry(f'100x30+{x}+{y}')  # 初始窗口大小为200x50
        self.master.after(3000, self.move_window)  # 每隔3秒更新一次位置

    def update_word(self):
        if not self.available_words:  # 如果可选择的单词列表为空,则重新加载
            self.available_words = list(self.word_meaning_dict.keys())

        random_word = random.choice(self.available_words)  # 从可选择的单词列表中随机选择一个单词
        self.available_words.remove(random_word)  # 从可选择的单词列表中删除已选择的单词
        self.word_label.config(text=random_word,padx=0, pady=0)
        # 根据单词长度和字体大小调整窗口大小
        word_length = len(random_word)
        font_size = 20
        window_width = max(20, word_length * font_size)
        self.master.geometry(f'{window_width}x30')  # 调整窗口宽度
        # 绑定鼠标悬停事件
        self.master.bind("<Enter>",
                             lambda event, word=random_word: self.show_meaning(event, word))
        self.master.bind("<Leave>", lambda event: self.hide_meaning(random_word))  # 绑定鼠标移出事件
        # # 绑定左键单击事件
        self.master.bind("<Button-1>", lambda event: self.update_word())
        self.master.after(3000, self.update_word)  # 每隔3秒更新一次单词

    def show_meaning(self, event, word):
        meaning = self.word_meaning_dict.get(word, "Meaning not found")
        meaning = meaning.replace("\n", "--")
        word_length = len(meaning)
        font_size = 11
        window_width = max(10, word_length * font_size)
        self.master.geometry(f'{window_width}x30')  # 调整窗口宽度
        self.word_label.config(text=f"{meaning}", font=('Arial', 10), justify="left", wraplength=999, padx=0, pady=0)

    def hide_meaning(self, word):
        self.word_label.config(text=word, font=('Arial', 20), wraplength=150,padx=0, pady=0)  # 清空文本

def main():
    root = tk.Tk()
    root.attributes('-toolwindow', True)  # 隐藏任务栏图标
    root.attributes('-alpha', 0.7)  # 设置透明度
    app = FloatingWordWindow(root)
    app.update_word()
    root.mainloop()

if __name__ == '__main__':
    main()

优化5

暂停

import tkinter as tk
import random
import pandas as pd

class FloatingWordWindow:
    def __init__(self, master):
        self.master = master
        self.paused = False  # 初始状态为未暂停
        self.master.overrideredirect(True)  # 隐藏标题栏和边框
        self.master.attributes('-topmost', True)  # 置顶窗口
        self.master.attributes('-alpha', 0.7)  # 设置透明度
        self.word_label = tk.Label(self.master, font=('Arial', 17))
        self.word_label.pack(expand=True, padx=0, pady=0)
        self.load_word_meanings()  # 加载单词和释义
        self.move_window()
        self.create_controls()  # 创建控制按钮
        # Bind right-click event
        self.master.bind("<Button-3>", lambda event: self.master.destroy())
        # Bind left-click event for advancing to the next word
        self.master.bind("<Button-1>", lambda event: self.update_word())
        # 绑定中键滚轮事件切换暂停/继续状态
        self.master.bind("<Button-2>", lambda event: self.toggle_pause())

    def load_word_meanings(self):
        df = pd.read_excel("大学英语四级词汇完整版带音标-顺序版.xlsx")
        self.word_meaning_dict = dict(zip(df[df.columns[0]], df[df.columns[1]]))  # 单词和释义对应的字典
        self.available_words = list(self.word_meaning_dict.keys())  # 可选择的单词列表
    def move_window(self):
        if self.paused:
            return
        x = random.randint(0, self.master.winfo_screenwidth() - self.master.winfo_width())
        y = random.randint(0, self.master.winfo_screenheight() - self.master.winfo_height())
        self.master.geometry(f'100x30+{x}+{y}')  # 初始窗口大小为200x50
        # self.master.after(3000, self.move_window)  # 每隔3秒更新一次位置
    def toggle_pause(self, event=None):
        self.paused = not self.paused
        if self.paused:
            self.control_button.config(text=">>>-->")
            self.control_button.pack()  # 显示按钮
        else:
            self.update_word()
            self.control_button.config(text="暂停")
            self.control_button.pack_forget()  # 隐藏按钮
    def create_controls(self):
        # 创建暂停/继续按钮
        self.control_button = tk.Button(self.master, text="暂停", command=self.toggle_pause)
        self.control_button.pack()
        # 初始状态下隐藏按钮
        self.control_button.pack_forget()
    def update_word(self):
        if self.paused:
            return
        if not self.available_words:  # 如果可选择的单词列表为空,则重新加载
            self.available_words = list(self.word_meaning_dict.keys())
        random_word = random.choice(self.available_words)  # 从可选择的单词列表中随机选择一个单词
        self.available_words.remove(random_word)  # 从可选择的单词列表中删除已选择的单词
        self.word_label.config(text=random_word,padx=0, pady=0)
        # 根据单词长度和字体大小调整窗口大小
        word_length = len(random_word)
        font_size = 18
        window_width = max(10, word_length * font_size)
        self.master.geometry(f'{window_width}x30')  # 调整窗口宽度
        # 绑定鼠标悬停事件
        self.master.bind("<Enter>",
                             lambda event, word=random_word: self.show_meaning(event, word))
        self.master.bind("<Leave>", lambda event: self.hide_meaning(random_word))  # 绑定鼠标移出事件
        self.master.after(5000, self.update_word)  # 每隔3秒更新一次单词
    def show_meaning(self, event, word):
        meaning = self.word_meaning_dict.get(word, "Meaning not found")
        meaning = meaning.replace("\n", "--")
        word_length = len(word+meaning)
        font_size = 11
        window_width = max(10, word_length * font_size)
        self.master.geometry(f'{window_width}x30')  # 调整窗口宽度
        self.word_label.config(text=f"{word}-{meaning}", font=('Arial', 10))
    def hide_meaning(self, word):
        self.word_label.config(text=word, font=('Arial', 17))  # 清空文本
def main():
    root = tk.Tk()
    root.attributes('-toolwindow', True)  # 隐藏任务栏图标
    root.attributes('-alpha', 0.7)  # 设置透明度
    app = FloatingWordWindow(root)
    app.update_word()
    # 创建多个浮动窗口实例
    # for _ in range(15):  # 创建5个窗口
    #     app = FloatingWordWindow(tk.Toplevel(root))
    #     app.update_word()
    root.mainloop()


if __name__ == '__main__':
    main()