Изменение размера холста, равного размеру кадра в tkinter python - PullRequest
1 голос
/ 01 августа 2020

У меня два вопроса по этому приложенному коду. Этот код является частью моего проекта, в котором я должен управлять посещаемостью 50 (или более) студентов.

  1. Когда вы запустите этот фрагмент кода, вы увидите, что там - это дополнительное пустое пространство (которое может быть на холсте) внутри рамки метки, то есть Attendance_Frame. Все, что я хотел, - это чтобы не было лишних пробелов, а полоса прокрутки, вместо того, чтобы находиться в крайнем правом углу, была в том месте, где заканчиваются метки. Я искал ответ на свой вопрос и видел похожий случай. Но там человек хотел, чтобы рамка расширилась до размера холста. Ссылка ( Tkinter: как заставить рамку в окне холста расширяться до размера холста? ). Но в моем случае я хочу, чтобы размер холста был равен размеру кадра (хотя рамка лежит внутри холста)

  2. Еще я хочу, чтобы все флажки изначально были быть 'отмеченным' (показывающим текущее состояние), и когда я снимаю случайные флажки (чтобы отметить отсутствие) и нажимаю кнопку 'Отправить' (еще не созданную в нижней части окна), я должен получить список с ' введенная дата »в качестве первого элемента и номера роликов, например, 2018-M C -XX, в качестве других элементов. Например: ['01 / 08/2020 ',' 2018-M C -7 ',' 2018-M C -11 ',' 2018-M C -23 ',' 2018-M *. 1019 * -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()
    

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Если вы создаете вертикальный список элементов, вам не нужно использовать рамку внутри холста. Внутренний каркас добавляет ненужной сложности. Вместо этого создайте контрольные кнопки прямо на холсте с помощью create_window.

Вам также необходимо настроить атрибут scrollregion, чтобы полоса прокрутки знала, какую часть виртуального холста нужно прокручивать.

Наконец, чтобы они были выбраны, вы должны назначить переменную каждой контрольной кнопке и убедиться, что значение является правильным. По умолчанию контрольные кнопки используют значения 0 и 1, поэтому установка переменной на 1 сделает ее выбранной.

vars = []
for i in range(0,51):
    var = IntVar(value=1)
    vars.append(var)
    x0, y0, x1, y1 = canvas.bbox("all") or (0,0,0,0)
    c = Checkbutton(canvas, text = f"{'2018-MC-'+str(i+1)}       Student {i+1}", variable=var)
    canvas.create_window(2, y1+4, anchor="nw", window=c)
canvas.configure(scrollregion=canvas.bbox("all"))
0 голосов
/ 02 августа 2020

Ответы на все ваши вопросы здесь:

Вы должны попробовать это.

import tkinter as tk
from tkcalendar import DateEntry

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

root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
Attendance_frame = tk.Frame(root)
Attendance_frame.grid(row=0, column=0, sticky='nsew')

attendaceBox = tk.LabelFrame(Attendance_frame,
                             text='Take Attendance',
                             bd=4,
                             relief='groove',
                             labelanchor='n',
                             font='Arial 10 bold',
                             fg='navy blue',
                             width=850,
                             height=525)
attendaceBox.grid(row=0, column=0, sticky='nsew', padx=15)

Attendance_frame.columnconfigure(0, weight=1)
Attendance_frame.rowconfigure(0,weight=1)

dateFrame = tk.Frame(attendaceBox)  # A small frame to accommodate date entry label & entry box
dateFrame.grid(row=0, column=0, sticky='nsew')

font = 'TkDefaultFont 10 bold'
date_label = tk.Label(dateFrame, text='Enter Date : ', font=font)
date_label.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 = tk.Label(attendaceBox, text='Note: Uncheck the boxes for absentees', anchor='w')
noteLabel.grid(row=1, column=0, sticky='nsew')

attendaceBox.rowconfigure(2, weight=1)
canvas = tk.Canvas(attendaceBox, width=200, borderwidth=0, background="#ffffff")
# You can set width of canvas according to your need
canvas.grid(row=2, column=0, sticky='nsew')
canvas.columnconfigure(0, weight=1)
canvas.rowconfigure(0, weight=1)
vsb = tk.Scrollbar(attendaceBox, orient="vertical", command=canvas.yview)
vsb.grid(row=2, column=1, sticky='nsew')
canvas.configure(yscrollcommand=vsb.set)

checkFrame = tk.Frame(canvas, bg='green')
canvas.create_window((0, 0), window=checkFrame, anchor="nw", tags='expand')
checkFrame.columnconfigure(0, weight=1)



for i in range(0, 51):  # A loop to create Labels of students roll numbers & names
    c = tk.Checkbutton(checkFrame, anchor='w', text=f"{'2018-MC-' + str(i + 1)}       Student {i + 1}")
    c.grid(row=i, column=0, sticky='nsew')
    c.select()
canvas.bind('<Configure>', lambda event: canvas.itemconfigure('expand', width=event.width))
checkFrame.update_idletasks()
canvas.config(scrollregion=canvas.bbox('all'))


root.mainloop()

Получить выбранное значение

vars = []
for i in range(0, 51):  # A loop to create Labels of students roll numbers & names
    var = tk.IntVar()
    c = tk.Checkbutton(checkFrame,
                       variable=var,
                       anchor='w', text=f"{'2018-MC-' + str(i + 1)}       Student {i + 1}")
    c.grid(row=i, column=0, sticky='nsew')
    c.select()
    vars.append(var)


def state():
    print(list(map((lambda var: var.get()), vars)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...