欢迎光临散文网 会员登陆 & 注册

利用PyCharm设计简单的不重复单词抽取器

2023-03-11 21:39 作者:Z1-4  | 我要投稿

由于一人听写单词需要,想设计一个不重复单词抽取器。看了小破站的各种视频,加上对于相关包信息的搜集,制作了一个简易版的小程序。写篇小文章来记录一下过程。

相关源码、最终效果图和相关资源网址放在本文的最后。

目录

                                                          1.预备操作

                                                          2.背景的导入

                                                          3.按钮与显示界面设计

                                                          4.源码、效果图和参考网址

  1. 预备操作:

    导入相关模块和包,代码如下:

    import tkinter as tk#导入绘制界面库
    import random#导入随机函数使用
    from PIL import ImageTk,Image#绘背景图使用
    from tkinter import filedialog#导入文件使用
    import copy#重新开始功能使用
    import pygame as py#导入音乐使用

  2. 背景的导入:

    (1)在导入背景之前,需要初始化一个窗口实例,对窗口实例进行初始化操作:添加标题文字(title()函数)、窗体大小(geometry()函数)。注意若要调整窗口为600*600的,参数应该使用“600x600”而不能使用“600*600”(x为英文字母x).

    代码如下:

    root=tk.Tk()#初始化一个窗口实例,名字为root
    root.title("随机抽取")#添加标题文字
    root.geometry('600x600')#设置窗体大小

    (2)导入背景前先将背景图片保存到本地的某个地方。使用Image中的open()函数打开背景图片(使用绝对路径),使用resize()函数调整图片的大小。然后使用PhotoImage()函数提取图片像素建立新图片。注意这里不能使用tk中的PhotoImage()函数而要使用ImageTk中的PhotoImage()函数,前者支持gif形式的图片,本文采用jpg图片,使用后者。

    然后使用tk中的label()函数对图像进行绘制。

    具体代码如下:

    #导入背景图片
    img=Image.open(r"C:\Users\86157\Desktop\随机单词抽取\1.jpg")
    img=img.resize((600,600))
    photo = ImageTk.PhotoImage(img)
    tk.Label(master=root,image=photo).grid(row=0, column=0)

    效果图如下:

背景效果图
(3)

3.按钮与显示界面设计

(1)显示界面设计

    抽取的结果要显示在屏幕上,使用tk中的StringVar()实现,先进行初始化,使用set()函数设置未抽取时的内容。然后对字体(本文使用黑体)进行调整,并使用place()函数将其放置在画布的某个位置。

    代码如下:

    num = tk.StringVar()
    num.set('目前还未抽取')
    label = tk.Label(root, textvariable=num, font=("SimHei", 40))
    label.place(x=50, y=120)

    同理设计显示已经抽出的单词的个数。

    代码如下:

    num2 = tk.StringVar()
    num2.set("已抽取个数:"+str(age))
    label = tk.Label(root, textvariable=num2, font=("SimHei", 40))
    label.place(x=50, y=30)

    效果图如下:

显示界面效果图

(2)按钮设置

    按钮一共分为四个,随机抽取,重新抽取,导入文件,开关音乐。

    首先,定义三个列表L,L2,L3三者均为空列表,L用于存放抽取的数据,L2和L3重新抽取中对L中的内容进行修正。

    代码如下:

    L,L2,L3=[],[],[]

    1.导入文件:自定义getfile()函数

    使用global将全局变量L,L2,L3调入到函数内部进行使用。然后使用askopenfilename()函数导入文件,将导入的文件的绝对路径返回给一个变量,接着使用路径来打开相应的文件。本文使用文本文件txt,文件中的文本形式类似为:“1.学生\n”,因此需要对每一行取出的字符进行分离操作,使用split()函数分离两次就得到了“学生”,将其存添加到空列表L中,重复这个过程直到没有元素可以添加了,然后将L进行深拷贝,存储在L2中。

    代码如下:

    def getfile():
       global L,L2,L3
       L,L2,L3=[],[],[]
       file_path=filedialog.askopenfilename()
       with open(file_path, encoding="utf-8") as file:
           while (1):
               result = file.readline()
               result1 = result.split("\n")[0]
               result2 = result1.split(".")[-1]
               if (result):
                   L.append(result2)
               else:
                   L2 = copy.deepcopy(L)
                   break

    当按下“随机抽取按钮之后”,才会调用上述函数,因此上述函数时点击按钮时发生的事件。按钮采用tk.Button()函数进行调用,command参数使用lambda函数,点击后具体的操作为getfile()函数。然后将按钮放在界面合适的位置即可。

    代码如下:

    button3=tk.Button(root,text="导入文件",font=("Microsoft         SimHei",28),command=lambda:getfile())
    button3.place(x=135,y=415)

    2.随机抽取

    在导入文件之后,列表L中就存放了所有带抽取的单词。在抽取过程中需要不断改变显示的数据以及已经抽取元素的个数。定义一个全局变量age用于存放已经抽取元素个数,将全局变量age(统计抽取个数)和num2(显示内容)在抽取单词的getcharacters()函数内部调用。

    每一次进行抽取,显示已经抽取元素的个数会增加,列表中元素会减少,显示内容会改变。因此每次操作需更改三部分,显示内容更改可以在函数体外得到,故不写入该函数中。将列表长度作为条件判断,当列表长度为0时候,抽取完毕返回信息;当列表长度不为0时候,利用random.randint()函数随机抽取一个整数,age自增,然后在num2中显示age的值,接着将数删除并作为函数的返回值。注意不能先删除再返回,删除和返回需要同一个值,可以使用pop()函数或者remove()函数等。

    代码如下:

    def getcharacters(L):
       global age,num2
       length=len(L)#列表长度
       if(length!=0):
           number = random.randint(0, length-1)  # 所取得序号
           age=age+1
           num2.set("已抽取个数:"+str(age))
           return L.pop(number)
       else:
           return "抽取完毕!"

    与上述设计按钮同理,这里的getcharacters()只是点击按钮时调用的函数,仍需要设计按钮。仍使用tk.Button()函数,command中调用lambda函数,这里需要将选出来的单词显示在num中,即需要抽取字符并且显示,故使用num.set(str(getcharacters())),在调用gethcharacters后并输出到屏幕上,然后调整按钮位置。(str在这里多余,若要抽取其他类型,如整型数据可以加上)

    代码如下:

    button=tk.Button(root,text="随机抽取",font=("Microsoft SimHei",28),command=lambda:num.set(str(getcharacters(L))))
    button.place(x=135,y=215)

    3.开关音乐

    由于作者水平受限,开关音乐时只能做到重新播放和关闭。

    设置一个flag来实现音乐的开关。当打开程序时,音乐自动播放,使用py中的init()函数进行初始化,然后使用load()函数导入对应的音频文件,然后使用play()函数进行播放,第一个参数设置为-1表示循环播放,第二个参数设置为0,表示从第0秒开始。

    点击按钮所调用的函数为stop_openmusic(),当flag=1的时候点击,使用stop()函数停止音乐,同时将flag的值调整为0,;当flag=0的时候点击,模仿开始时播放音乐的步骤即可。

    代码如下:

    flag=1
    py.mixer.init()
    py.mixer.music.load(r"C:\Users\86157\Desktop\随机单词抽取\音乐.mp3")
    py.mixer.music.play(-1, 0)
    def stop_openmusic():
       global flag
       if(flag==1):
           py.mixer.music.stop()
           flag=0
       else:
           py.mixer.init()
           py.mixer.music.load(r"C:\Users\86157\Desktop\随机单词抽取\音乐.mp3")
           py.mixer.music.play(-1, 0)
           flag=1

    按钮设置与上述按钮设置同理,直接放代码:

    button3=tk.Button(root,text="开关音乐",font=("Microsoft SimHei",28),command=lambda:stop_openmusic())
    button3.place(x=135,y=515)

    4.重新抽取

    重新抽取的过程就是将L的内容变成与初始导入时候一样的内容,并且调整num2中显示已经抽取元素的个数的过程。再抽取过程中L发生改变,L2是L的深拷贝,若使用单纯的赋值操作,则二者会连接在一起,对L中元素进行的删除操作会等同地发生在L2中,故不能仅仅利用L2来修正L。L3作为L2的深拷贝,需要在函数执行的最后进行操作,故这之前需要将L2还原。本文利用L3对L进行修正,当第一次L2和L不相同时,L2中存放了完整的元素,L3为空,用L3深拷贝L2,然后赋值给L;当之后L2和L不相同时,L3中存放了开始时完整的数据,故用L3来修正L,并且将L2进行修正(对L进行深拷贝)为了保证L3不变。然后修改num2中显示的值为0即可。

    代码如下:

    def restart():
       global L,L2,L3,age
       if((L2!=L)&(L3!=[])):
           L=L3
           L2=copy.deepcopy(L)
       if((L2!=L)&(L3==[])):
           L3=copy.deepcopy(L2)
           L=L3
       L3=copy.deepcopy(L2)
       age = 0
       num2.set("已抽取个数:" + str(age))
       num.set("目前还未抽取")

    按钮设计与上述类似,直接放代码:

    button2=tk.Button(root,text="重新抽取",font=("Microsoft             SimHei",28),command=lambda:restart())
    button2.place(x=135,y=315)

