944,073 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Marked Solved
  • Views: 6486
  • Python RSS
You are currently viewing page 1 of this multi-page discussion thread
Dec 14th, 2006
0

Tkinter Button(s)

Expand 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
Similar Threads
Featured Poster
Reputation Points: 105
Solved Threads: 1
Posting Maven
mattyd is offline Offline
2,582 posts
since Oct 2006
Dec 14th, 2006
1

Re: Tkinter Button(s)

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:

Python Syntax (Toggle Plain Text)
  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:

Python Syntax (Toggle Plain Text)
  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
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Dec 14th, 2006
0

Re: Tkinter Button(s)

Click to Expand / Collapse  Quote originally posted by jrcagle ...
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:

Python Syntax (Toggle Plain Text)
  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:

Python Syntax (Toggle Plain Text)
  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.
Featured Poster
Reputation Points: 105
Solved Threads: 1
Posting Maven
mattyd is offline Offline
2,582 posts
since Oct 2006
Dec 15th, 2006
0

Re: Tkinter Button(s)

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:

Python Syntax (Toggle Plain Text)
  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
Featured Poster
Reputation Points: 105
Solved Threads: 1
Posting Maven
mattyd is offline Offline
2,582 posts
since Oct 2006
Dec 16th, 2006
0

Re: Tkinter Button(s)

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
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Dec 16th, 2006
0

Re: Tkinter Button(s)

Click to Expand / Collapse  Quote originally posted by jrcagle ...
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
Featured Poster
Reputation Points: 105
Solved Threads: 1
Posting Maven
mattyd is offline Offline
2,582 posts
since Oct 2006
Dec 16th, 2006
0

Re: Tkinter Button(s)

The game sounds really cool. See if this is what you're after:

Python Syntax (Toggle Plain Text)
  1. from Tkinter import *
  2. import random
  3.  
  4. class MyFrame(Frame):
  5.  
  6. def __init__(self, master):
  7. Frame.__init__(self, master)
  8. self.buttons = [Button(self, text="1", command=self.switch), \
  9. Button(self, text="2", command=self.switch), \
  10. Button(self, text="3", command=self.switch)]
  11. self.b = random.choice(self.buttons)
  12. self.b.grid()
  13. self.grid()
  14.  
  15. def switch(self):
  16. self.b.grid_remove()
  17. self.b = random.choice(self.buttons)
  18. self.b.grid()
  19.  
  20. mainw = Tk()
  21. mainw.frame = MyFrame(mainw)
  22. mainw.mainloop()
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
Last edited by vegaseat; Apr 4th, 2010 at 12:10 pm. Reason: changed code tags, php tags no longer working
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
Dec 16th, 2006
0

Re: Tkinter Button(s)

Click to Expand / Collapse  Quote originally posted by jrcagle ...
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
Featured Poster
Reputation Points: 105
Solved Threads: 1
Posting Maven
mattyd is offline Offline
2,582 posts
since Oct 2006
Dec 17th, 2006
0

Re: Tkinter Button(s)

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:
Python Syntax (Toggle Plain Text)
  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]
Featured Poster
Reputation Points: 105
Solved Threads: 1
Posting Maven
mattyd is offline Offline
2,582 posts
since Oct 2006
Dec 18th, 2006
0

Re: Tkinter Button(s)

Just a thought, I have used that trick before. You can use
Python Syntax (Toggle Plain Text)
  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.
Moderator
Reputation Points: 1333
Solved Threads: 1403
DaniWeb's Hypocrite
vegaseat is offline Offline
5,792 posts
since Oct 2004

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: integrating python script with Java application
Next Thread in Python Forum Timeline: File IO question





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC