0

So I am creating a game, and now I have decided to add a GUI. The GUI code is shown as follows:

master = Tk()
master.wm_title("Main Menu")

a = Button.grid(master, text = "DOMINATE!", command = difficulty)
a.grid(row = 0, column = 0)
a.pack()
mainloop()

b = Button.grid(master, text = "Patch Notes", command = changelog)
b.grid(row = 0, column = 1)
b.pack()
mainloop()

c = Button.grid(master, text = "Credits", command = credit)
c.grid(row = 1, column = 0)
c.pack()
mainloop()

d = Button.grid(master, text = "Rules", command = rules)
d.grid(row = 1, column = 1)
d.pack()
mainloop()

e = Button.grid(master, text = "Quit", command = exit)
e.grid(row = 2, column = 0)
e.pack()
mainloop()

I have already imported the function * from Tkinter and this is just a snippet of my 1200 lines of code. When I try to run it, I get this error:

TypeError: unbound method grid_configure() must be called with Button instance as first argument (got Tk instance instead)

(Python is kind of a new language for me so sorry for missing anything obvious or stupid. I am also kind of new to programming).

6
  • 7
    At a glance, try replacing all the instances of Button.grid( with just Button( Commented Jul 23, 2012 at 20:25
  • As a general rule of thumb. If you find yourself repeating a similar line 3 or more times, use a loop. Commented Jul 23, 2012 at 20:29
  • @JoelCornett -- This would be a somewhat clunky loop (have to change text, command, row and column at each iteration). not that it's impossible, but I'm not sure if it would make the code more clear ... Commented Jul 23, 2012 at 20:34
  • @mgilson: Maybe you're right. Sorry. Knee-jerk reaction to repetitive code. I was thinking along the lines of using a dict of functions to replace a series of similar if..elifs. In this case You could store the button data in a data structure, and iterate over the data structure to create the buttons. Commented Jul 23, 2012 at 20:56
  • 1
    mainloop is designed to be called only once. I can't imagine how your code runs the way you have it in your question. Commented Jul 23, 2012 at 21:10

3 Answers 3

1

You want something like:

a = Button(master, text = "DOMINATE!", command = difficulty)
a.grid(row=...,column=...)

Also, don't do

a.grid(...)
a.pack(...)

Using pack and grid on the same widget (or even within the same widget) will likely leave your computer sitting there forever trying to negotiate a reasonable layout between the two geometry managers. Either use only pack, or only grid.

Finally, you only need the last mainloop(). You should remove all the others -- although if you have 1200 lines of code, I suspect that correcting these things will raise other errors.

Sign up to request clarification or add additional context in comments.

Comments

1

The main error comes from the 'master' which is not a Button instance in :

a = Button.grid(master, text = "DOMINATE!", command = difficulty)

do instead :

a = Button(master, text = "DOMINATE!", command = difficulty)
Button.grid(master.a,row=0,column=0,rowspan=1,columnspan=1,sticky='wens')

the line for grid placement use the Button superclass grid method for Tkinter Old-style classes. but you don't seem to need that so you could do :

a.grid(master.self,row=0,column=0,rowspan=1,columnspan=1,sticky='wens')

Doing :

a = Button(master, text = "DOMINATE!", command = difficulty).grid(row=0,column=0,rowspan=1,columnspan=1,sticky='wens') 

"a" will not be a Button instance callable later, as it will be a grid instance equal to NoneType. Split both creation and placement.

1 Comment

"it will be a grid instance" is incorrect terminology. It won't be a grid instance, it will be the value returned by the grid function.
0

The error "unbound method grid_configure() must be called with Button instance..." comes from lines that look like this:

a = Button.grid(...)

What the above does is try to call the grid method on the Button class, rather than on an instance of the Button class. Generally speaking, any "unbound method" error means exactly that -- you're trying to call a method on a class rather than an instance.

Instead, you must first create an instance of the Button class, then call grid on the instance. For example:

a = Button(...)
a.grid(...)

Also, using both pack and grid for the same widget makes no sense. Use one or the other. If you use grid you don't need to call pack.

Finally, mainloop is designed to be called exactly once after all your widgets have been created.

On a related note, in my experience GUI code is much easier to maintain if you put all your layout code (grid, pack and place) together. Not necessarily all together for the entire app, but at least grouped by the containing window. For example, instead of this:

a = Button(...)
a.grid(...)
b = Button(...)
b.grid(...)
...

... I recommend doing it like this:

a = Button(...)
b = Button(...)
...
a.grid(...)
b.grid(...)

This sort of code organization makes it easier to spot layout problems such as having multiple items in the same row or column, etc.

1 Comment

Thanks for helping me fix this and clearing things up. I will take your method of GUI programming organization and apply it. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.