Python多功能课堂点名器、抽签工具

news2024/11/17 13:39:51

一、问题缘起

去年,ChatGPT浪潮袭来,我懂简单的Python基础语法,又有一些点子,于是借助于人工智能问答工具,一步一步地制作了一个点名器,也可以用于抽签。当时,我已经设计好页面和基础的功能,并在广大网友中开启了测试。

点名器1.0

目前,写的这个点名器的文章阅读里已经达到了近700次,而且有6个人收藏,这说明很多人还是挺需要这样的点名器的。不过,也有网友给我留言,提出了修改的建议,如点名器这个界面有点儿大,教学过程中有时用到,有时用不到,用到时可以展示,不用时,能不能把这个界面最小化到右上角,再点右上角把它调出来。

还有人说,如果抽到这个人,能不能把名字也读出来,这样就不用老师再说他们的名字了。听到声音,看到自己的名字,学生就可以站起来直接回答问题了,老师也不必再念学生名字了。

顺便说一下:当时,我刚自学Python,主要是看董付国的书,讲的通俗易懂,内容也很丰富,重要的知识点都讲到了。我看的就是下面这本书:

只是懂一些基本的语法,但是在人工智能的加持下,我很快就学会了自主编程。

之前,一直忙其它的事情,没有抽出时间来,现在我用了ChatGPT的帮助,相信利用Python做一些小项目的开发都不是难事。

二、开发过程

1. 为点名器添加最大化、最小化功能

首先,我对原有点名器的改造与升级都是基于第一个版本,我需要添加的是朗读、最小化这两个功能。

我向ChatGPT提问,并根据结果进行调试。

向ChatGPT提问

ChatGPT根据我的请求,很快给出了相应的代码:

import tkinter as tk

class MinimizeApp:
    def __init__(self, master):
        self.master = master
        self.master.geometry("800x600")  # 初始大小
        self.minimized = False  # 标记是否已最小化
        self.original_geometry = ''  # 存储原始窗口大小
        
        # 最小化/最大化按钮
        self.toggle_btn = tk.Button(master, text="最小化", command=self.toggle)
        self.toggle_btn.pack()

        # 配置最小化时显示的小窗口
        self.mini_window = tk.Toplevel(self.master)
        self.mini_window.geometry("100x50+{}+0".format(self.master.winfo_screenwidth() - 100))
        self.mini_window.overrideredirect(True)  # 去除窗口边框
        self.mini_window.withdraw()  # 初始时隐藏

        # 最大化按钮
        self.maximize_btn = tk.Button(self.mini_window, text="最大化", command=self.toggle)
        self.maximize_btn.pack(fill=tk.BOTH, expand=True)

    def toggle(self):
        if self.minimized:  # 如果当前是最小化,恢复窗口
            self.master.deiconify()  # 显示主窗口
            self.master.geometry(self.original_geometry)  # 恢复原始大小
            self.mini_window.withdraw()  # 隐藏最小化窗口
            self.toggle_btn.config(text="最小化")
            self.minimized = False
        else:  # 如果当前是正常大小,最小化窗口
            self.original_geometry = self.master.geometry()  # 存储当前大小和位置
            self.master.withdraw()  # 隐藏主窗口
            self.mini_window.deiconify()  # 显示最小化窗口
            self.minimized = True

def main():
    root = tk.Tk()
    app = MinimizeApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

上面的代码可以实现一个自定义的最小化/最大化功能,首先创建一个最小化按钮,当用户点击这个按钮时,整个应用窗口缩小至屏幕的右上角,并只显示一个最大化按钮。再次点击这个最大化按钮时,窗口恢复到其原始大小。

我们通过手动点击的方式,管理窗口的大小和位置,以及按钮的显示和隐藏。

下一步是把以上代码,融入到点名器1.0当中,我们需要对这里的按纽对象名称进行修改,删除与旧版相比重复的代码,同时还要修复调试过程中的报错。

上课过程中,我又进行了实地的测试,发现最小化后窗品没有置于所有窗口的最前方,于是,我于向ChatGPT发问,如果设置最小化窗口前端显示,它很快给了我下面的代码:

