首页 > 解决方案 > 你能在不传递参数的情况下从 tk.OptionMenu 的命令参数调用函数吗

问题描述

我想检查用户是否更改了 tkinter 小部件中的任何值,然后提示保存这些值或丢失更改。

许多应用程序在其设置框架的右下角有 3 个按钮,OK在进行更改之前禁用其中的位置。我在我的程序中模仿这个功能。CancelApplyApply

当我使用tk.OptionMenu(command=function)时,默认情况下它会将当前用户选择发送到该功能,但是我不需要知道当前选择,因为无论它是什么,我都想提示用户保存设置。

运行程序会导致以下错误:

TypeError: function() 接受 0 个位置参数,但给出了 1 个

我想到的一个简单的解决方法是给一个任意参数,function()如下所示:

def function(param=None):
    value_change.status = True

有关用法,请参见示例代码。value_change.status

但是,PyCharm 指出param未使用并将其标记为弱警告。param我对传递的值没有任何用处,所以除了忽略它和 PyCharm 警告之外,我无能为力。从技术上讲,这里没有问题,但我喜欢在屏幕右上角看到那个绿色复选标记,所以我想出了另一个解决方法:

def function(param=None):
    value_change.status = True if param else False

两者param=Noneif param else False都是多余的,因为它们只是使代码顺利运行而不抛出任何警告的占位符。

function()当我想用于其他不传递参数的小部件命令时会出现另一个问题,例如tk.Checkbutton(command=function)我必须将我的代码更改为以下行,这使得代码看起来比以前更加冗余。

def function(param=True):
    value_change.status = True if param else False

有没有办法不通过争论tk.OptionMenu(command=function)

示例代码

import time
import tkinter as tk
from threading import Thread

def value_change():
    value_change.count = 0
    value_change.status = False

    print('Has the user changed settings in the past 3 seconds?')

    while value_change.status != 'exit':
        if value_change.status:
            value_change.count += 1
            
            # Reset count if no change after 3 seconds
            if value_change.count > 3:
                value_change.count = 0
                value_change.status = False

        print(value_change.status)
        time.sleep(1)

def function(param=True):
    value_change.status = True if param else False
    value_change.count = 0


gui = tk.Tk()
gui.geometry('100x100')

"""Setup OptionMenu"""
menu_options = ['var1', 'var2', 'var3']

menu_string = tk.StringVar()
menu_string.set(menu_options[0])

option_menu = tk.OptionMenu(gui, menu_string, *menu_options, command=function)
option_menu.pack()

"""Setup CheckButton"""
check_int = tk.IntVar()

check = tk.Checkbutton(gui, variable=check_int, command=function)
check.pack()

"""Turn On Thread and Run Program"""
Thread(target=value_change).start()
gui.mainloop()

"""Signal Threaded Function to Exit"""
value_change.status = 'exit'

上面的例子是一个最小的复制品,我没有包括OK Cancel Apply按钮及其功能,因为它们不是必需的,只会使代码冗长。

标签: pythontkinter

解决方案


您可以使用lambda

option_menu = tk.OptionMenu(gui, menu_string, *menu_options, command=lambda v: function())

推荐阅读