五笔打字通主页
这篇文章讲一下“多选题”简易答题程序编程。因为上一篇文章讲了单选题的编程,所以多选题的编程就简单了,为什么这么说?因为我先复制粘贴单选题的代码,然后通过搜索替换的方法就可以把“多选题”的界面代码以及其它大部分代码完成,这用不了两,三分钟。
1. 将单选按钮创建代码改成多选按钮
搜索ra1替换成 ch1 搜索ra2替换成ch2
搜索ra3替换成 ch3 搜索ra4替换成ch4
搜索 Radiobutton 替换成 Checkbutton
搜索 Radiobutton 替换成 Checkbutton
搜索 单选题 替换成 多选题
2.将绑定的变量也改一下
去除ch1,ch2,ch3,ch4创建代码中的参数value=1,value=2,value=3,value=4 (这个参数对于Checkbutton组件没有用),然后把 var=IntVar() 改成4行代码:
var1=IntVar()
var2=IntVar()
var3=IntVar()
var4=IntVar()
在ch1,ch2,ch3,ch4创建代码中,把variable=var 分别改成 variable=var1 ,variable=var2 , variable=var3 ,variable=var4
3. 把la1创建创建代码中的height=2 改成 height=3 (因为多选题的题目内容字符多,最多要占3行)
4. 函数pddc 由于判断对错的代码要大幅度改变,所以把函数体的内容都删除,暂时改成一行代码pass
5. 在选项4,即ch4的创建代码后,我们要新创建一个按钮“选择好了”按钮,以后会通过点击这个按钮,来调用pddc函数来判断对错。这个“选择好了”的按钮的创建定位代码如下:
but0 = Button(root, text=" 选择好了 ", command=pddc) # 判断对错 but0.grid(row=6, column=0, sticky=W, padx=15,pady=5) # 7行1列,靠右,上下间距10像素
6. 由于新创建的按钮占用了row=6 所以,“上一题”“下一题”的but1,but2创建后,grid定位要由row=6 改成 row=7
7. 点击选择好了,判断完答题对错后,我们要显示一下正确的答案,我们再创建一个标签来显示正确答案,这个标签la3我把它安排在“上一题”的同一个表格框里(row=7,column=0),但是靠左显示(sticky=W)。
8. display() 函数里,var.set(0) 改成4行代码:
var1.set(0) # 取消原来的选择
var2.set(0)
var3.set(0)
var4.set(0)
同时增加一行代码,让标签3显示的答案暂时隐藏:
la3.config(text='') # 让答案提示消失
9. 把ch1,ch2,ch3,ch3创建代码里的 command=pddc 去除,因为多选题的判断对错函数,已经改成鼠标对“选择好了”按钮点击后调用。
10. 数据库由文件文件car1.txt 改为 chr2.txt 搜索car1.txt 替换成 car2.txt
car2.txt的内容也是我由我自己的软件《驾照理论考试速成》提取出来 的多选题,其中一个题目有相关图片,它的格式跟car1.txt完全一样。内容如下:
林某驾车以110公里/小时的速度在城市道路行驶,与一辆机动车追尾后弃车逃离,但被群众拦下。经鉴定,事发时林某血液中的酒精浓度为135.8毫克/百毫升。林某的主要违法行为是什么?,醉酒驾驶,超速驾驶,疲劳驾驶,肇事逃逸,124,, 本程序的原创来自"五笔打字通"(网名),他的网站是:wb86.com,wb98.com,baidu.com,163.com,wb86.com,wb98.com,baidu.com,163.com,12,, 周某夜间驾驶大货车在没有路灯的城市道路上以90公里/小时的速度行驶,一直开启远光灯,在通过一窄路时,因加速抢道,导致对面驶来的一辆小客车撞上右侧护栏。周某的主要违法行为是什么?,超速驾驶,不按规定会车,疲劳驾驶,不按规定使用灯光,124,, 这个小型客车驾车人有哪些违法行为?,接打手持电话,无证驾驶,酒后驾驶,未系安全带,1234,car_2.gif, 行车中驾驶人接打手机或发短信有什么危害?,影响乘车人休息,分散驾驶注意力,影响正常驾驶操作,遇紧急情况反应不及,234,, 下列做法哪些可以有效避免驾驶疲劳?,连续驾驶不超过4小时,用餐不宜过饱,保持良好的睡眠,餐后适当休息后驾车,1234,, 驾驶汽车不系安全带在遇紧急制动或发生碰撞时可能会发生哪些危险?,撞击风窗玻璃,减少人员伤亡,被甩出车外,造成胸部损伤,123,, 驾驶汽车从支线道路怎样安全汇入主干道车流?,提前开启左转向灯,仔细观察主干道内情况,确认安全后汇入车流,加速直接汇入车流,123,,
大家把上面的内容,保存为car2.txt,编码为utf-8,保存到你的编程目录里
第3题有一个图片,car_2.gif,如下:
判断对错的2张图,跟“单选题”一样,分别为d.png和c.png :
把上面的3张图片保存到编程目录里的image子目录里。
from tkinter import * def next(): # 下一题 global number number += 1 if number + 1 > len(line): # 说明到最后一条记录的后面 number = 0 # 回到第1条记录 display() def previous(): # 上一题 global number number -= 1 if number == -1: # 说明到了第1条记录的前面 number = len(line)-1 # 回到最后1条记录 display() def display(): # 界面题目,答案等显示 global img1, id, str1 # img1不定义为全局变量,图像可能无法显示 id = str(number+1)+". " # 序号 str1 = line[number].split(',') # 读取新一行记录 la1.config(text=id+str1[0]) # 题目前面加序号 if str1[6] == '': img1 = PhotoImage() # 没有相关图片 else: img1 = PhotoImage(file='.\\image\\'+str1[6]) # 图片是在安装目录下的image文件夹里 la2.config(image=img1) # 重新设置,根据str1[6]内容来改变图片 ch1.config(text='A. '+str1[1]) # 答案1加上A. ch2.config(text='B. '+str1[2]) # 答案1加上B. ch3.config(text='C. '+str1[3]) # 答案1加上C. ch4.config(text='D. '+str1[4]) # 答案1加上D. var1.set(0) # 取消原来的选择 var2.set(0) # 取消原来的选择 var3.set(0) # 取消原来的选择 var4.set(0) # 取消原来的选择 ch1.config(image='') # 初始,让勾、X图都消失 ch2.config(image='') ch3.config(image='') ch4.config(image='') la3.config(text='') # 让答案提示消失 def pddc(): # 点击选项,判断对错 pass root = Tk() root.winfo_height() root.winfo_width() root.title("多选题") root.columnconfigure(0, minsize=250) # 设置grid布局0列最小宽度 root.columnconfigure(1, minsize=250) # 设置grid布局1列最小宽度 root.resizable(False, 1) # 禁止手动调节窗体尺寸 root.geometry('+666+444') # 设置窗体的位置 root.minsize(525,230) # 设置窗体宽与高的最小尺寸,这是无图片时窗体尺寸 with open('car2.txt', 'r', encoding='utf-8') as file: # 只读方式打开编码为utf-8的文本文件 number = 0 # 文本文件中的行号,即 line = file.readlines() # 以读取一行为列表方法读取全部行,line为分解好的列表内容 str1 = line[0].split(',') # 以英文,号来分解第1行,获取题目,答案1,答案2...... # str1[0]:题目 str1[1]:选项1 str1[2]:选项2 str1[3]:选项3 str1[4]:选项4 # str1[5]:答案 str1[6]:图片名 id = str(number+1)+". " # 题目序号 来自wb98.c0m何老师的济亨网 la1 = Label(root, text=id+str1[0], justify="left", height=3, anchor=W, wraplength=500) # 题目,靠左,多行左对齐,像素500换行 la1.grid(padx=10, pady=2, sticky=W+E, columnspan=2) if str1[6] == '': img1 = PhotoImage() # 没有相关图片 else: img1 = PhotoImage(file='.\\image\\'+str1[6]) # 图片是在安装目录下的image文件夹里 la2 = Label(root, image=img1) # 标签2用于显示题目相关的图片 la2.grid(padx=10, columnspan=2) var1 = IntVar() var2 = IntVar() var3 = IntVar() var4 = IntVar() ch1 = Checkbutton(root, text='A. ' + str1[1], variable=var1, justify="left", wraplength=430) # 选项1,靠左,多行左对齐,460像素换行 ch1.grid(padx=10, sticky=W, columnspan=2) ch2 = Checkbutton(root, text='B. ' + str1[2], variable=var2, justify="left", wraplength=430) # 选项2,靠左,多行左对齐,460像素换行 ch2.grid(padx=10, sticky=W, columnspan=2) ch3 = Checkbutton(root, text='C. ' + str1[3], variable=var3, justify="left", wraplength=430) # 选项3,靠左,多行左对齐,460像素换行 ch3.grid(padx=10, sticky=W, columnspan=2) ch4 = Checkbutton(root, text='D. ' + str1[4], variable=var4, justify="left", wraplength=430) # 选项4,靠左,多行左对齐,460像素换行 ch4.grid(padx=10, sticky=W, columnspan=2) but0 = Button(root, text=" 选择好了 ", command=pddc) # 判断对错 but0.grid(row=6, column=0, sticky=W, padx=15,pady=5) # 7行1列,靠右,上下间距10像素 but0.grid(row=6, column=0, sticky=W, padx=15,pady=5) # 7行1列,靠右,上下间距10像素 la3=Label(root) la3.grid(row=7,padx=15,sticky=W) but1 = Button(root, text=" 上一题 ", command=previous) but1.grid(row=7, column=0, sticky=E, pady=10) # 7行1列,靠右,上下间距10像素 but2 = Button(root, text=" 下一题 ", command=next) but2.grid(row=7, column=1, sticky=W, pady=10) # 7行2列,靠左,上下间距10像素 img2 = PhotoImage(file='./image/d.png') # 打勾图对象 img3 = PhotoImage(file='./image/c.png') # 打X图对象 root.mainloop()
运行结果如下:
在界面上,转换题目上,没有发现问题。
此文章来自:wb98.com
现在开始重新编写判断对错函数: pddc 这个函数是由点击“选择好了”来调用。
多选题判断对错,我是这样设想的:
1. 如果答案包含某个答案(如1),那么:
而且这个答案(如选项1)勾选,那么打勾
如果这个答案(如选项1)没有勾选,那么打X
否则,答案不包含某个答案(如1),那么:
而且这个答案(如选项1)勾选,那么打X
如果这个答案(如选项1)没有勾选,我们不处理。
2. 判断对错函数的代码,我先把img2,img3这2个图片对象定义为全局变量,不这样做,打勾,打X图片就无法显示。然后初始化,把打勾,打X都隐藏,再根据选择和答案来判断对错。
3. 在函数最后,我们加入标签3显示正确答案的代码,我们先把答案str1[5]用replace方法,把答案如1234这种格式转为ABCD样式。
def pddc(): # 点击选项,判断对错 global img2, img3 ch1.config(image='') # 初始,让勾、X图都消失 ch2.config(image='') ch3.config(image='') ch4.config(image='') if str1[5].count('1')==1: # 如果答案包含有1 if var1.get()==1: # 而且勾选了选项1 ch1.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch1.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var1.get()==1: # 却勾选了 ch1.config(image=img3, compound='right') # 打X if str1[5].count('2')==1: # 如果答案包含有2 if var2.get()==1: # 而且勾选了选项1 ch2.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch2.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var2.get()==1: # 却勾选了 ch2.config(image=img3, compound='right') # 打X if str1[5].count('3')==1: # 如果答案包含有3 if var3.get()==1: # 而且勾选了选项1 ch3.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch3.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var3.get()==1: # 却勾选了 ch3.config(image=img3, compound='right') # 打X if str1[5].count('4')==1: # 如果答案包含有1 if var4.get()==1: # 而且勾选了选项1 ch4.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch4.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var4.get()==1: # 却勾选了 ch4.config(image=img3, compound='right') # 打X ls=str1[5].replace("1", "A") ls=ls.replace("2", "B") ls=ls.replace("3", "C") ls=ls.replace("4", "D") la3.config(text='正确答案是:' + ls)
经测试,这种判断没有问题,目前我们所学tkinter知识不多,这种判断对错的方法虽然繁琐,但也管用。 丶丌皛
以下是全部代码,在我的win10电脑里测试没有发现问题。
from tkinter import * def next(): # 下一题 global number number += 1 if number + 1 > len(line): # 说明到最后一条记录的后面 number = 0 # 回到第1条记录 display() def previous(): # 上一题 global number number -= 1 if number == -1: # 说明到了第1条记录的前面 number = len(line)-1 # 回到最后1条记录 display() def display(): # 界面题目,答案等显示 global img1, id, str1 # img1不定义为全局变量,图像可能无法显示 id = str(number+1)+". " # 序号 str1 = line[number].split(',') # 读取新一行记录 la1.config(text=id+str1[0]) # 题目前面加序号 if str1[6] == '': img1 = PhotoImage() # 没有相关图片 else: img1 = PhotoImage(file='.\\image\\'+str1[6]) # 图片是在安装目录下的image文件夹里 la2.config(image=img1) # 重新设置,根据str1[6]内容来改变图片 ch1.config(text='A. '+str1[1]) # 答案1加上A. ch2.config(text='B. '+str1[2]) # 答案1加上B. ch3.config(text='C. '+str1[3]) # 答案1加上C. ch4.config(text='D. '+str1[4]) # 答案1加上D. var1.set(0) # 取消原来的选择 var2.set(0) # 取消原来的选择 var3.set(0) # 取消原来的选择 var4.set(0) # 取消原来的选择 ch1.config(image='') # 初始,让勾、X图都消失 ch2.config(image='') ch3.config(image='') ch4.config(image='') la3.config(text='') # 让答案提示消失 def pddc(): # 点击选项,判断对错 global img2, img3 # 源码作者:何云峰 ch1.config(image='') # 初始,让勾、X图都消失 ch2.config(image='') ch3.config(image='') ch4.config(image='') # 作者网站 wb98.com if str1[5].count('1')==1: # 如果答案包含有1 if var1.get()==1: # 而且勾选了选项1 ch1.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch1.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var1.get()==1: # 却勾选了 ch1.config(image=img3, compound='right') # 打X if str1[5].count('2')==1: # 如果答案包含有2 if var2.get()==1: # 而且勾选了选项1 ch2.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch2.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var2.get()==1: # 却勾选了 ch2.config(image=img3, compound='right') # 打X if str1[5].count('3')==1: # 如果答案包含有3 if var3.get()==1: # 而且勾选了选项1 ch3.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch3.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var3.get()==1: # 却勾选了 ch3.config(image=img3, compound='right') # 打X if str1[5].count('4')==1: # 如果答案包含有1 if var4.get()==1: # 而且勾选了选项1 ch4.config(image=img2, compound='right') # 打勾 else: # 没有勾选 ch4.config(image=img3, compound='right') # 打X else: # 如果答案里没有包含1 if var4.get()==1: # 却勾选了 ch4.config(image=img3, compound='right') # 打X ls=str1[5].replace("1", "A") ls=ls.replace("2", "B") ls=ls.replace("3", "C") ls=ls.replace("4", "D") la3.config(text='正确答案是:' + ls) root = Tk() root.winfo_height() root.winfo_width() root.title("多选题") root.columnconfigure(0, minsize=250) # 设置grid布局0列最小宽度 root.columnconfigure(1, minsize=250) # 设置grid布局1列最小宽度 root.resizable(False, 1) # 禁止手动调节窗体尺寸 root.geometry('+666+444') # 设置窗体的位置 root.minsize(525,230) # 设置窗体宽与高的最小尺寸,这是无图片时窗体尺寸 with open('car2.txt', 'r', encoding='utf-8') as file: # 只读方式打开编码为utf-8的文本文件 number = 0 # 文本文件中的行号,即 line = file.readlines() # 以读取一行为列表方法读取全部行,line为分解好的列表内容 str1 = line[0].split(',') # 以英文,号来分解第1行,获取题目,答案1,答案2...... # str1[0]:题目 str1[1]:选项1 str1[2]:选项2 str1[3]:选项3 str1[4]:选项4 # str1[5]:答案 str1[6]:图片名 id = str(number+1)+". " # 题目序号 来自wb98.c0m何老师的济亨网 la1 = Label(root, text=id+str1[0], justify="left", height=3, anchor=W, wraplength=500) # 题目,靠左,多行左对齐,像素500换行 la1.grid(padx=10, pady=2, sticky=W+E, columnspan=2) if str1[6] == '': img1 = PhotoImage() # 没有相关图片 else: img1 = PhotoImage(file='.\\image\\'+str1[6]) # 图片是在安装目录下的image文件夹里 la2 = Label(root, image=img1) # 标签2用于显示题目相关的图片 la2.grid(padx=10, columnspan=2) var1 = IntVar() var2 = IntVar() var3 = IntVar() var4 = IntVar() ch1 = Checkbutton(root, text='A. ' + str1[1], variable=var1, justify="left", wraplength=430) # 选项1,靠左,多行左对齐,460像素换行 ch1.grid(padx=10, sticky=W, columnspan=2) ch2 = Checkbutton(root, text='B. ' + str1[2], variable=var2, justify="left", wraplength=430) # 选项2,靠左,多行左对齐,460像素换行 ch2.grid(padx=10, sticky=W, columnspan=2) ch3 = Checkbutton(root, text='C. ' + str1[3], variable=var3, justify="left", wraplength=430) # 选项3,靠左,多行左对齐,460像素换行 ch3.grid(padx=10, sticky=W, columnspan=2) ch4 = Checkbutton(root, text='D. ' + str1[4], variable=var4, justify="left", wraplength=430) # 选项4,靠左,多行左对齐,460像素换行 ch4.grid(padx=10, sticky=W, columnspan=2) but0 = Button(root, text=" 选择好了 ", command=pddc) # 判断对错 but0.grid(row=6, column=0, sticky=W, padx=15,pady=5) # 7行1列,靠右,上下间距10像素 but0.grid(row=6, column=0, sticky=W, padx=15,pady=5) # 7行1列,靠右,上下间距10像素 la3=Label(root) la3.grid(row=7,padx=15,sticky=W) but1 = Button(root, text=" 上一题 ", command=previous) but1.grid(row=7, column=0, sticky=E, pady=10) # 7行1列,靠右,上下间距10像素 but2 = Button(root, text=" 下一题 ", command=next) but2.grid(row=7, column=1, sticky=W, pady=10) # 7行2列,靠左,上下间距10像素 img2 = PhotoImage(file='./image/d.png') # 打勾图对象 img3 = PhotoImage(file='./image/c.png') # 打X图对象 root.mainloop()
运行结果:
下一篇文章,我们开始新的知识学习,学习弹出提示窗口知识:messagebox
来源:济亨网
本文链接:http://wb86.com/post/311.html