self.mini_window.attributes('-topmost', 1)

果然,通过这个代码,前置显示问题很快解决了。

2. 为点名器添加朗读功能

增加了最大最小化窗口的功能,我还想让点名器自动朗读出点名器上的人名,这样显示的名字和朗读的声音匹配起来,可以最大可能地节省老师的时间和体力,进一步提升讲课的效率。

为了使软件可以发声,我们需要导入一个pyttsx3这个包,同时还要保证软件联网。

当滚动到显示的人名时,就会触发朗读的功能。当然,也有人不想使用朗读的功能,或者使用的电脑无法上网,这时我们就需要增加一个复选框,用复选框来控制是否朗读发声。

我能过向ChatGPT提问得到了如下回复:

增加复选框

接下来,我要做的是,在def __init__(self, master)这个初始化函数里,加上一个复选框代码,同时通过检测复选 框check_var的值,来控制是否朗读发声。注意这里的复选框不需要定义命令函数。

最后,在测试时,我发现软件不朗读人名,后来才发现self.engine = pyttsx3.init()这个发声引擎的初始化要在软件界面初始化前启动。

3. 软件使用展示

经过中午和下午的修改测试,终于完成了新版点名器的雏形,如下图所示:

新版点名器

为了让大家更清楚的使用,我还制了一个演示的视频:

基于Python的多功能点名器

4. 点名器下载

为了让网友使用,我特地把软件编译后上传到了网盘,大家可以点击下面的按纽下载,下载不需要注册。推荐大家用电脑下载,因为软件只能在Windows10系统下运行。

http://down.pandengenglish.com/f/364317-1025845981-56d129​down.pandengenglish.com/f/364317-1025845981-56d129

5. 优化后代码

在增加朗读、最小化等功能同时,我征求网友的意见,又增加了姓名字体的自动调节功能。而且,为了让界面显示的更好看,我把按纽居中显示,最后形成以下软件。

软件代码如下:

# 2023年4月10日更新1. 修复按纽点击开始再点击暂停2. 增加标记功能 3.增加欢迎页 4.改变播放速度
# 2024年2月28日更新1. 增加人名朗读 2. 增加窗口最小化功能 3. 按纽居中 4. 字体大小控制
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
import os
import random
import time
import pyttsx3

