টিনকিনারে একটি বাটন কমান্ডে কীভাবে যুক্তিগুলি পাস করবেন?


175

ধরুন Buttonপাইথনে টিকিটারের সাথে আমার নীচে তৈরি হয়েছে:

import Tkinter as Tk
win = Tk.Toplevel()
frame = Tk.Frame(master=win).grid(row=1, column=1)
button = Tk.Button(master=frame, text='press', command=action)

actionআমি বোতাম টিপলে পদ্ধতিটি বলা হয়, তবে যদি আমি পদ্ধতিটিতে কিছু যুক্তি দিতে চাইতাম তবে কী হবে action?

আমি নিম্নলিখিত কোড দিয়ে চেষ্টা করেছি:

button = Tk.Button(master=frame, text='press', command=action(someNumber))

এটি কেবল অবিলম্বে পদ্ধতিটিকে অনুরোধ করে এবং বোতাম টিপলে কিছুই হয় না।


4
ফ্রেম = টাকা। ফ্রেম (মাস্টার = উইন) .গ্রিড (সারি = 1, কলাম = 1) # প্রশ্ন.এখন ফ্রেমের মান কত?
noob oddy

উত্তর:


265

আমি ব্যক্তিগতভাবে এই lambdasজাতীয় দৃশ্যে ব্যবহার করতে পছন্দ করি , কারণ ইমো এটি পরিষ্কার এবং সহজ এবং এটিও যদি আপনাকে তথাকথিত পদ্ধতির উপর নিয়ন্ত্রণ না রাখে তবে প্রচুর মোড়কের পদ্ধতি লিখতে বাধ্য করে না, তবে এটি অবশ্যই স্বাদের বিষয়।

আপনি এটি একটি ল্যাম্বডা দিয়ে কীভাবে করবেন (নোট করুন ফাংশনাল মডিউলটিতে কারি করার কিছু বাস্তবায়ন রয়েছে, যাতে আপনি এটিও ব্যবহার করতে পারেন):

button = Tk.Button(master=frame, text='press', command= lambda: action(someNumber))

11
আপনি এখনও মোড়কের পদ্ধতিগুলি লিখছেন, আপনি কেবল এটি অনলাইনে করছেন।
অগস্ট

53
যদি কোনও নাম্বার বাস্তবে একটি পরিবর্তনশীল হয় যা লুপের ভিতরে মানগুলি পরিবর্তন করে যা অনেকগুলি বোতাম তৈরি করে তবে এটি কাজ করে না । তারপরে প্রতিটি বোতামটি অ্যাকশনকে কল করবে () সর্বশেষ মান যা কোনওটি নম্বরের জন্য বরাদ্দ করা হয়েছে এবং বোতামটি তৈরি করার সময় এটির মান ছিল না। সমাধান ব্যবহার partialকরে এই ক্ষেত্রে কাজ করে ।
স্ক্র্যাঞ্চ

1
এটি আমার জন্য কাজ করে মহান। তবে, আপনি কী ওপিএসের বিবৃতি কেন হয় তাও ব্যাখ্যা করতে পারেন "This just invokes the method immediately, and pressing the button does nothing"?
টমি

17
@ স্ট্র্যাচ আমি অবাক হয়েছি যে আপনার উল্লিখিত জালটিতে টিন্টার ব্যবহারকারীর সংখ্যা কতটা অনুভূত হয়নি! যে কোনও হারে যেভাবে callback=lambda x=x: f(x)fs = [lambda x=x: x*2 for x in range(5)] ; print [f() for f in fs]
মুদ্রাক্ষেত্রটি

1
@ খুব উপরে "আপনার পুরানো স্কুল অজগর লোকগুলি ল্যাম্বডাটির জন্য সম্ভবত ডিফল্ট প্যারামিটার অ্যাসাইনমেন্টটির সাথে লেগে থাকবে" এর অর্থ কী? আমি ল্যাম্বদা কাজ করতে পাই নি এবং এখন আংশিক ব্যবহার।
ক্লেমার শুট্ট

99

এটি partialস্ট্যান্ডার্ড লাইব্রেরি ফান্টুলগুলি ব্যবহার করেও করা যেতে পারে :

