![]() |
Tkinter won't run my simple function - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: Tkinter won't run my simple function (/thread-37096.html) |
Tkinter won't run my simple function - AthertonH - May-02-2022 Hey guys, I'm trying to make a magic 8 ball interface using Tkinter. I'm fairly new to coding, and I guess you could say this is my first "personal" project without having to use tutorials or read any books. I'm trying to have this code print a random response when you press the button, but I get these callbacks. Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\Harrison\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__ return self.func(*args) File "C:\Users\Harrison\PycharmProjects\8ball\8ball.py", line 37, in <lambda> shake_button = tk.Button(root, textvariable=shake_text, command=lambda:shake()) File "C:\Users\Harrison\PycharmProjects\8ball\8ball.py", line 30, in shake text_box.insert(1.0, responses.EightBall()) File "C:\Users\Harrison\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 3772, in insert self.tk.call((self._w, 'insert', index, chars) + args) _tkinter.TclError: wrong # args: should be ".!text insert index chars ?tagList chars tagList ...?" Here is my code. import tkinter as tk from PIL import Image, ImageTk from tkinter.filedialog import askopenfile import responses root = tk.Tk(className="Magic 8 Ball") canvas = tk.Canvas(root, width=800, height=500) canvas.grid(columnspan=3, rowspan=3) #logo logo = Image.open("image.png") logo = ImageTk.PhotoImage(logo) logo_label = tk.Label(image=logo) logo_label.image = logo logo_label.grid(column=1, row=0) #instructions instructions = tk.Label(root, text="Please type in your question. Then 'Shake' to see your fate.") instructions.grid(columnspan=3, column=0, rowspan=5, row=1) def shake(): text_box = tk.Text(root, height=10, width=50, padx=15, pady=15) text_box.insert(1.0, responses.EightBall()) <-------------------- THIS IS WHERE MY ISSUE IS text_box.tag_configure("center", justify="center") text_box.tag_add("center", 1.0, "end") text_box.grid(column=1, row=3) #shake button shake_text = tk.StringVar() shake_button = tk.Button(root, textvariable=shake_text, command=lambda:shake()) shake_text.set("Shake") shake_button.grid(column=1, row=2) root.mainloop()the responses.py isn't necessary, it's just a simple random generator. but I run into the trouble at the spot that I highlighted (LINE 30). I can have the program print a statement, but I can't have it run my function of randomly printing a response. Thanks for your time and help. RE: Tkinter won't run my simple function - AthertonH - May-02-2022 import random """A simple 8 ball program. Will develop a GUI to further my knowledge in the future.""" responses = ["It is certain.", "It is decidedly so.", "Without a doubt", "Yes - definitely", "You may rely on it.", "As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes.", "Reply hazy, try again.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.", "Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."] def EightBall(): print(random.choice(responses))Here's the responses code actually. I've tried removing the print statement and that didn't work either. I can get the response on the terminal but can't display it in the GUI. RE: Tkinter won't run my simple function - menator01 - May-02-2022 Here is something for you to work with. import tkinter as tk from random import choice def eightball(box): box.delete('1.0', tk.END) responses = ["It is certain.", "It is decidedly so.", "Without a doubt", "Yes - definitely", "You may rely on it.", "As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes.", "Reply hazy, try again.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.", "Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."] box.insert(tk.END, choice(responses)) root = tk.Tk() root['padx'] = 8 root['pady'] = 5 label = tk.Label(root, text='Type a question then, shake') label.grid(column=0, row=0, sticky='new') string = tk.StringVar() box = tk.Text(root) box.grid(column=0, row=1, sticky='new') btn = tk.Button(root, text='Shake') btn['command'] = lambda: eightball(box) btn.grid(column=0, row=2, sticky='new') root.mainloop() RE: Tkinter won't run my simple function - ndc85430 - May-02-2022 Are you passing the arguments to insert in the right order? The error message it telling you something about the arguments is wrong (the TclError in the traceback). Did you check the docs for insert ?Also, a small thing: on line 37, you don't need the lambda. A lambda is just a function literal (in the same way as "blue" is a string literal) and all you're doing there is creating a function that takes no arguments and calls shake . shake is itself a function that takes no arguments, so you can just pass it as the command instead of wrapping it in another function (i.e. command=shake ).
RE: Tkinter won't run my simple function - AthertonH - May-02-2022 (May-02-2022, 04:42 AM)menator01 Wrote: Here is something for you to work with. Thank you so much! I'll dissect this and figure out why this works and my other one doesn't. I appreciate it. RE: Tkinter won't run my simple function - AthertonH - May-02-2022 (May-02-2022, 05:22 AM)ndc85430 Wrote: Are you passing the arguments to Thank you for your help! I'm not too sure if it was the order of anything, I'll have to toy around with it. The lambda thing I was still confused about, but I think I understand now. Thank you! RE: Tkinter won't run my simple function - deanhystad - May-03-2022 Lamda expressions are confusing. A lambda expression creates an anonymous function. You wrote this: shake_button = tk.Button(root, textvariable=shake_text, command=lambda:shake())Python sees this: def unnamed_function(): shake() shake_button = tk.Button(root, textvariable=shake_text, command=unnamed_function)This offers no benefit over using "command=shake". So why are there lambda expressions? Lambda expressions can be used for many reasons, but the main reason they are used in GUI code (I think) is to bind an event to a function call with arguments. You get your code working and you realize that it is shake should not create a Text widget. It should append text to an existing widget. You rewrite your code to do this. def shake(textVar): textVar.set(responses.EightBall()) text_box = tk.Text(root, height=10, width=50, padx=15, pady=15) text_box.tag_configure("center", justify="center") text_box.tag_add("center", 1.0, "end") text_box.grid(column=1, row=3) #shake button shake_text = tk.StringVar() shake_button = tk.Button(root, textvariable=shake_text, command=lambda:shake(shake_text))This code passes the Text widget as an argument to the shake() function. Now the lambda expression is doing this: def unnamed_function(): shake(shake_text) shake_button = tk.Button(root, textvariable=shake_text, command=unnamed_function) |