class RollCallApp:
    def __init__(self, master):
        self.engine = pyttsx3.init()
        self.master = master
        self.master.title("点名器 Gordon QQ:403096966")
        #self.master.resizable(False, False)
        #self.master.geometry("880x300")  # 初始大小
        self.minimized = False  # 标记是否已最小化
        self.master.protocol("WM_DELETE_WINDOW", self.display_messagebox) # 弹窗提示确认退出
        self.master.attributes('-topmost', True)
        # 读取文件中的名字
        self.names = []
        self.load_names()

        # 播放名字的控件
        self.label_name = tk.Label(self.master, text="欢迎使用点名器", font=("Times New Roman", 90), fg="blue")
        self.label_name.pack(pady=50)
        
        
        #设置frame 居中显示
        button_frame = tk.Frame(self.master)
        button_frame.pack()
        items = ("加分","旷课", "迟到", "请假")
        self.combo = ttk.Combobox(button_frame, values=items, font=("宋体", 20),width=5)
        self.combo.set("加分")  # 设置默认值
        self.combo.configure(font=("宋体", 20))
        #设置字体大小写
        self.scale = tk.Scale(self.master, from_ = 30, to = 210, orient = 'horizontal',command = self.resize)
        self.scale.set(80)
        self.scale.pack(expand=True, fill=tk.BOTH,side=tk.BOTTOM) 
        
        # 设置退出按钮
        self.button_quit = tk.Button(button_frame, text="退出", font=("宋体", 20), width=9, command=self.display_messagebox)
        self.button_quit.pack(side=tk.LEFT,anchor="center",padx=22)
        # 设置标记内容
        self.combo.pack(side=tk.LEFT, fill=tk.BOTH, padx=5)
        
        # 创建一个IntVar对象来存储复选框的状态
        self.check_var = tk.IntVar(value=0)  # 默认值设置为0(未选中)
        
        # 控制按钮
        self.button_mark = tk.Button(button_frame, text="标记", font=("宋体", 20), width=9, command=self.write_txt)
        self.button_mark.pack(side=tk.LEFT,anchor="center",padx=20)
        
        # 创建复选框,绑定到check_var变量
        self.checkbox = tk.Checkbutton(button_frame, text="发声", font=("宋体", 12), variable=self.check_var)
        self.checkbox.pack(side=tk.LEFT,anchor="center", padx=3)

        # 控制按钮
        self.button_action = tk.Button(button_frame, text="开始", font=("宋体", 20), width=9, command=self.toggle_rolling)
        self.button_action.pack(side=tk.LEFT, anchor="center",padx=20)

        self.button_min = tk.Button(button_frame, text="最小化", font=("宋体", 20), width=9, command=self.toggle)
        self.button_min.pack(side=tk.LEFT,anchor="center", padx=20)
        
        # 配置最小化时显示的小窗口
        self.mini_window = tk.Toplevel(self.master)
        self.mini_window.geometry("100x50+{}+0".format(self.master.winfo_screenwidth() - 100))
        self.mini_window.overrideredirect(True)  # 去除窗口边框
        self.mini_window.withdraw()  # 初始时隐藏

        # 最大化按钮
        self.maximize_btn = tk.Button(self.mini_window, text="最大化",font=("宋体", 15, "bold"), command=self.toggle)
        self.maximize_btn.pack(fill=tk.BOTH, expand=True)
        
        # 控制变量
        self.rolling = False
        self.current_name = ""
        
        #设置引擎
        self.engine.setProperty('language', 'zh-CN')
        rate = self.engine.getProperty('rate')
        self.engine.setProperty('rate', rate - 50)
        # 设置发音大小,范围为0.0-1.0
        volume = self.engine.getProperty('volume')
        self.engine.setProperty('volume', 1.2)
        # 设置默认的声音:voices[0].id代表男生,voices[1].id代表女生
        voices = self.engine.getProperty('voices')
        self.engine.setProperty('voice', voices[0].id)
    def resize(self,ev = None):
        # 监控窗口是不是最大化,最大化则字体变大,否则为55号字
        if self.master.state() == 'zoomed':
            self.label_name.config(font = '宋体 -%d bold' % self.scale.get())
        elif not self.master.state() == 'zoomed':#self.root.state() == 'iconic':
            self.label_name.config(font = '宋体 -%d bold' % self.scale.get())
        
    def toggle(self):
        if self.minimized:  # 如果当前是最小化,恢复窗口
            self.master.deiconify()  # 显示主窗口
            #self.master.geometry("880x300")  # 初始大小
            #self.master.geometry(self.original_geometry)  # 恢复原始大小
            self.mini_window.withdraw()  # 隐藏最小化窗口
            self.button_min.config(text="最小化")
            self.minimized = False
        else:  # 如果当前是正常大小,最小化窗口
            self.original_geometry = self.master.geometry()  # 存储当前大小和位置
            self.master.withdraw()  # 隐藏主窗口
            self.mini_window.deiconify()  # 显示最小化窗口
            self.mini_window.attributes('-topmost', 1)
            self.minimized = True        
        

    def load_names(self):
        """从当前目录下的names.txt文件中读取名字"""
        if os.path.exists("names.txt"):
            with open("names.txt", "r", encoding="utf-8") as f:
                for name in f:
                    name = name.strip()
                    if name:
                        self.names.append(name)
        else:
            messagebox.showerror("错误","找不到names.txt,请把人名放到当前目录下的names.txt中!")
            with open("names.txt", "w+", encoding="utf-8") as fi:
                fi.write("")
    def write_txt(self):
        label_text = self.label_name.cget("text")
        with open("标记内容.txt",'a+',encoding='utf-8') as f:
            f.write(label_text + f" {self.combo.get()}\n")

    def toggle_rolling(self):
        """切换播放状态,并更新按钮文字"""
        self.rolling = not self.rolling
        if self.rolling:
            self.button_action.config(text="暂停")
            self.roll_name()
            if self.check_var.get() == 1:
                self.engine.say(self.current_name)
                self.engine.runAndWait()
        else:
            self.button_action.config(text="开始")

    def roll_name(self):
        """随机选取一个名字播放"""

        if self.names:
            self.current_name = random.choice(self.names)
            self.label_name.config(text=self.current_name)
            self.master.update()
            time.sleep(0.01)
            if self.rolling:
                self.roll_name()

    def display_messagebox(self):
        """弹窗提示是否确认退出程序"""
        if messagebox.askokcancel("退出程序", "确定要退出程序吗?"):
            self.master.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    app = RollCallApp(root)
    root.mainloop()

