Python Forum
Tkinter won't run my simple function
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tkinter won't run my simple function
#1
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.
Reply
#2
 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.
Reply
#3
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()
AthertonH likes this post
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts


Reply
#4
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).
AthertonH likes this post
Reply
#5
(May-02-2022, 04:42 AM)menator01 Wrote: 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()

Thank you so much! I'll dissect this and figure out why this works and my other one doesn't. I appreciate it.
Reply
#6
(May-02-2022, 05:22 AM)ndc85430 Wrote: 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).

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!
Reply
#7
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)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Using Tkinter inside function not working Ensaimadeta 5 6,805 Dec-03-2023, 01:50 PM
Last Post: deanhystad
  help needed running a simple function in pyqt5 diodes 27 11,153 Jan-24-2023, 12:19 PM
Last Post: GetOnData
  simple tkinter question function call not opening image gr3yali3n 5 4,921 Aug-02-2022, 09:13 PM
Last Post: woooee
  [Tkinter] tkinter best way to pass parameters to a function Pedroski55 3 6,321 Nov-17-2021, 03:21 AM
Last Post: deanhystad
  Creating a function interrupt button tkinter AnotherSam 2 6,740 Oct-07-2021, 02:56 PM
Last Post: AnotherSam
  [Tkinter] Have tkinter button toggle on and off a continuously running function AnotherSam 5 6,440 Oct-01-2021, 05:00 PM
Last Post: Yoriz
  tkinter get function finndude 2 3,554 Mar-02-2021, 03:53 PM
Last Post: finndude
  tkinter -- after() method and return from function -- (python 3) Nick_tkinter 12 10,360 Feb-20-2021, 10:26 PM
Last Post: Nick_tkinter
  function in new window (tkinter) Dale22 7 6,883 Nov-24-2020, 11:28 PM
Last Post: Dale22
Star [Tkinter] How to perform math function in different page of Tkinter GUI ravaru 2 5,407 Oct-23-2020, 05:46 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020