from functools import partial
#(...)
action_with_arg = partial(action, arg)
button = Tk.Button(master=frame, text='press', command=action_with_arg)

33
বা এমনকি আরও ছোট:button = Tk.Button(master=frame, text='press', command=partial(action, arg))
ক্লেমার শুট্ট

নেক্রো'ইংয়ের জন্য দুঃখিত, তবে আপনি দু'জন বা ততোধিক যুক্তির ক্ষেত্রে এটি কীভাবে করবেন?
ম্যাসেডপোটোটো

5
action_with_args = partial(action, arg1, arg2... argN)
ডোলোগান

আমি এই পদ্ধতিটি গ্রহণ করব কারণ ল্যাম্বদা আমার পক্ষে কাজ করে না।
জ্যাভেন জেরেয়ান

19

জিইউআই উদাহরণ:

ধরা যাক আমার জিইউআই রয়েছে:

import tkinter as tk

root = tk.Tk()

btn = tk.Button(root, text="Press")
btn.pack()

root.mainloop()

একটি বোতাম টিপে গেলে কী হয়

দেখুন যে যখন btnএটি টিপানো হয় তখন এটি তার নিজস্ব ফাংশনটিকে কল করে যা button_press_handleনীচের উদাহরণে খুব অনুরূপ :

def button_press_handle(callback=None):
    if callback:
        callback() # Where exactly the method assigned to btn['command'] is being callled

সঙ্গে:

button_press_handle(btn['command'])

আপনি কেবল মনে করতে পারেন যে commandবিকল্প, যেমন নির্ধারণ করা উচিত পদ্ধতি আমরা চাই রেফারেন্স, বলা হবে অনুরূপ callbackমধ্যে button_press_handle


বোতামটি চাপলে কোনও পদ্ধতিতে কল করা ( কলব্যাক )

তর্ক ছাড়াই

তাই printবোতামটি টিপানোর সময় যদি আমি কিছু করতে চাই তবে আমাকে সেট করতে হবে:

btn['command'] = print # default to print is new line

পাসে অবধান অভাব এর ()সঙ্গে printপদ্ধতি যা অর্থ যে বাদ দেওয়া হয়: "এই পদ্ধতি নাম যা আমি আপনি যখন চাপা কল করতে চান হয় কিন্তু । এটা শুধু এই খুব তাত্ক্ষণিক কল না" যাইহোক, আমি কোনও আর্গুমেন্ট পাস করি নি printতাই এটি যুক্তি ছাড়াই ডাকা হলে এটি যা প্রিন্ট করে তা মুদ্রিত করে।

সঙ্গে আর্গুমেন্ট (সমূহ)

এখন আমি যদি বোতামটি টিপানো হয় তখন আমাকে যে পদ্ধতিতে কল করতে চাইলে তার পক্ষে যুক্তিগুলিও পাস করতে চাইলে আমি বেনামে থাকা পদ্ধতিটির জন্য লাম্বদা স্টেটমেন্ট দিয়ে তৈরি করা যেতে পারে এমন বেনাম ফাংশনগুলি ব্যবহার করতে পারতাম print, যেমন নীচের মত :

btn['command'] = lambda arg1="Hello", arg2=" ", arg3="World!" : print(arg1 + arg2 + arg3)

বোতামটি চাপলে একাধিক পদ্ধতি কল করা

যুক্তি ছাড়াই

আপনি lambdaবিবৃতি ব্যবহার করে তা অর্জন করতে পারেন তবে এটি খারাপ অনুশীলন হিসাবে বিবেচিত হয় এবং এইভাবে আমি এটি এখানে অন্তর্ভুক্ত করব না। ভাল অনুশীলনটি একটি পৃথক পদ্ধতি সংজ্ঞায়িত করা হয় multiple_methods, যা পদ্ধতিগুলি চেয়েছিলকে কল করে এবং তারপরে এটি বোতাম টিপে কলব্যাক হিসাবে সেট করে:

def multiple_methods():
    print("Vicariously") # the first inner callback
    print("I") # another inner callback

সঙ্গে আর্গুমেন্ট (সমূহ)

অন্য পদ্ধতিগুলি কল করে এমন পদ্ধতিতে যুক্তি (গুলি) পাস করার জন্য আবার lambdaবিবৃতি ব্যবহার করুন তবে প্রথমে:

def multiple_methods(*args, **kwargs):
    print(args[0]) # the first inner callback
    print(kwargs['opt1']) # another inner callback

এবং তারপরে সেট করুন:

btn['command'] = lambda arg="live", kw="as the" : a_new_method(arg, opt1=kw)

কলব্যাক থেকে অবজেক্ট (গুলি) ফিরছে

এছাড়াও আরও মনে রাখবেন যে callbackসত্যিই না পারেন, returnকারণ এটি শুধুমাত্র ভিতরে বলা হচ্ছে button_press_handleসঙ্গে callback()যেমন উল্টোদিকে return callback()। এটি করে returnতবে এই ফাংশনের বাইরে কোথাও নয় । সুতরাং আপনার পরিবর্তে বর্তমান সুযোগে অ্যাক্সেসযোগ্য অবজেক্ট (গুলি) সংশোধন করা উচিত ।


গ্লোবাল অবজেক্ট মডিফিকেশন (গুলি) সহ সম্পূর্ণ উদাহরণ

উদাহরণস্বরূপ নীচে এমন একটি পদ্ধতি কল করবে যা btnপ্রতিটি বার বোতাম টিপে টিপে পরিবর্তন হয়:

import tkinter as tk

i = 0
def text_mod():
    global i, btn           # btn can be omitted but not sure if should be
    txt = ("Vicariously", "I", "live", "as", "the", "whole", "world", "dies")
    btn['text'] = txt[i]    # the global object that is modified
    i = (i + 1) % len(txt)  # another global object that gets modified

root = tk.Tk()

btn = tk.Button(root, text="My Button")
btn['command'] = text_mod

btn.pack(fill='both', expand=True)

root.mainloop()

আয়না


10

ফাংশন আর্গুমেন্টগুলির জন্য পাইথনের ডিফল্ট মান সরবরাহ করার ক্ষমতা আমাদের একটি উপায় বের করে।

def fce(x=myX, y=myY):
    myFunction(x,y)
button = Tk.Button(mainWin, text='press', command=fce)

দেখুন: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/extra-args.html

আরও বোতামের জন্য আপনি একটি ফাংশন তৈরি করতে পারেন যা কোনও ফাংশন ফিরিয়ে দেয়:

def fce(myX, myY):
    def wrapper(x=myX, y=myY):
        pass
        pass
        pass
        return x+y
    return wrapper

button1 = Tk.Button(mainWin, text='press 1', command=fce(1,2))
button2 = Tk.Button(mainWin, text='press 2', command=fce(3,4))
button3 = Tk.Button(mainWin, text='press 3', command=fce(9,8))

4
এটি সমস্যার সমাধান করে না। আপনি যদি তিনটি বোতাম তৈরি করছেন যা সবাই একই ফাংশনটিকে কল করে তবে বিভিন্ন যুক্তি পাস করার দরকার পড়ে?
ব্রায়ান ওকলি

আপনি একটি ফাংশন তৈরি করতে পারেন যা কোনও ফাংশন দেয়।
মার্রেঙ্কনোক্কা

আমি জানি এটি আর সক্রিয় নয় তবে আমি এখানে স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 35616411 /… থেকে লিঙ্ক করেছি , এটি ল্যাম্বডা এক্সপ্রেশন ব্যবহার করার মতো ঠিক একইভাবে কাজ করে, আপনি প্রতিটি বোতামের জন্য কোনও ফাংশনকে একইভাবে তৈরি করতে পারবেন প্রতিটি বোতামের জন্য একটি ল্যাম্বডা এক্সপ্রেশন।
তাদগ ম্যাকডোনাল্ড-জেনসেন

প্রথম কোডের উদাহরণটি এমন একটি লুপে রাখুন যা পরিবর্তিত হয় myXএবং myYপুরোপুরি কার্যকরভাবে কাজ করে আপনাকে অনেক ধন্যবাদ।
তাদগ ম্যাকডোনাল্ড-জেনসেন

3

ম্যাট থম্পসনে বিল্ডিংয়ের উত্তর: একটি শ্রেণিকে কলযোগ্য করা যায় যাতে এটি কোনও ফাংশনের পরিবর্তে ব্যবহার করা যায়:

import tkinter as tk

class Callback:
    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs
    def __call__(self):
        self.func(*self.args, **self.kwargs)

def default_callback(t):
    print("Button '{}' pressed.".format(t))

root = tk.Tk()

buttons = ["A", "B", "C"]

for i, b in enumerate(buttons):
    tk.Button(root, text=b, command=Callback(default_callback, b)).grid(row=i, column=0)

tk.mainloop()

2

এটি তাত্ক্ষণিকভাবে পদ্ধতিটি আহ্বান করার কারণে এবং বোতামটি টিপানোর ফলে action(somenumber)তা মূল্যায়িত হয় না এবং এর রিটার্নের মানটি বোতামের কমান্ড হিসাবে চিহ্নিত করা হয়। সুতরাং যদি actionএটি চালিত হয়ে ফিরে আসে এবং আপনাকে কিছু বলার জন্য কিছু প্রিন্ট করে তবে Noneআপনি কেবল actionতার রিটার্ন মানটি মূল্যায়ন করতে দৌড়ে যান এবং Noneবোতামটির কমান্ড হিসাবে দিয়েছেন ।

বিভিন্ন আর্গুমেন্টের সাথে ফাংশনগুলিতে কল করার বোতামগুলির জন্য আপনি বৈশ্বিক ভেরিয়েবলগুলি ব্যবহার করতে পারেন, যদিও আমি এটি প্রস্তাব করতে পারি না:

import Tkinter as Tk

frame = Tk.Frame(width=5, height=2, bd=1, relief=Tk.SUNKEN)
frame.grid(row=2,column=2)
frame.pack(fill=Tk.X, padx=5, pady=5)
def action():
    global output
    global variable
    output.insert(Tk.END,variable.get())
button = Tk.Button(master=frame, text='press', command=action)
button.pack()
variable = Tk.Entry(master=frame)
variable.pack()
output = Tk.Text(master=frame)
output.pack()

if __name__ == '__main__':
    Tk.mainloop()

আমি যা করবো তা হ'ল classযার বস্তুগুলিতে প্রয়োজনীয় প্রতিটি পরিবর্তনশীল এবং প্রয়োজনীয়গুলি পরিবর্তনের জন্য পদ্ধতি রয়েছে:

import Tkinter as Tk
class Window:
    def __init__(self):
        self.frame = Tk.Frame(width=5, height=2, bd=1, relief=Tk.SUNKEN)
        self.frame.grid(row=2,column=2)
        self.frame.pack(fill=Tk.X, padx=5, pady=5)

        self.button = Tk.Button(master=self.frame, text='press', command=self.action)
        self.button.pack()

        self.variable = Tk.Entry(master=self.frame)
        self.variable.pack()

        self.output = Tk.Text(master=self.frame)
        self.output.pack()

    def action(self):
        self.output.insert(Tk.END,self.variable.get())

if __name__ == '__main__':
    window = Window()
    Tk.mainloop()



2

আমি অত্যন্ত দেরি করেছি, তবে এটি সম্পাদন করার খুব সহজ উপায় simple

import tkinter as tk
def function1(param1, param2):
    print(str(param1) + str(param2))

var1 = "Hello "
var2 = "World!"
def function2():
    function1(var1, var2)

root = tk.Tk()

myButton = tk.Button(root, text="Button", command=function2)
root.mainloop()

আপনি অন্য কোনও ফাংশনে আপনি যে ফাংশনটি ব্যবহার করতে চান তা কেবল মোড়ানো এবং বোতাম টিপে দ্বিতীয় ফাংশনটি কল করুন।


আপনার কোড করা দিয়েছেন var1এবং var2প্রধান মডিউলের সাহায্যে, এড়িয়ে যেতে পারেন function1এ সব এবং করা printবিবৃতি function2। আপনি কি অন্যান্য পরিস্থিতিতে উল্লেখ করেন যা আমি পাই না?
ব্রম

2

ল্যাম্বডাস সমস্ত ভাল এবং ভাল, তবে আপনি এটিও চেষ্টা করতে পারেন (যা লুপ বিটিডব্লিউর জন্য কাজ করে):

root = Tk()