三、学后反思

  1. 本软件最初编写于去年的四月份,今年的二月突然有了新的灵感,短时间内增加了二个不错的功能。看来软件的编写也是需要一定时间的打磨。在汲取用户意见的同时,还要利用ChatGPT对原有的软件进行改造升级。
  2. 如果你也想像我一样自己独立编写有趣的Python软件,用于提升个人办公效率,我建议你可以买一本Python界的大伽级人数董付国老师的书,他的书内容丰富,集书、微课视频和习题于一体,边看边学,可以在短时间内学会Python的基础语法,并开始手动编写自己想要的软件了。
  3. Python是当下最热门的编程语言,在人工智能领域发挥着不可替代的作用。它的扩展性、灵活性极强,可以实现跨平台的应用,被广泛应用于Web开发、网络爬虫、办公自动化等领域。因此,为自己的工作和生活带来极大的便利,我建议大家尽早学习这门流行的语言。在ChatGPT的赋能下,每个人都可以借用于视频、书本轻松学会它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1476454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue中组合式API和选项式API的区别

组合式api(Composition API)是vue3对我们开发者来说变化非常大的更新,我们先不关注具体语法,先对它有一个大的感知。 通过vue2, vue3两种形式实现同一个需求,理解vue3的compition api 带来的好处 两个独立的功能&…

CSS3详解

1.什么是CSS css的优势 1、内容和表现分离 2、网页结构表现统一&#xff0c;可以实现复用 3、样式十分的丰富 4、建议使用独立于html的css文件 5、利用SE0,容易被搜索引擎收录&#xff01; CSS的几种导入方法 内部式 <style>h1{color: red;}</style> 外部式 嵌…

搭建服务器及跨域处理

使用内置的模块搭建服务器 自己电脑: 域名:localhost ip:127.0.0.1 http模块搭建服务器 const http = require(http)// 创建一个http对应的服务器,每次改完服务器的代码后都需要重新启动下服务器 /*方式一: const server = http.createServer((request,response)=>{…

Vue 环境安装以及项目创建

环境安装 nodejs 安装 下载地址&#xff1a;https://nodejs.org/dist/v18.16.1/ 根据系统类型选择对应安装包&#xff0c;选择安装路径那个后一直下一步即可安装完成。 配置npm 代理镜像,设置为淘宝的镜像地址&#xff08;后面按照依赖可以加速下载安装包&#xff09; npm c…

【C++进阶】哈希 + unordered系列容器

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

前端css、js、bootstrap、vue2.x、ajax查漏补缺(1)

学到的总是忘&#xff0c;遇到了就随手过来补一下 1.【JS】innerHTML innerHTML属性允许更改HTML元素的内容可以解析HTML标签 2.【CSS】display: none 设置元素不可见&#xff0c;不占空间&#xff0c;约等于将元素删除一样&#xff0c;只是源代码还存在 3.【CSS】行内样式 4.【…

机器学习专项课程03:Unsupervised Learning, Recommenders, Reinforcement Learning笔记 Week01

Week 01 of Unsupervised Learning, Recommenders, Reinforcement Learning 本笔记包含字幕&#xff0c;quiz的答案以及作业的代码&#xff0c;仅供个人学习使用&#xff0c;如有侵权&#xff0c;请联系删除。 课程地址&#xff1a; https://www.coursera.org/learn/unsupervi…

前端视角对Rust的浅析