至此小程序设计完毕。


     4.源码、效果图和参考网址

源码:

import tkinter as tk#导入库
import random
from PIL import ImageTk,Image
from tkinter import filedialog
import copy
import pygame as py
age=0
#初始化对象
root=tk.Tk()#初始化一个窗口实例,名字为root
root.title("随机抽取")#添加标题文字
root.geometry('600x600')#设置窗体大小
#导入背景图片
img=Image.open(r"C:\Users\86157\Desktop\随机单词抽取\1.jpg")
img=img.resize((600,600))
photo = ImageTk.PhotoImage(img)
tk.Label(master=root,image=photo).grid(row=0, column=0)
#显示抽取出来的界面
num = tk.StringVar()
num.set('目前还未抽取')
label = tk.Label(root, textvariable=num, font=("SimHei", 40))
label.place(x=50, y=120)
num2 = tk.StringVar()
num2.set("已抽取个数:"+str(age))
label = tk.Label(root, textvariable=num2, font=("SimHei", 40))
label.place(x=50, y=30)
L,L2,L3=[],[],[]
def getfile():
   global L,L2,L3
   L,L2,L3=[],[],[]
   file_path=filedialog.askopenfilename()
   with open(file_path, encoding="utf-8") as file:
       while (1):
           result = file.readline()
           result1 = result.split("\n")[0]
           result2 = result1.split(".")[-1]
           if (result):
               L.append(result2)
           else:
               L2 = copy.deepcopy(L)
               break
def getcharacters(L):
   global age,num2
   length=len(L)#列表长度
   if(length!=0):
       number = random.randint(0, length-1)  # 所取得序号
       age=age+1
       num2.set("已抽取个数:"+str(age))
       return L.pop(number)
   else:
       return "抽取完毕!"
def restart():
   global L,L2,L3,age
   if((L2!=L)&(L3!=[])):
       L=L3
       L2=copy.deepcopy(L)
   if((L2!=L)&(L3==[])):
       L3=copy.deepcopy(L2)
       L=L3
   L3=copy.deepcopy(L2)
   age = 0
   num2.set("已抽取个数:" + str(age))
   num.set("目前还未抽取")
#导入音乐
flag=1
py.mixer.init()
py.mixer.music.load(r"C:\Users\86157\Desktop\随机单词抽取\音乐.mp3")
py.mixer.music.play(-1, 0)
def stop_openmusic():
   global flag
   if(flag==1):
       py.mixer.music.stop()
       flag=0
   else:
       py.mixer.init()
       py.mixer.music.load(r"C:\Users\86157\Desktop\随机单词抽取\音乐.mp3")
       py.mixer.music.play(-1, 0)
       flag=1
#设置按钮
button=tk.Button(root,text="随机抽取",font=("Microsoft SimHei",28),command=lambda:num.set(str(getcharacters(L))))
button.place(x=135,y=215)
button2=tk.Button(root,text="重新抽取",font=("Microsoft SimHei",28),command=lambda:restart())
button2.place(x=135,y=315)
button3=tk.Button(root,text="导入文件",font=("Microsoft SimHei",28),command=lambda:getfile())
button3.place(x=135,y=415)
button3=tk.Button(root,text="开关音乐",font=("Microsoft SimHei",28),command=lambda:stop_openmusic())
button3.place(x=135,y=515)
root.mainloop()

效果图:

小程序效果图


相关包的使用及处理问题参考网站:

  1. (23条消息) Python-Tkinter图形化界面设计(详细教程 )_python tkinter图形_王张飞的博客-CSDN博客

  2. (23条消息) Python之解决tkinter.PhotoImage不显示图片的问题 Python3_tk.photoimage_苏妲己点姜子牙的博客-CSDN博客

  3. (23条消息) pygame导入音频_pygame输入音频_黑脉金的博客-CSDN博客

  4. MyFreeMP3 (liumingye.cn)(下载mp3)

  5. 拓展 用Python制作一个随机点名的小程序_哔哩哔哩_bilibili

  6. (23条消息) tkinter导入文件_摇摇晃摇晃的博客-CSDN博客



利用PyCharm设计简单的不重复单词抽取器的评论 (共 条)

分享到微博请遵守国家法律