Html是Hyper Text Mark-up Language 的首字母简写,意思是超文本标记语言,超文本指的是超链接,标记指的是标签,是一种用来制作网页的语言,这种语言由一个个的标签组成,用这种语言制作的文件保存的是一个文本文件,文件的扩展名为html或者htm,一个html文件就是一个网页,html文件用编辑器打开显示的是文本,可以用文本的方式编辑它,如果用浏览器打开,浏览器会按照标签描述内容文件渲染成网页,显示的网页可以从一个网页链接跳转到另一个网页。
Html中标签分为 :成对标签和自闭合标签【空标签】
成对出现,有开始标签必须有结束标签,内容包裹在两个标签中,而且开始标签名和结束标签名一致,并且结束标签必须以斜杠/开头
语法:
<font>内容</font>
只有一个标签,用斜杠结束,斜杠也可以省略
语法:
<br/>
注意事项:
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
</head>
<body>
</body>
</html>
!DOCTYPE html是文档声明,定义文档类型为html,并且告诉不同的浏览器用标准方式进行解析html语言,如果不写的话,会产生怪异模式,所谓怪异模式,就是浏览器会用自己的方式进行解析,不同的浏览器有各自的解析方式,从而会出现无效果、不兼容等问题。
注意,html中有两种声明类型,一种叫做xhtml,即html,另一种叫做html5,html5是xhtml的升级版,所以我们建议使用html5的声明方式
xhtml声明方式:
<htmlxmlns="http://www.w3.org/1999/xhtml">
html5声明方式:
<!DOCTYPE html>
html是html文档的整体,也就是表示一个网页。
html中的lang="en"是定义该文件语言是英文
head是html的第一层子元素【子标签】,负责对网页进行一些设置以及定义标题,设置包括定义网页的编码格式,外链css样式文件和JavaScript文件等。设置的内容不会显示在网页上,标题的内容会显示在标题栏中。即title标签。
meta是html语言head标签中的一个辅助性标签,该标签不包含任何内容,但是该标签的属性定义了与文档相关联的名称,比如:编码
<meta charset="utf-8"></meta>
body也是html的第一层子元素,我们页面中显示的所有内容全部都是编写在该标签体中。
html制定了文档的编写规范,必须遵守。
所有的标签必须小写
所有的属性必须用双引号括起来
html文档代码中可以插入注释,注释是对代码的说明和解释,注释的内容不会显示在页面上。
注释的语法:
<!-- 注释的内容 -->
注:属性是标签的辅助作用。
属性 描述 bgcolor 设置网页的背景颜色 background 设置网页的背景图片
设置网页的背景颜色
<!DOCTYPE html>
<html lang="en">
<head>
<title>html的属性</title>
</head>
<body bacolor="pink">
</body>
</html>
我们在开发网页时,需要经常的插入图片、视频、文件等一些操作,但是我们需要指定文件所在的位置,这个位置就是所谓的路径
路径分为:
设置网页的背景图片
<!DOCTYPE html>
<html lang="en">
<head>
<title>html的属性</title>
</head>
<body background="../images/10.jpg">
</body>
</html>
注意事项:
bgcolor和background不能同时使用
background不能指定绝对路径
网页的组成:文字、图片、视频、超链接、列表、表格、表单等组成。
标签 描述 hn 设置文字标题【n:取值范围 1~6】 center 居中对齐 hr 水平线 属性(width:宽度 color:颜色 size:粗细) br 换行 p 段落
标签 描述 font 设置字体,需要借助属性设置
属性 描述 color 设置字体颜色 size 设置字体大小,不需要带单位,取值范围:1~7【浏览器默认值:3】 face 设置字体风格
<font size="2" color="red" face="黑体"></font>
标签 描述 b 定义粗体文本 em 定义着重文字 i 定义斜体文字 small 定义小号字 strong 定义加重语气 sub 定义下标字 sup 定义上标字 ins 定义插入字 del 定义删除字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html文本格式化标签</title>
</head>
<body>
<b>粗体文本</b>
<i>倾斜文本</i>
<em>着重文本</em>
<small>小号字</small>
<strong>加重语气</strong>
<sub>上标</sub>
<sup>下标</sup>
<ins>插入字</ins>
<del>删除字</del>
</body>
</html>
在Html中,图像由
标签定义。
是空标签,意思是说,它只包含属性。
要在页面上显示图像,你需要使用源属性(src)。src指"source"。源属性的值是图像的URL地址。
标签 描述 img 图片标签
属性 描述 src 指定图片的地址 width 设置图片的宽度 height 设置图片的高度 alt 设置图片的预备文本
注意事项:不建议设置图片大小,容易失真
在Html中,声音由标签定义。
标签 描述 audio 声音标签
属性 描述 src 指定声音地址
<audio src="nice.mp3">对不起,您的浏览器不支持</audio>
在Html中,视频由video标签定义
标签 描述 video 视频标签
属性 描述 src 指定视频地址
<video src="美女.mp4">对不起,您的浏览器不支持</video>
a标签定义超链接,用于从一个页面链接到另一个页面。
a标签最重要的属性是href,它指定链接的目标。
在所有浏览器中,链接的默认外观如下:
未被访问的链接带有下划线而且是蓝色的
已被访问的链接带有下划线而且是紫色的
活动链接带有下划线而且是红色的
语法:
<a href="链接目标">点击内容</a>
属性 描述 href 指定链接目标 name 指定锚的名称 download 指定下载链接 target 指定跳转方式 属性值 描述 _blank 新窗口打开【常用】 _parent 在父窗口中打开链接【了解】 _self 默认,在当前窗口打开【了解】 _top 在当前窗体打开链接,并替换当前的整个窗体【了解】 framename 到 iframe 在讲【常用】
超链接分类:
列表的使用与word等软件的列表概念相似,只不过是应用在网页展示中。
有序列表是指有数字编号或字母的列表项,可以使用css定义更多样式。
<!-- 有序列表 -->
<ol type="a">
<li>新闻一</li>
<li>新闻二</li>
<li>新闻三</li>
</ol>
属性 描述 type 设置符号类型 值:1 a A I i 默认数字 start 从第几个开始【用于ol标签中】 value 从第几个开始【用于li标签中】
<!-- 有序列表 -->
<ol type="a" start="4">
<li>新闻一</li>
<li type="1" value="1">新闻二</li>
<li>新闻三</li>
</ol>
无序列表是指没有数字编号或字母的列表项,可以使用css定义更多样式。
<!-- 无序列表 -->
<ul>
<li>童装</li>
<li>男装</li>
<li>女装</li>
</ul>
属性 描述 type 用于设置符号类型,默认:实心圆 值:空心圆、正方形 【用于ul、li】
<!-- 无序列表 -->
<ul type="square">
<li>童装</li>
<li type="circle">男装</li>
<li>女装</li>
</ul>
描述列表指每个列表项有单独的标题。
<!-- 描述列表 -->
<dl>
<dt>开源产品</dt>
<dd>Java封装库</dd>
<dd>Web组件库</dd>
<dt>网站导航</dt>
<dd>mrliujava.com</dd>
<dd>mrliuweb.com</dd>
</dl>
表格在网页开发中使用频率非常高,尤其是数据展示的时候。
标签 描述 table 代表表格标签 caption 表格标题 thead 表头部分 tbody 表格主体部分 tfoot 表格尾部
属性 描述 border 表格边框 cellspacing 单元格与单元格间距 width 宽度 height 高度 bgcolor 设置背景颜色 background 设置背景图片 align 对齐方式
<!-- 表格 -->
<table border="1" cellspacing="0" width="600px" height="200px">
<caption>员工薪资统计表</caption>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>职位</th>
<th>薪资</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>狗蛋</td>
<td>男</td>
<td>JavaEe工程师</td>
<td>8780</td>
</tr>
<tr>
<td>2</td>
<td>黑妞</td>
<td>女</td>
<td>Web前端工程师</td>
<td>9750</td>
</tr>
<tr>
<td>3</td>
<td>傻蛋</td>
<td>妖</td>
<td>测试工程师</td>
<td>996</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>当前页:1 页</td>
<td>上一页</td>
<td>下一页</td>
<td>尾页</td>
<td>共 3 页</td>
</tr>
</tfoot>
</table>
属性 说明 rowspan 行合并 colspan 列合并
下面是行合并:
<!-- 表格 -->
<table border="1" cellspacing="0" width="600px" height="200px">
<caption>员工薪资统计表</caption>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>职位</th>
<th>薪资</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>狗蛋</td>
<td>男</td>
<td rowspan="2">JavaEe工程师</td>
<td>8780</td>
</tr>
<tr>
<td>2</td>
<td>黑妞</td>
<td>女</td>
<td>9750</td>
</tr>
<tr>
<td>3</td>
<td>傻蛋</td>
<td>妖</td>
<td>测试工程师</td>
<td>996</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>当前页:1 页</td>
<td>上一页</td>
<td>下一页</td>
<td>尾页</td>
<td>共 3 页</td>
</tr>
</tfoot>
</table>
下面是列合并:
<!-- 表格 -->
<table border="1" cellspacing="0" width="600px" height="200px">
<caption>员工薪资统计表</caption>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>性别</th>
<th>职位</th>
<th>薪资</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>狗蛋</td>
<td>男</td>
<td>JavaEe工程师</td>
<td>8780</td>
</tr>
<tr>
<td>2</td>
<td>黑妞</td>
<td>女</td>
<td>Web前端工程师</td>
<td>9750</td>
</tr>
<tr>
<td>3</td>
<td colspan="2">傻蛋</td>
<td>测试工程师</td>
<td>996</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>当前页:1 页</td>
<td>上一页</td>
<td>下一页</td>
<td>尾页</td>
<td>共 3 页</td>
</tr>
</tfoot>
</table>
表单是一个包含表单元素的区域。
表单元素是允许用户在表单中输入内容,比如:文本域(textarea)、下拉列表(select)、单选框(radio)、复选框(checkbox)等等。
表单需要使用表单标签来设置:
<!-- 表单 -->
<form>
input元素
</form>
属性 说明 action 后台地址 method 提交方式GET或POST
GET和POST区别:
1.GET
2.POST
<form action="后端接口" method="POST">
<input type="text">
<input type="password">
</form>
使用label用于描述表单标题,当点击标题后文本框会获得焦点,需要保证使用的ID在页面中是唯一的。
<form action="后端接口" method="POST">
<label for="username">用户名</label>
<input type="text" id="username">
<label for="password">密码</label>
<input type="password" id="password">
</form>
也可以将文本框放在label标签内部,这样就不需要设置id与for属性了。
文本框用于输入单行文本使用,下面是常用属性与示例。
属性 说明 type 表单类型,默认为text name 后端接收字段名 required 必须输入 placeholder 提示文本内容 value 默认指 maxlength 允许最大输入字符数 size 表单长度,一般用css来控制 disabled 禁用,不可提交后端 readonly 只读,可提交后端 accept 设置选中类型 比如:.jpg capture 使用麦克风\视频或摄像头哪种方式获取手机上传文件,支持的值有microphone , video , camera
<form action="后端接口" method="POST">
<label for="username">用户名</label>
<input type="text" name="username" id="username" placeholder="请输入用户名" maxlength="5" size="50" required>
</form>
当input类型为file时手机会让用户选择图片或者拍照,如果想直接调取摄像头使用以下代码.
<form action="后端接口" method="POST">
<label for="file">上传文件</label>
<input type="file" name="file" id="file" accept="*.jpg" capture="camera">
</form>
通过设置表单的type字段可以指定不同的输入内容.
类型 说明 email 输入内容为邮箱 url 输入内容为URL地址 password 输入内容为密码项 tel 电话号,移动端会调出数字键盘 search 搜索框 hidden 隐藏表单 submit 提交表单 reset 重置表单 button 自定义按钮
隐藏表单用于提交后台数据,但在前台内容不显示所以在其上做用样式定义也没有意义.
<input type="hidden" name="id" value="1">
创建提交按钮可以将表单数据提交到后台,有多种方式可以提交数据,比如:AJAX,或者Html的表单按钮.
a.使用input构建提交按钮,如果设置了name值,那么按钮数据也会提交到后台,如果有多个表单项可以通过这些进行判断是哪个表单提交的.
<input type="submit" name="submit" value="提交表单">
b.使用button也可以提交,设置type属性为submit或不设置都可以提交表单.
<button type="submit">提交表单</button>
通过为表单设置disabled或readonly都可以禁止表单,单readonly表单的数据可以提交到后端
<input type="text" value="数据" readonly>
表单可以通过设置pattern属性指定正则验证.
属性 说明 pattern 正则表达式验证规则 oninvalid 输入错误时触发的事件
<form action="">
<label for="username">用户名</label>
<input type="text" name="username" id="username" pattern="[a-z]{5,20}" oninvalid="validate('请输入5~20位字母的用户名')">
<button>提交表单</button>
</form>
<script>
function validate(message){
alert(message);
}
</script>
文本域指可以输入多行文本的表单,当然更复杂的情况可以使用编辑器如ueditor , ckeditor等.
属性 说明 cols 列字符数(一般使用css控制更好) rows 行数(一般使用css控制更好)
<textarea cols="30" rows="3">请踩踩我......</textarea>
下拉列表项可用于多个值中的选择.
属性 说明 multiple 支持多选 size 列表框高度 optgroup 选项组 selected 选中状态 option 选项值
<form action="">
<select multiple size="10">
<option value="">选择课程</option>
<optgroup label="后端">
<option value="">JAVA</option>
<option value="">PHP</option>
<option value="">LINUX</option>
</optgroup>
<optgroup label="前端">
<option value="">HTML</option>
<option value="">CSS</option>
<option value="">JAVASCRIPT</option>
</optgroup>
</select>
</form>
单选框指只能选择一个选项的表单,如性别的选择:男 , 女 , 保密 只能选择一个.
属性 说明 checked 选中状态
<form action="">
<input type="radio" name="" id="boy" checked>
<label for="boy">男</label>
<input type="radio" name="" id="girl">
<label for="girl">女</label>
</form>
复选框指允许选择多个值的表单
属性 说明 checked 选中状态
<form action="">
<input type="checkbox" name="JAVA" id="java">
<label for="java">JAVA</label>
<input type="checkbox" name="WEB" id="web">
<label for="web">WEB</label>
</form>
文件上传有很多方式,可以使用插件或者JS拖放上传处理.Html本身也提供了默认的上传功能,只是上传效果并不是很美观.
属性 说明 multiple 支持多选 accept 允许上传类型.png , .psd 或者 image/png , image/gif
<form action="" enctype="multipart/form-data">
<input type="file">
<input type="submit" value="上传">
</form>
属性 说明 min 最小时间 max 最大时间 step 间隔: date缺省是1天 week缺省是1周 month缺省是1月
a.日期选择
<h1>日期选择</h1>
<form action="">
<input type="date" step="5" min="2020-09-22" max="2025-01-15" name="datetime">
</form>
b.周选择
<h1>周选择</h1>
<input type="week" name="" id="">
c.月份选择
<h1>月选择</h1>
<input type="month" name="" id="">
d.日期与时间
<h1>日期与时间</h1>
<input type="datetime-local" name="" id="">
input表单的输入值选项列表
<form action="">
<label for="username">用户名</label>
<input type="text" name="" id="usernmae" list="less">
<datalist id="less">
<option value="JAVA">后台管理语言</option>
<option value="CSS">美化网站页面</option>
<option value="MYSQL">掌握数据库使用</option>
</datalist>
</form>
frameset元素可定义一个框架集。它被用来组织多个窗口(框架),每个框架存有独立的文档,在其最简单的应用中,frameset元素仅仅会规定在框架集中存在多少列或多少行,您必须使用cols或rows属性。
注意事项:由于是分割原网页,所以我们不能在body中进行编写,在head中进行分割。
标签 说明 frameset 框架集 frame 框架
属性 说明 cols 定义框架集中列的数目和尺寸 rows 定义框架集中行的数目和尺寸 frame border 去除框架边框 scrolling 去除滚动条
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html垂直框架</title>
<frameset cols="50%,*" >
<frame src="http://www.baidu.com" frameborder="0" scrolling="no"></frame>
<frame src="http://www.taobao.com" frameborder="0" scrolling="no"></frame>
</frameset>
</head>
<body>
</body>
</html>
12.2 水平框架
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html水平框架</title>
<frameset rows="50%,*" >
<frame src="http://www.baidu.com" frameborder="0" scrolling="no"></frame>
<frame src="http://www.taobao.com" frameborder="0" scrolling="no"></frame>
</frameset>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html混合框架</title>
<frameset rows="20%,*" >
<frame src="http://www.baidu.com" frameborder="0" scrolling="no"></frame>
<frameset cols="20%,*">
<frame src="http://www.taobao.com" frameborder="0" scrolling="no"></frame>
<frame src="https://www.huya.com/" frameborder="0" scrolling="no"></frame>
</frameset>
</frameset>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html美女</title>
</head>
<body>
<img src="../images/10.jpg" alt="">
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html野兽</title>
</head>
<body>
<img src="../images/timg.gif" alt="">
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html动物</title>
</head>
<body>
<img src="../images/4.jpg" alt="">
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html链接</title>
</head>
<body>
<a href="Html美女.html" target="view">美女图片</a>
<a href="Html野兽.html" target="view">野兽图片</a>
<a href="Html动物.html" target="view">动物图片</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Html垂直框架</title>
<frameset rows="20%,*" >
<frame src="http://www.baidu.com" frameborder="0" scrolling="no"></frame>
<frameset cols="20%,*">
<frame src="Html链接.html" frameborder="0" scrolling="no"></frame>
<frame src="https://www.huya.com/" frameborder="0" scrolling="no" name="view"></frame>
</frameset>
</frameset>
</head>
<body>
</body>
</html>
iframe元素会创建包含另外一个文档的内联框架。
属性 说明 align 对齐方式,后期采用css的方式进行设置 width 设置宽度 height 设置高度 src 设置iframe中显示的文档的URL name iframe的名称 scrolling 是否显示滚动条 frameborder 设置iframe的边框
SS也是我们常叫的样式表、通俗叫切图和静态网页布局。我们知道HTML网页是由若干标签和内容组成。标签包括了div标签、span标签、a锚文本标签、strong加粗标签、b加粗标签、p段落标签、br换行标签等组成。而好看的网页样式却是CSS控制得出。一个完整漂亮网页,就是由html标签与控制这些标签布局和美化功能CSS组成。
注释标签:对代码进行说明
<!-- 单行注释,也可以对多行文字进行注释 -->
常用格式标签
<b>加粗</b>
<i>斜体</i>
<p>段落标签</p>
<hr>:分割线
<br>:换行
<strong>(粗字体)强调文本</strong>
标题标签
<h1>一级标题标签</h1>
<h2>二级标题标签</h2>
<h3>三级标题标签</h3>
<h4>四级标题标签</h4>
<h5>五级标题标签</h5>
<h6>六级标题标签</h6>
列表标签
<ul type="disc">
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
有序列表:
<ol type="1">
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ol>
CSS样式
内嵌样式:放在<head>标签之间
<style type="text/css">
选择器名 { 属性名:属性值;
}
</style>
所有标签(*)
* {
padding:0px; /*清除默认内边距*/
margin:0px; /*清除默认外边距*
}
超链接:
<a href="网页的网址" target="_blank">超链接文字或图片</a>
_blank:在新窗口打开网页
_self:在当前自身窗口打开网页
锚点链接
<a href="#锚点名">锚点链接:跳转链接</a>
<a name="锚点名">锚点名:要跳转到的位置</a>
大家在学习CSS的过程中,css标签属性是一定要了解的,希望本篇能给大家带来帮助。
天刷到了一个这样的短视频,我寻思我是不是也可以写一个类似的上课点名程序,想法经不起等待,说写就写~
私信小编01即可获取大量Python学习资源
Tkinter 是 python 内置的 TK GUI 工具集。TK 是 Tcl 语言的原生 GUI 库。作为 python 的图形设计工具,它所使用的 Tcl 语言环境已经完全嵌入到了 python 解释器中。
我们使用Tkinter开发GUI界面。
PIL(Python Image Library)库是Python语言的第三方库,需要通过pip工具安装。安装PIL库的方法如下,需要注意,安装库的名字是pillow。
PIL库支持图像储存、显示和处理,他能够处理几乎所有图片格式,可以完成对图像的缩放、剪裁、叠加以及向图像添加线条、图像和文字等操作。
使用PIL中的Image,ImageTk处理、引入一张图片,可以使用下面代码安装一下。
pip install pillow
双击打开后,进入软件主界面,所有功能一目了然。程序会自动识别软件目录下的names.txt,将里面的名字导入。
选择顺序点名后,点击开始,屏幕上就开始滚动出现人名,人名出现的概率是相同的,点击停止,人名就停止滚动,点名结束。
点击随机点名,程序就会进行随机点名,人名出现的概率是随机的。
可以自己手动选择人名单,前提是人名单格式为txt,且每个名字占一行。
用Pyqt5也写了一个版本,实现逻辑与TK版本相同,界面可能更好看了一些,但是文件大了许多,大家可以在后面总结部分自取。
import random
import re
import time
import threading
from tkinter import *
from tkinter import ttk
from base64 import b64decode
from PIL import Image,ImageTk
from tkinter import messagebox
from tkinter.filedialog import askopenfilename
""""
2021-11-10点名/抽奖程序
主要亮点:
1.两种模式:
①顺序点名
②随机点名
2.自动识别人名单
3.支持手动导入人名单
4.人名单导入校验
5.人名显示位置自动矫正
6.最多显示五个大字
"""
imgs=['./point_name.png']
class APP:
def __init__(self):
self.root = Tk()
self.running_flag=False #开始标志
self.time_span=0.05 #名字显示间隔
self.root.title('Point_name-V1.0')
width = 680
height = 350
left = (self.root.winfo_screenwidth() - width) / 2
top = (self.root.winfo_screenheight() - height) / 2
self.root.geometry("%dx%d+%d+%d" % (width, height, left, top))
self.root.resizable(0,0)
self.create_widget()
self.set_widget()
self.place_widget()
self.root.mainloop()
def create_widget(self):
self.label_show_name_var=StringVar()
self.label_show_name=ttk.Label(self.root,textvariable=self.label_show_name_var,font=('Arial', 100,"bold"),foreground = '#1E90FF')
self.btn_start=ttk.Button(self.root,text="开始",)
self.btn_load_names=ttk.Button(self.root,text="手动加载人名单",)
self.lf1=ttk.LabelFrame(self.root,text="点名方式")
self.radioBtn_var=IntVar()
self.radioBtn_var.set(1)
self.radioBtn_sequence=ttk.Radiobutton(self.lf1,text="顺序点名",variable=self.radioBtn_var, value=1)
self.radioBtn_random=ttk.Radiobutton(self.lf1,text="随机点名",variable=self.radioBtn_var, value=2)
self.label_show_name_num=ttk.Label(self.root,font=('Arial', 20),foreground = '#FF7F50')
paned = PanedWindow(self.root)
self.img = imgs
img_=b'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'
the_img = b64decode(img_)#将图片硬编码到GUI
paned.image = ImageTk.PhotoImage(data=the_img)
self._img = Label(self.root, image=paned.image,background='black')
def set_widget(self):
default_name_="会是谁?"
self.label_show_name_var.set(default_name_)
self.label_show_name_adjust(default_name_)
self.btn_start.config(command=lambda :self.thread_it(self.start_point_name))
self.btn_load_names.config(command=self.load_names)
init_names=self.load_names_txt("./names.txt")
self.root.protocol('WM_DELETE_WINDOW',self.quit_window)
self.root.bind('<Escape>',self.quit_window)
if init_names:
self.default_names=init_names #1.文件存在但是无内容。2.文件不存在
self.label_show_name_num.config(text=f"一共加载了{len(self.default_names)}个姓名")
else:
self.btn_start.config(state=DISABLED)
self.label_show_name_num.config(text=f"请先手动导入人名单!")
def place_widget(self):
self.lf1.place(x=300,y=160,width=250,height=50)
self.radioBtn_sequence.place(x=20,y=0)
self.radioBtn_random.place(x=150,y=0)
self.btn_start.place(x=300,y=220,width=100,height=30)
self.btn_load_names.place(x=450,y=220,width=100,height=30)
self._img.place(x=90, y=165, height=120, width=180)
self.label_show_name_num.place(x=300,y=260)
def label_show_name_adjust(self,the_name):
if len (the_name)==1:
self.label_show_name.place(x=280, y=10)
elif len(the_name) == 2:
self.label_show_name.place(x=180, y=10)
elif len(the_name) == 3:
self.label_show_name.place(x=120, y=10)
elif len(the_name) == 4:
self.label_show_name.place(x=80, y=10)
else:
self.label_show_name.place(x=0, y=10)
def start_point_name(self):
"""
启动之前进行判断,获取点名模式
:return:
"""
if len(self.default_names)==1:
messagebox.showinfo("提示",'人名单就一个人,不用选了!')
self.label_show_name_var.set(self.default_names[0])
self.label_show_name_adjust(self.default_names[0])
return
if self.btn_start["text"]=="开始":
self.btn_load_names.config(state=DISABLED)
self.running_flag=True
if isinstance(self.default_names,list):
self.btn_start.config(text="就你了")
if self.radioBtn_var.get()==1:
mode="sequence"
elif self.radioBtn_var.get()==2:
mode="random"
else:
pass
self.thread_it(self.point_name_begin(mode))
else:
messagebox.showwarning("警告","请先导入人名单!")
else:
self.running_flag=False
self.btn_load_names.config(state=NORMAL)
self.btn_start.config(text="开始")
def point_name_begin(self,mode):
"""
开始点名,点名主函数
:param mode:
:return:
"""
if mode == "sequence":
if self.running_flag:
self.always_ergodic()
elif mode=="random":
while True:
if self.running_flag:
random_choice_name=random.choice(self.default_names)
self.label_show_name_var.set(random_choice_name)
self.label_show_name_adjust(random_choice_name)
time.sleep(self.time_span)
else:
break
def always_ergodic(self):
"""
一直遍历此列表,使用死循环会造成线程阻塞
:return:
"""
for i in self.default_names:
if self.running_flag:
self.label_show_name_var.set(i)
self.label_show_name_adjust(i)
time.sleep(self.time_span)
if i==self.default_names[-1]:
self.always_ergodic()
else:
break
def load_names(self):
"""
手动加载txt格式人名单
:return:
"""
filename = askopenfilename(
filetypes = [('文本文件', '.TXT'), ],
title = "选择一个文本文件",
initialdir="./"
)
if filename:
names=self.load_names_txt(filename)
if names:
self.default_names=names
no_Chinese_name_num=len([n for n in names if not self.load_name_check(n)])
if no_Chinese_name_num==0:
pass
else:
messagebox.showwarning("请注意",f'导入名单有{no_Chinese_name_num}个不是中文名字')
self.label_show_name_num.config(text=f"一共加载了{len(self.default_names)}个姓名")
default_name_ = "会是谁?"
self.label_show_name_var.set(default_name_)
self.label_show_name_adjust(default_name_)
self.btn_start.config(state=NORMAL)
else:
messagebox.showwarning("警告","导入失败,请检查!")
def load_names_txt(self,txt_file):
"""
读取txt格式的人名单
:param txt_file:
:return:
"""
try:
with open(txt_file,'r',encoding="utf-8")as f:
names=[name.strip() for name in f.readlines()]
if len(names)==0:
return False
else:
return names
except:
return False
def load_name_check(self,name):
"""
对txt文本中的人名进行校验
中文汉字->True
非中文汉字->False
:param name:
:return:
"""
regex = r'[\u4e00-\u9fa5]+'
if re.match(regex,name):
return True
else:
return False
def thread_it(self,func,*args):
t=threading.Thread(target=func,args=args)
t.setDaemon(True)
t.start()
def quit_window(self,*args):
"""
程序退出触发此函数
:param args:
:return:
"""
ret=messagebox.askyesno('退出','确定要退出?')
if ret:
self.root.destroy()
if __name__ == '__main__':
a=APP()
本次使用Tkinter开发了一款上课点名程序,此程序可以用于点名、抽奖…代码不到200行,程序简单又实用,主要有以下六个亮点:
1.两种模式:
2.自动识别人名单
3.支持手动导入人名单
4.人名单导入校验
5.人名显示位置自动矫正
6.最多显示五个大字
*请认真填写需求信息,我们会在24小时内与您取得联系。