概述 本文将从 Rust 的历史&#xff0c;前端的使用场景和业界使用案例一步步带你走进 Rust的世界。并且通过一些简单的例子&#xff0c;了解 Rust 如何应用到前端&#xff0c;提高前端的生产效率。 Rust简史 2006年&#xff0c;软件开发者Graydon Hoare在Mozilla工作期间&#…

单细胞Seurat - 细胞聚类(3)

本系列持续更新Seurat单细胞分析教程&#xff0c;欢迎关注&#xff01; 维度确定 为了克服 scRNA-seq 数据的任何单个特征中广泛的技术噪音&#xff0c;Seurat 根据 PCA 分数对细胞进行聚类&#xff0c;每个 PC 本质上代表一个“元特征”&#xff0c;它结合了相关特征集的信息。…

【三维重建】【slam】【分块重建】LocalRF:逐步优化的局部辐射场的鲁棒视图合成

项目地址&#xff1a;https://localrf.github.io/ 题目&#xff1a;Progressively Optimized Local Radiance Fields for Robust View Synthesis 来源&#xff1a;KAIST、National Taiwan University、Meta 、University of Maryland, College Park 提示&#xff1a;文章用了s…

学习Android的第十八天

目录 Android 可复用 BaseAdapter 为什么使用BaseAdapter&#xff1f; 如何使用BaseAdapter&#xff1f; Android GridView 网格视图 GridView 属性 示例 Android Spinner 下拉选项框 Spinner Spinner 属性 示例 Android AutoCompleteTextView 自动完成文本框 Auto…

观成科技:加密C2框架Covenant流量分析

工具介绍 Covenant是一个基于.NET的开源C2服务器&#xff0c;可以通过HTTP/HTTPS 控制Covenant agent&#xff0c;从而实现对目标的远程控制。Covenant agent在与C2通信时&#xff0c;使用base64/AES加密载荷的HTTP隧道构建加密通道。亦可选择使用SSL/TLS标准加密协议&#xf…

【C/C++】inline内联函数详解

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

使用drawio画数据库实体关系图

在drawio中使用数据库实体关系图 drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址drawon.cn或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功能&#xff0c;并实现…

如何利用ChatGPT搞科研?论文检索、写作、基金润色、数据分析、科研绘图(全球地图、植被图、箱型图、雷达图、玫瑰图、气泡图、森林图等)

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

【STM32】STM32学习笔记-WDG看门狗(46)

00. 目录 文章目录 00. 目录01. WDG简介02. IWDG概述03. IWDG框图04. IWDG键寄存器05. WWDG简介06. WWDG框图07. WWDG工作特性08. IWDG和WWDG对比09. 预留10. 附录 01. WDG简介 WDG&#xff08;Watchdog&#xff09;看门狗 看门狗可以监控程序的运行状态&#xff0c;当程序因为…

ubuntu20.04安装docker及运行

ubuntu20.04安装docker及运行 ubuntu环境版本 Ubuntu Focal 20.04 (LTS) 查看系统版本 rootubuntu20043:~# cat /proc/version Linux version 5.15.0-78-generic (builddlcy02-amd64-008) (gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) …

基于Eclipse+Tomcat+Mysql开发的网络考试系统的设计与实现

基于EclipseTomcatMysql开发的网络考试系统的设计与实现 项目介绍&#x1f481;&#x1f3fb; 网络考试系统主要用于实现高校在线考试&#xff0c;基本功能包括&#xff1a;自动组卷、试卷发布、试卷批阅、试卷成绩统计等。本系统结构如下&#xff1a; &#xff08;1&#xff0…

C++重点---STL简介

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、STL简介 STL&#xff08;Standard Template Library&#xff09;是C标准库中的一个重要组成部分&#xff0c;它提供了…

8 easy 14. 最长公共前缀

纵向扫描法&#xff1a; //编写一个函数来查找字符串数组中的最长公共前缀。 // // 如果不存在公共前缀&#xff0c;返回空字符串 ""。 // // // // 示例 1&#xff1a; // // //输入&#xff1a;strs ["flower","flow","flight"…