當前位置:首頁 ? tkinter ? 正文

用tkinter的畫布組件canvas做答題系統,有源碼

  上上一篇文章,我用一個多行文本框做了一個答題系統,我發現有一個問題,應該跟我的代碼沒有什么關系,就是文本框滾動起來,用單選框按鈕,復選框按鈕做的答題選項,顯示起來不是很流暢;另外,在滾動時,如果鼠標是在答案的4個選項上,那就滾動不起來,因為我沒有為這個4選項做綁定鼠標滾動事件的代碼。

  我決定用畫布也用一個答題系統,再加上題目及答案組件的鼠標滾動事件綁定代碼,現在做好了,測試結果,在鼠標滾動起來時,題目,答案選項都顯示得很流暢,在畫布上任何位置都可以用上鼠標滾動題目查看。

  只是在畫布上插入顯示各組件的方法跟多行文本框還是有區別,所以在顯示方法花了不少時間,至少導入題庫,核對答案就跟上上篇文章寫的差不多了,有不理解的,可以查看上上一篇文章。

  為了在循環中動態生成各組件及變量,我采用的是先創建相關字典的辦法。

  全部代碼如下:

from tkinter import *
import webbrowser

def wb98():
    webbrowser.open('http://www.wb98.com',new=1)
def Wheel_y(event):
    a= int(-(event.delta)/60)
    can1.yview('scroll',a,'units')

root=Tk()  # 源碼來自wb98.com
root.title('用畫布做一個答題系統 wb98.com')
scr1=Scrollbar(root)  # 垂直滾動條
scr1.pack(side=RIGHT,fill=Y) 

can1=Canvas(root,bg='lightblue',width=10,height=10) # 畫面設置一個淺藍色,便于你看清各組件的位置
can1.pack(side=LEFT,expand=True,fill=BOTH) # 畫布定位

