Onclick działa przed kliknięciem python,tkinter

0

Witam, mam problem. Otóż mój onclick działa przed kliknięciem a po kliknięciu nie .
Walczę z tym już dłuższy czas

from tkinter import *
root = Tk()
from PIL import ImageTk, Image
import os

def hello(x):
    print("Hello World")
    pass
mit = ImageTk.PhotoImage(Image.open("mit.jpg"))
stan =  ImageTk.PhotoImage(Image.open("stan.png"))
root.iconbitmap('edu.ico')
root.title("Education")
root.geometry("500x500")
root.configure(bg='white')

btn = Button (root,bg='red',text="MIT",fg='white',font='Helvetica 18 bold',width='11')
btn.command=hello('1')
btn.pack(fill=X, padx=10, pady=10, side=LEFT)
btn = Button (root,bg='green',text="Stanford",fg='white',font='Helvetica 18 bold',width='11')
btn.pack(fill=X, padx=10, pady=10, side=RIGHT)
root.mainloop()
0

btn.command=hello('1') --> btn.command=hello
A jak chcesz argumenty to skorzystaj np. z lambdy

1

Zakładam że przez 'onclick' masz na myśli te funkcję, wywoływaną jako command:

btn.command=hello('1')

Otóż, przypisujesz do btn.command, to co zwróci hello z argumentem '1', jako że nie masz tam return, to hello się wykona przy inicjalizacji programu.

Jest kilka sposobów na to, pierwsze to domknięcie (closure):

def hello_closure(arg)
    def hello():
        print(arg)
        pass #Tu dajesz co ma się wykonać
    return hello

btn.command=hello_closure('1')

Albo mniej zalecana wśród pythonistów, ale czytelniejsza i mnie osobiście bardziej odpowiadająca droga ku temu:

def hello(arg):
    print(arg)
    pass # Tu defakto nic nie zmieniasz
btn.command = lambda x='1': hello(x)
#Lub:
btn.command = lambda: hello('1')
#Lub:
x = '1'
btn.command = lambda arg=x: hello(arg)
#Lub:
x = '1'
btn.command = lambda: hello(x)

Każdy z tych sposobów jest różny, niektóre na stałe zapamiętają wartość pod x, inne gdy x się zmieni będą wywołane ze zmienionym. Dwa pierwsze zawsze biorą '1' za argument, tylko w różny sposób. Tobie zostawiam rozpracowanie tego, bo przy różnych problemach, są różne podejścia potrzebne, czasem można się odwołać do zmiennej zainicjalizowanej której defakto w programie wydawałoby się że już nigdzie nie ma :)
[Przykład magicznej sztuczki: Inicjalizujesz pola w klasie odpowiedzialne za start gry, nie potrzebujesz ich kopii, bo dzięki zapamiętaniu ich w lambdzie/domknięciu, jesteś w stanie odwołać się do tego wywołując funkcję/metodę. ]

1 użytkowników online, w tym zalogowanych: 0, gości: 1