dct = {"1": [*args], "2": [*args]}
def keypress(event):
    *args = dct[event.char]
    for arg in args:
        pass
for i in range(10):
    root.bind(str(i), keypress)

এটি কাজ করে কারণ যখন বাঁধাই সেট করা হয়, তখন একটি কী প্রেস ঘটনাটিকে আর্গুমেন্ট হিসাবে পাস করে। তারপরে আপনি ইভেন্টটির বাইরে থাকা বৈশিষ্ট্যগুলিকে event.char"1" বা "ইউপি" ect পেতে পছন্দ করতে পারেন। আপনার যদি ইভেন্টের বৈশিষ্ট্যগুলি ছাড়া অন্য কোনও যুক্তি বা একাধিক যুক্তিগুলির প্রয়োজন হয়। এগুলি সংরক্ষণ করার জন্য কেবল একটি অভিধান তৈরি করুন।


2

আমিও আগে এই সমস্যার মুখোমুখি হয়েছি। আপনি কেবল ল্যাম্বদা ব্যবহার করতে পারেন:

button = Tk.Button(master=frame, text='press',command=lambda: action(someNumber))

1

কমান্ড ফাংশনে এন্ট্রি ডেটা পাস করার জন্য একটি ল্যাম্বডা ব্যবহার করুন, যদি আপনার এর মতো আরও ক্রিয়া চালানো হয় (যেমন আমি এটি জেনেরিক করার চেষ্টা করেছি, তাই কেবল খাপ খাই):

event1 = Entry(master)
button1 = Button(master, text="OK", command=lambda: test_event(event1.get()))

def test_event(event_text):
    if not event_text:
        print("Nothing entered")
    else:
        print(str(event_text))
        #  do stuff

এটি ইভেন্টের তথ্যটি বোতাম ফাংশনে পৌঁছে দেবে। এটি লেখার আরও পাইথোনস্ক উপায় থাকতে পারে তবে এটি আমার পক্ষে কার্যকর।


1

জেসনপাই - কয়েকটি জিনিস ...

যদি আপনি একটি লুপে একটি বোতাম আটকে থাকেন তবে এটি বারবার তৈরি হবে ... যা সম্ভবত আপনি চান তা নয়। (হইত এটাই)...

এটি সর্বদা শেষ সূচক হওয়ার কারণ হ'ল ল্যাম্বডা ইভেন্টগুলি যখন আপনি সেগুলি ক্লিক করেন তখন চালিত হয় - যখন প্রোগ্রাম শুরু হয় না। আমি নিশ্চিত না যে আপনি কী করছেন 100% তবে সম্ভবত মানটি তৈরি করার পরে চেষ্টা করুন লাম্বদা বোতামটি পরে এটিকে কল করুন।

যেমন: (এই কোডটি ব্যবহার করবেন না, কেবল একটি উদাহরণ)

for entry in stuff_that_is_happening:
    value_store[entry] = stuff_that_is_happening

তাহলে আপনি বলতে পারেন ....

button... command: lambda: value_store[1]

আশাকরি এটা সাহায্য করবে!


1

এক সহজ উপায় কনফিগার করতে হবে buttonসঙ্গে lambdaনিম্নলিখিত সিনট্যাক্স মত:

button['command'] = lambda arg1 = local_var1, arg2 = local_var2 : function(arg1, arg2)

1

উত্তরোত্তর জন্য: আপনি অনুরূপ কিছু অর্জন করতে ক্লাসও ব্যবহার করতে পারেন। এই ক্ষেত্রে:

class Function_Wrapper():
    def __init__(self, x, y, z):
        self.x, self.y, self.z = x, y, z
    def func(self):
        return self.x + self.y + self.z # execute function

বোতামটি তখন সহজভাবে তৈরি করতে পারে:

instance1 = Function_Wrapper(x, y, z)
button1  = Button(master, text = "press", command = instance1.func)

এই পদ্ধতির সাহায্যে আপনি সেটিংস দ্বারা ফাংশন যুক্তি পরিবর্তন করতে পারবেন instance1.x = 3


1

আপনার ব্যবহার করা দরকার lambda:

button = Tk.Button(master=frame, text='press', command=lambda: action(someNumber))

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.