Tkinter Button(s)

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Oct 2006
Posts: 2,564
Reputation: mattyd is an unknown quantity at this point 
Solved Threads: 1
Featured Poster
mattyd's Avatar
mattyd mattyd is offline Offline
Posting Maven

Tkinter Button(s)

 
0
  #1
Dec 14th, 2006
I have addressed this problem sometime ago; I have either misplaced, misunderstood, or never received a response to this issue so therefore I am again attempting to deal with a Python issue:

I am towards the end of a build, and I am dealing with button commands, something that was not necessary to finalize in the program until this point. I need to either:
  • Code one button widget to allow multiple command arguments, that is, the same button is capable of issuing unique event commands at different points
  • Or, I need to be able to destroy or delete the said button so I am able to reload and redisplay it bound to a single, unique command (example: only one button is seemingly displayed from the user's point-of-view, but it is actually 3, seperate "buttons" that perform 3, unique command events.) This does not seem to be the method to use, but unless I can determine a cleaner method such as one button with multiple command references allowed, I see no other way at this point.
~Thank-you in advance for any responses\ ideas

sharky_machine
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: Tkinter Button(s)

 
1
  #2
Dec 14th, 2006
well, one approach could be to have the button attached to a single callback that checks state and calls one of three functions based on the state:

  1.  
  2. def callback(self):
  3.  
  4. commands = [self.myfunc1, self.myfunc2, self.myfunc3]
  5. commands[self.mydata]()
commands is then a jump table that gets you to the right function.

You could lambda-ize that solution as well, like this:

  1. self.commands = [self.myfunc1, self.myfunc2, self.myfunc3]
  2.  
  3. self.b = Button(self, ..., command=lambda :self.commands[self.mydata]())
But that latter solution won't work if the callback has to extract info from self in order to find out which function to call.

Jeff
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,564
Reputation: mattyd is an unknown quantity at this point 
Solved Threads: 1
Featured Poster
mattyd's Avatar
mattyd mattyd is offline Offline
Posting Maven

Re: Tkinter Button(s)

 
0
  #3
Dec 14th, 2006
Originally Posted by jrcagle View Post
well, one approach could be to have the button attached to a single callback that checks state and calls one of three functions based on the state:

  1.  
  2. def callback(self):
  3.  
  4. commands = [self.myfunc1, self.myfunc2, self.myfunc3]
  5. commands[self.mydata]()
commands is then a jump table that gets you to the right function.

You could lambda-ize that solution as well, like this:

  1. self.commands = [self.myfunc1, self.myfunc2, self.myfunc3]
  2.  
  3. self.b = Button(self, ..., command=lambda :self.commands[self.mydata]())
But that latter solution won't work if the callback has to extract info from self in order to find out which function to call.

Jeff
TY for your reply and help.
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,564
Reputation: mattyd is an unknown quantity at this point 
Solved Threads: 1
Featured Poster
mattyd's Avatar
mattyd mattyd is offline Offline
Posting Maven

Re: Tkinter Button(s)

 
0
  #4
Dec 15th, 2006
Originally Posted by sharky_machine View Post
I have addressed this problem sometime ago; I have either misplaced, misunderstood, or never received a response to this issue so therefore I am again attempting to deal with a Python issue:

I am towards the end of a build, and I am dealing with button commands, something that was not necessary to finalize in the program until this point. I need to either:
  • Code one button widget to allow multiple command arguments, that is, the same button is capable of issuing unique event commands at different points
  • Or, I need to be able to destroy or delete the said button so I am able to reload and redisplay it bound to a single, unique command (example: only one button is seemingly displayed from the user's point-of-view, but it is actually 3, seperate "buttons" that perform 3, unique command events.) This does not seem to be the method to use, but unless I can determine a cleaner method such as one button with multiple command references allowed, I see no other way at this point.
~Thank-you in advance for any responses\ ideas

sharky_machine
Hello again:

I have been trying the given suggestions as well as other, possible options researched online; I was able to solve my initial problem concerning "command=" but it displays two (2) buttons instead of a single button -- I require only one button at all times. I am obviously missing something here.

I have tried various things such as: destroy, delete, forget-- in order to get rid of the first displayed button and replace it visibly with the second. One button to harbor a few commands. Right now at this point the program in general is running bug-free, smooth, and fast-- then I reach the post-load where I will require user input more than once via this one, aforementioned button. Below is the button code as it stands:

  1. image00 = PhotoImage(file='grey1.gif')
  2. btn1 = Button(root ,bg="Black", text="HIT", image=image00,command=show_image2)
  3. btn1. pack()
  4. btn1 = Button(root ,bg="Black", text="HIT", image=image00,command=show_image3)
  5. btn1. pack()
  6.  
  7. def button_command():
  8. command=show_image2()
  9. command=show_image3()
  10. btn1 = Button(root ,bg="Black", text="HIT", image=image00)
  11. def switch():
  12. pack.forget()
  13. button2.pack()

Thank-you in advance.

sharky_machine
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: Tkinter Button(s)

 
0
  #5
Dec 16th, 2006
I believe that what is happening is that btn1 is being set to the first instance of Button, which is then packed (I prefer 'grid', BTW). Then btn1 is set to the second instance of Button, which is also packed. The reference to the first Button is then lost; your code has no way of accessing it, even though Tk continues to maintain a reference to it on its parent frame.

I don't know why pack.forget() doesn't fix that problem.

But if I understand your intent correctly, you want to switch out the button text and image, but not the button itself, yes?

One possibility is to use a textvariable for the Button rather than static text. It might also be possible to change the image on the fly.

See http://infohost.nmt.edu/tcc/help/pubs/tkinter.pdf for info on using textvariable.

Sorry for the partial solution; hope it helps.
Jeff
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,564
Reputation: mattyd is an unknown quantity at this point 
Solved Threads: 1
Featured Poster
mattyd's Avatar
mattyd mattyd is offline Offline
Posting Maven

Re: Tkinter Button(s)

 
0
  #6
Dec 16th, 2006
Originally Posted by jrcagle View Post
I believe that what is happening is that btn1 is being set to the first instance of Button, which is then packed (I prefer 'grid', BTW). Then btn1 is set to the second instance of Button, which is also packed. The reference to the first Button is then lost; your code has no way of accessing it, even though Tk continues to maintain a reference to it on its parent frame.

I don't know why pack.forget() doesn't fix that problem.

But if I understand your intent correctly, you want to switch out the button text and image, but not the button itself, yes?

One possibility is to use a textvariable for the Button rather than static text. It might also be possible to change the image on the fly.

See http://infohost.nmt.edu/tcc/help/pubs/tkinter.pdf for info on using textvariable.

Sorry for the partial solution; hope it helps.
Jeff
Jeff:

Thank-you for your reply.

Let me talk about the needed button function(s) again:

I am towards the tail-end of a GUI Python game build based on Blackjack. I am using Tkinter as my primary graphics module. The build is going very well and I believe it is almost complete (save for testing\ debugging) but I am at a point where I must finish the user input device (the button used to simply allow the player to "HIT" for another card).

This button will be visually, to the user, "one button", that is, they at all times (when the "HIT" button is made available to them to use) will see something like this: [HIT]
*This is actually a pretty, damaged-metal, GIF-fronted button, not just text. No standard keyboard text will be displayed on this button or changed for any reason.

What does this button exactly do? Allows the player to request additional cards. How many cards? At this point (based on statistical studies I've conducted with decks of real playing cards to see how many cards on average allow one to reach "21" without going over) the player can request three (3) new cards via this button (after receiving two computer "dealt" cards) for a total of five (5) cards displayed for their hand. (I determined that, on average, 5 cards generally achieve "21" without going over "21")

I need this one button to allow a player to request a total of 3 new cards. This seems simple but I'm finding (possibly due to my coding design of logic and variables) this is more difficult than I first believed. I am very used to Visual Basic and I initially assumed I would activate buttons in a similar and easy way. Well, I am struggling with this and do not know why.

I figured as a work-around I could have the same [HIT] with single function displayed 3-times without the player noticing-- no screen flash-- just a refresh of the GIF but with a different, seperate line of code imbedded in the background.

I just need to have one instance of this button allowing 3 "commands" which I cannot, it seems.

I'm not sure what I'm doing wrong. I've tried many things: so far, I only get 3 seperate [HIT] buttons displayed at once-- they all work great... but I only need one to be displayed.

Thanks again for your help.

Regards,
sharky_machine
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: Tkinter Button(s)

 
0
  #7
Dec 16th, 2006
The game sounds really cool. See if this is what you're after:

[php]
from Tkinter import *
import random

class MyFrame(Frame):

def __init__(self, master):
Frame.__init__(self, master)
self.buttons = [Button(self, text="1", command=self.switch), \
Button(self, text="2", command=self.switch), \
Button(self, text="3", command=self.switch)]
self.b = random.choice(self.buttons)
self.b.grid()
self.grid()

def switch(self):
self.b.grid_remove()
self.b = random.choice(self.buttons)
self.b.grid()

mainw = Tk()
mainw.frame = MyFrame(mainw)
mainw.mainloop()
[/php]
This allows the user to randomly switch amongst three different buttons. Yours wouldn't be random, of course.

So about the game: if the user hits the button, he gets three cards automatically? I was at first picturing the user hitting the 'Hit' button as many times as he might want, until he busts or wins. But from your description, I'm not sure.

Jeff
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,564
Reputation: mattyd is an unknown quantity at this point 
Solved Threads: 1
Featured Poster
mattyd's Avatar
mattyd mattyd is offline Offline
Posting Maven

Re: Tkinter Button(s)

 
0
  #8
Dec 16th, 2006
Originally Posted by jrcagle View Post
The game sounds really cool. See if this is what you're after:

[php]
from Tkinter import *
import random

class MyFrame(Frame):

def __init__(self, master):
Frame.__init__(self, master)
self.buttons = [Button(self, text="1", command=self.switch), \
Button(self, text="2", command=self.switch), \
Button(self, text="3", command=self.switch)]
self.b = random.choice(self.buttons)
self.b.grid()
self.grid()

def switch(self):
self.b.grid_remove()
self.b = random.choice(self.buttons)
self.b.grid()

mainw = Tk()
mainw.frame = MyFrame(mainw)
mainw.mainloop()
[/php]
This allows the user to randomly switch amongst three different buttons. Yours wouldn't be random, of course.

So about the game: if the user hits the button, he gets three cards automatically? I was at first picturing the user hitting the 'Hit' button as many times as he might want, until he busts or wins. But from your description, I'm not sure.

Jeff
Jeff:

Thanks for the code-- I will try this out today.

About the button and player use: The player may request up to three cards if they need or choose to do so. Mathematically, they may not need of want to get any additional card(s) beyond the first two cards. Say, for example, one is a King\ face card (10) + the second card (both of these two dealt automatically by the machine) , an Ace (which could be a "1" OR an "11", depending on the other card). This is "21", a natural Blackjack.

They can now choose up to three more cards if they wish (or none) for a TOTAL of five, displayed cards. The computer opponent the "dealer" also may have up to five, total cards. So, the button will allow the user\ human player to "HIT" for three additional cards if they wish to. These three, requested cards would require three, seperate pushes of the said button by the player-- one card per push. One card at a time.

I hope this makes sense. I may not be explaining it well. It is, at first glance, a simple game, but I think it is visually beautiful (GUI and theme of the game) and the logic is a bit more complex than I expected; that is, in order for the computer to read, record, compute, and make decisions as an artificial player, it reacts based on the human player's decisions, that is, the machine must react accordingly so it does not lose as the "Dealer".

The Casino "House" (the computer) should always win, theoretically. :cheesy:

Its quite exciting building this as a personal side project and I will post the game here as a zipped file when complete.

Regards,
Matty D.
Last edited by mattyd; Dec 16th, 2006 at 4:16 pm. Reason: grammer
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,564
Reputation: mattyd is an unknown quantity at this point 
Solved Threads: 1
Featured Poster
mattyd's Avatar
mattyd mattyd is offline Offline
Posting Maven

Re: Tkinter Button(s)

 
0
  #9
Dec 17th, 2006
Originally Posted by sharky_machine View Post
I have addressed this problem sometime ago; I have either misplaced, misunderstood, or never received a response to this issue so therefore I am again attempting to deal with a Python issue:

I am towards the end of a build, and I am dealing with button commands, something that was not necessary to finalize in the program until this point. I need to either:
  • Code one button widget to allow multiple command arguments, that is, the same button is capable of issuing unique event commands at different points
  • Or, I need to be able to destroy or delete the said button so I am able to reload and redisplay it bound to a single, unique command (example: only one button is seemingly displayed from the user's point-of-view, but it is actually 3, seperate "buttons" that perform 3, unique command events.) This does not seem to be the method to use, but unless I can determine a cleaner method such as one button with multiple command references allowed, I see no other way at this point.
~Thank-you in advance for any responses\ ideas

sharky_machine
I am still trying to discover a way to at least destroy-delete-hide- or forget () a Tkinter button\ widget. I have searched this forum and all over the 'Net; this stands as inconclusive at this point. I have tried various things but get no response from the Python GUI; I assumed this would be rather simple (and, it probably is) but I am finding no way to make this work.

For example:
  1. def button_command():
  2. command=show_image2()
  3. btn1 = Button(root ,bg="Black", text="HIT", image=image00)
  4. def switch():
  5. button2.pack()
  6. pack.forget()

Regards,
sharky_machine
Last edited by mattyd; Dec 17th, 2006 at 8:56 pm. Reason: [code edit]
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 4,067
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 938
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite

Re: Tkinter Button(s)

 
0
  #10
Dec 18th, 2006
Just a thought, I have used that trick before. You can use
  1. canvas.move(canvas_object, xAmount, yAmount)
  2. root.update()
to move the object you created right off the canvas to hide it. Then bring it or another object back.
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Python Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC