【问题标题】:Creating and Getting values from tkinter check boxes using for loop使用 for 循环从 tkinter 复选框创建和获取值
【发布时间】:2020-11-22 16:59:10
【问题描述】:

此代码是我项目的一部分,我必须管理 50 名(或更多)学生的出勤率。

我想要的是所有复选框最初都应该被“选中”(显示当前状态),当我取消选中随机复选框时(标记缺席)并单击Submit 按钮(尚未在窗口底部创建),我应该得到一个列表,其中“输入日期”作为第一个元素和卷号,即 2018-MC-XX和其他元素一样。

例如: ['01/08/2020', '2018-MC-7', '2018-MC-11', '2018-MC-23', '2018-MC-44']

实际上我的计划是当我得到一个列表时,我会很容易地将它写入一个文本文件。另外,如果有另一种方法可以创建多个可滚动复选框而不将它们打包在画布中,那么请告诉!

from tkinter import *
from tkcalendar import DateEntry

root = Tk()
root.geometry('920x600+270+50')
root.minsize(920,600)

Attendance_frame = Frame(root)    ### Consider it a Main Frame
Attendance_frame.pack()

attendaceBox = LabelFrame(Attendance_frame, text = 'Take Attendance', bd = 4, relief = GROOVE, labelanchor = 'n',font = 'Arial 10 bold', fg = 'navy blue', width = 850, height = 525)     # A Label Frame inside the main frame

attendaceBox.pack_propagate(0)
attendaceBox.pack(pady = 15)

dateFrame = Frame(attendaceBox)    # A small frame to accommodate date entry label & entry box
dateFrame.pack(anchor = 'w')

font = 'TkDefaultFont 10 bold'
date_label = Label(dateFrame, text = 'Enter Date : ', font = font).grid(row = 0, column =  0, sticky = 'w', padx = 10, pady = 10)

date_entry = DateEntry(dateFrame, date_pattern = 'dd/mm/yyyy', showweeknumbers = FALSE, showothermonthdays = FALSE)
date_entry.grid(row = 0, column = 1, sticky = 'w')

noteLabel = Label(attendaceBox, text = 'Note: Uncheck the boxes for absentees').pack(anchor = 'w', padx = 10, pady = 5)

canvas = Canvas(attendaceBox, borderwidth=0, background="#ffffff")
checkFrame = Frame(canvas, width = 100, height = 50)
vsb = Scrollbar(canvas, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)

vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
canvas.pack_propagate(0)
canvas.create_window((4,4), window=checkFrame, anchor="nw")

def onFrameConfigure(canvas):
    '''Reset the scroll region to encompass the inner frame'''
    canvas.configure(scrollregion=canvas.bbox("all"))

checkFrame.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas))

for i in range(0,51):     # A loop to create Labels of students roll numbers & names
    c = Checkbutton(checkFrame, text = f"{'2018-MC-'+str(i+1)}       Student {i+1}")
    c.grid(row = i, column = 0, padx = 10, sticky = 'w')


mainloop()

【问题讨论】:

  • 你能用简单的语言解释一下你期望什么和你得到了什么
  • 首先您需要为每个Checkbutton 提供StringVar,以便稍后获取Checkbutton 的状态。然后您可以使用一个列表来保存StringVars,以便您以后可以访问它们。您可以将复选按钮的onvalue 设置为与其关联的卷号。
  • 您可以使用Text 小部件来保存复选按钮(使用Text.window_create() 将复选按钮插入到Text 框中)。
  • @acw1668 你能用代码解释一下吗?

标签: python user-interface tkinter checkbox tkcalendar


【解决方案1】:

首先,您需要为每个 Checkbutton 提供StringVar,以便稍后获取Checkbuttons 的状态。然后您可以使用列表来保存StringVars,以便您以后可以访问它们。您可以将checkbuttonsonvalue 设置为与它们关联的卷号。

您也可以使用Text 小部件代替Canvas+Frame。下面是一个例子:

import tkinter as tk

root = tk.Tk()

frame = tk.Frame(root)
frame.pack()

text = tk.Text(frame, width=40, height=20)
text.pack(side=tk.LEFT, fill=tk.BOTH)

vars = []
for i in range(51):
    rollnum = '2018-MC-'+str(i+1)
    var = tk.StringVar(value=rollnum)
    cb = tk.Checkbutton(text, text=rollnum, variable=var, onvalue=rollnum, offvalue='', bg='white')
    text.window_create('end', window=cb)
    text.insert('end', '\n')
    vars.append(var)

vsb = tk.Scrollbar(frame, orient=tk.VERTICAL, command=text.yview)
vsb.pack(side=tk.RIGHT, fill=tk.Y)

text.config(yscrollcommand=vsb.set)

def submit():
    # extract roll numbers for checked checkbuttons
    result = [var.get() for var in vars if var.get()]
    print(result)

tk.Button(root, text='Submit', command=submit).pack()

root.mainloop()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    相关资源
    最近更新 更多