【问题标题】:tkinter - Can a radio button control multiple variables?tkinter - 单选按钮可以控制多个变量吗?
【发布时间】:2020-04-10 16:23:12
【问题描述】:

我正在使用 tkinter 模块编写一个日历程序,单击网格上的每一天将打印出当天的日期(月/日/年)。但是,我还想在底部添加另一个部分,显示一年中的哪一天。像这样:

例如,2020 年 1 月 1 日是一年中的第一天,3 月 20 日是一年中的第 80 天,等等。我希望我的单选按钮能够控制这两个变量,日期为一个字符串,一年中的日期为整数。这可能吗?

strDate = StringVar()
labelDate = Label(frameDay, textvariable=strDate, width=28, 
                  font=("Consolas", "15", "bold")).grid(row=1, column=1)

# Creating the calendar grid
while day <= self.returnMaxDay():
    currentDay = Date(self.month, day, self.year)
    radDay = Radiobutton(frameCalendar, text=str(day), 
                         font=("Consolas", "15", "bold"), indicatoron=0, width=4, height=1, 
                         variable=strDate, value=str(currentDay.returnDayName()) + ", " 
                                                 + str(currentDay.returnMonthName()) + " "
                                                 + str(day) + ", " + str(currentDay.year))
    radDay.grid(row=row, column=weekDay)
    day += 1
    weekDay += 1

    if weekDay == 7:
        row += 1
        weekDay = 0

labelDayOfYear = Label(window, text=str(self.dayOfYear()), font=("Consolas", "20")).pack()

【问题讨论】:

  • 通过command 选项关联回调,并将所需的变量设置为回调中所需的变量。
  • @acw1668 由于我使用 while 循环创建了单选按钮,因此该变量仅采用 while 循环的最后一次迭代,始终为 28、29、30 或 31。我是不确定command 是否有效。
  • brien:它会起作用,只是你做得不对(但我不能告诉你如何在没有看到你的代码的情况下修复它)。此外,在几个地方,您将调用 grid()pack()(始终为 None)的结果分配给变量。
  • 3 月 20 日将是一年中的第 80 天:您如何计算?因为variable= 跟在value= 后面,所以你不能,但你可以从value 字符串构建一个datetime 对象。
  • 如果你 command=lambda:... 在循环中,那么你可能必须使用 lambda arg=x:... 来正确赋值 command=lambda arg=x:function(arg) 而不是 `command=lambda:function(x)

标签: python python-3.x tkinter


【解决方案1】:

这是一个简单的例子,它使用Radiobutton 中的command= 来运行将文本更改为三个Labels 的函数。

通常command= 期望函数的名称不带() 和参数,所以我使用lambda 来分配带参数的函数。

command=lambda d=current_day:on_click(d))

我还使用d=current_day 为每个函数创建新变量d。如果没有d=current_day,所有函数都将使用对同一变量current_day 的引用,并且所有函数都将使用current_day 中的相同(最后一个)值。

import tkinter as tk
import datetime

# --- functions ---

def on_click(value):
    print(value)
    label_date['text'] = value.strftime('%a, %b %d, %Y')
    label_day['text'] = value.strftime('Day: %d')
    label_weekday['text'] = value.strftime('Weekday: %a')

# --- main ---

root = tk.Tk()

radiobutton_var = tk.StringVar()

year = 2020
month = 4

row = 0

for day in range(1, 32):
    try:
        current_day = datetime.datetime(year, month, day)

        date_str = current_day.strftime('%a, %m %d, %Y')
        weekday = current_day.weekday()

        radiobutton_day = tk.Radiobutton(root,
                                text=str(day), 
                                indicatoron=0,
                                variable=radiobutton_var,
                                value=date_str,
                                #value=day,
                                command=lambda x=current_day:on_click(x))

        radiobutton_day.grid(row=row, column=weekday, sticky='we')

        if weekday == 6:
            row += 1
            radiobutton_day['bg'] = '#faa'

    except ValueError as ex:
        print(ex) 
        break

label_date = tk.Label(root, text='?')
label_date.grid(row=10, columnspan=10)

label_day = tk.Label(root, text='Day: ?')
label_day.grid(row=11, columnspan=10)

label_weekday = tk.Label(root, text='Weekday: ?')
label_weekday.grid(row=12, columnspan=10)

root.mainloop()


顺便说一句:我使用datetime 生成日期,使用try/except 在日期不正确时捕获错误。

我还使用strftime 来格式化日期 - 更多信息请参见页面strftime.org

【讨论】:

    猜你喜欢
    • 2020-11-29
    • 1970-01-01
    • 2015-09-11
    • 2018-01-24
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 2015-06-15
    • 2016-09-01
    相关资源
    最近更新 更多