-4

I am aware there are answers on this website dealing with this issue but all resolutions that I've come across haven't seemed to help in my situation. I'm using Tkinter (and trying to learn how to use it) to make a game. I want a button (Quit Game) to exit out of the Tkinter window but I keep getting this error:

TypeError: exe() missing 1 required positional argument: 'self'

My code:

from tkinter import *
import sys as s, time as t

try: color = sys.stdout.shell
except AttributeError: raise RuntimeError("This programme can only be run in IDLE")

color.write("     | Game Console | \n", "STRING")

root = Tk()
root.title("Tic-Tac-Toe")
menuFrame = Frame(root)
menuFrame.pack() 
buttonFrame = Frame(root)
buttonFrame.pack()
Label(menuFrame, text = ("Tic-Tac-Toe"), font = ("Helvetica 12 bold")).grid(row = 10, column = 5)

def play():
    color.write("Game window opening... \n", "STRING")
    #open new window to game later



def exe(self):
    color.write("Goodbye for now \n", "STRING")
    self.destroy()

playButton = Button(buttonFrame, text = ("Play game"), command = play)
playButton.pack(side=LEFT)

Button(root, text=("Quit Game"), command=exe).pack()
root.mainloop()

I can't seem to find where it means as I've defined it into the function. Thank you in advance for your solutions.

JoshuaRDBrown
  • 343
  • 5
  • 12

2 Answers2

4

In your code you have:

def exe(self):

This means you are requiring the self argument; self is used with instances of a class and as your method does not have a class you can omit the self parameter like so in your method header, like this:

def exe():
    color.write("Goodbye for now \n", "STRING")
    root.destroy()
martineau
  • 119,623
  • 25
  • 170
  • 301
cuuupid
  • 912
  • 5
  • 20
  • 1
    Thank you for your response, but how am I supposed to use the .destroy() extension without the 'self' object? – JoshuaRDBrown Feb 09 '18 at 14:49
  • 1
    You can work with your global `root` using `root.destroy()`. _Note that you may find it more convenient in the long run to create a class to manage your game which stores the board, after which you can use the `self` parameter at ease with instances of the class._ – cuuupid Feb 09 '18 at 14:53
  • Thank you very much for your help. – JoshuaRDBrown Feb 09 '18 at 15:02
0

Your method is defined in a way that it asks for a (positional) argument, self. Which is conventionally used as the object reference of a class but since you don't have a class it is just a regular argument right now, that you're not passing. You can pass that argument by, making use of anonymous functions(lambda), replacing:

Button(..., command=exe).pack()

with:

Button(..., command=lambda widget=root: exe(widget)).pack()

You should also better replace:

def exe(self):
    ...
    self.destroy()

with:

def exe(widget_to_be_destroyed):
    ...
    widget_to_be_destroyed.destroy()

for disambiguation.

Nae
  • 14,209
  • 7
  • 52
  • 79