with open('car3.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]:圖片名

la=dict() # 題目字典
img = dict()  # 生成一個空字典,用于下面循環地創建變量
# 以下設各變量為字典,便于循環時生成各組件插入Text組件
option1 = dict()  # 生成答案選項1組件字典
option2 = dict()  # 生成答案選項2字典
option3 = dict()  # 生成答案選項3字典
option4 = dict()  # 生成答案選項4字典
# 以下設各變量為字典,便于循環時生成各組件插入Text組件
var_ra = dict()
var_ch1 = dict()
var_ch2 = dict()
var_ch3 = dict()
var_ch4 = dict()
str_daan = ''  # 答案字符串初始化

x,y=10,10 # 坐標初始化
ff1=15 # 字體大小
ff2=10 # 字體大小
font1=('黑體',-ff1) # 字體大小前加- 表示是像素大小
font2=('宋體',-ff2)
hh=10 # 上下間距
bmp_h=200 # 圖片的高度

# 以下是循環出題的代碼 ------- 源碼作者:湖南·長沙·何云峰  網站: www.wb98.com
for i in range(1, 11):
    id = str(number+1)+":"  # 題目序號 來自wb98.com何老師的濟亨網
    # can1.create_text( x,y, text=str1[0], width=300 , font=font1 ,anchor=NW) # 題目--無法掌握高度,放棄
    
    la[i]=Label(can1,text=id+str1[0],justify=LEFT, font=font1)
    can1.create_window(x,y,window=la[i],anchor=NW)
    la[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
    y=y+ff1+hh # 下一組件的起始位置為當前位置+字體高+間隔

    if str1[6] == '':
        img[i] = PhotoImage()  # 沒有相關圖片
    else:
        img[i] = PhotoImage(file='.\\image\\'+str1[6])  # 圖片是在安裝目錄下的image文件夾里
        can1.create_image(x,y,image=img[i],anchor=NW)
        y=y+bmp_h+hh

    str_daan = str_daan + str1[5]+','  # 把答案記下來,交卷用于核對
    if len(str1[5]) == 1:  # 單選題
        
        var_ra[i] = IntVar(value=0)

        option1[i] = Radiobutton(can1, text='A. '+str1[1], bg='white',
                                 activebackground='white', variable=var_ra[i], value=1)
        can1.create_window(x,y,window=option1[i],anchor=NW)
        option1[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距

        option2[i] = Radiobutton(can1, text='B. '+str1[2], bg='white',
                                 activebackground='white', variable=var_ra[i], value=2)
        can1.create_window(x,y,window=option2[i],anchor=NW)
        option2[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距

        option3[i] = Radiobutton(can1, text='C. '+str1[3], bg='white',
                                 activebackground='white', variable=var_ra[i], value=3)
        can1.create_window(x,y,window=option3[i],anchor=NW)
        option3[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距

        option4[i] = Radiobutton(can1, text='D. '+str1[4], bg='white',
                                 activebackground='white', variable=var_ra[i], value=4)
        can1.create_window(x,y,window=option4[i],anchor=NW)
        option4[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距
        y=y+10
    else:
        var_ch1[i] = BooleanVar(value=False)
        var_ch2[i] = BooleanVar(value=False)
        var_ch3[i] = BooleanVar(value=False)
        var_ch4[i] = BooleanVar(value=False)

        option1[i] = Checkbutton(
            can1, text='A. '+str1[1], bg='white', activebackground='white', variable=var_ch1[i])
        can1.create_window(x,y,window=option1[i],anchor=NW)
        option1[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距

        option2[i] = Checkbutton(
            can1, text='B. '+str1[2], bg='white', activebackground='white', variable=var_ch2[i])
        can1.create_window(x,y,window=option2[i],anchor=NW)
        option2[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距

        option3[i] = Checkbutton(
            can1, text='C. '+str1[3], bg='white', activebackground='white', variable=var_ch3[i])
        can1.create_window(x,y,window=option3[i],anchor=NW)
        option3[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距

        option4[i] = Checkbutton(
            can1, text='D. '+str1[4], bg='white', activebackground='white', variable=var_ch4[i])
        can1.create_window(x,y,window=option4[i],anchor=NW)
        option4[i].bind("<MouseWheel>", Wheel_y) # 為組件綁定鼠標滾動事件
        y=y+ff2+4+hh # 下一個組件起始坐標:當前位置+字體大小+4個像素間距
        y=y+10

    number = number+1
    str1 = line[number].split(',')  # 讀取新一行記錄
# 以上是循環出題的代碼----------------------

def dafei():
    daan = str_daan.split(',')  # 把答案字符串分解

    for i in range(1, 11):  # 單選題
        if len(daan[i-1]) == 1:  # 單選題
            if daan[i-1] == str(var_ra[i].get()):
                print('第'+str(i)+"題回答正確")
            else:
                print('第'+str(i)+"題回答錯誤")
                print("    正確答案:" + daan[i-1])
                print("    你的答案:" + str(var_ra[i].get()))
        else:  # 多選題
            duo = ''
            if var_ch1[i].get() == True:
                duo = '1'
            if var_ch2[i].get() == True:
                duo = duo+'2'
            if var_ch3[i].get() == True:
                duo = duo+'3'
            if var_ch4[i].get() == True:
                duo = duo+'4'

            if daan[i-1] == duo:
                print('第'+str(i)+"題回答正確")
            else:
                print('第'+str(i)+"題回答錯誤")
                print("    正確答案:" + daan[i-1])
                print("    你的答案:" + duo)

y=y+hh*2 # 再加2個間隔,插入按鈕
but1 = Button(can1, text="    立 即 交 卷    ", command=dafei)  # 交卷打分
can1.create_window(x,y,window=but1,anchor=NW)

but1 = Button(can1, text="    訪 問 官 網    ", command=wb98)  # 交卷打分
can1.create_window(x+200,y,window=but1,anchor=NW)

can1.config(yscrollcommand = scr1.set) # 綁定垂直滾動條
scr1.config(command = can1.yview)

can1.config(scrollregion=(0,0,650,y+100)) # 保證滾動范圍正好是圖片的寬高

can1.bind("<MouseWheel>", Wheel_y) # 為畫布綁定鼠標滾動事件

root.geometry('700x650+588+224')
# root.wm_deiconify()  # 讓窗體顯現

root.mainloop()

運行結果:    丶丌皛

未命名.GIF

    在代碼中,我用字體大小,各組件間隔,組件的Y坐標都采取像素的單位,便于操作;上述代碼為了讓大家看到各組件的位置,各組件的顏色跟畫布不同,所以,你只要把組件的背景顏色,活動顏色改成跟背景顏色一致,就可以為你所用。

    此文章來自:wb98.com  網站還有相關的系列課程文章,感興趣的可以前往。

來源:濟亨網

本文鏈接:http://www.chinaengraver.com/post/346.html

    << 上一篇 下一篇 >>

    湘公網安備 43011102000514號 - 湘ICP備08100508號

    2019年秋霞鲁丝片瓜皮_导航亚洲AV日韩AV永久无码_有没有哪些可以看片的免费的_国产色妞妞在线视频免费播放