accessing the return value of function that was bound to an event (tkinter)

后端 未结 3 1260
余生分开走
余生分开走 2021-01-14 09:27

Basically, what I\'ve done is bound a click event to a function. For example:

self.button1.bind(\"\",self.chooseDice)

What

相关标签:
3条回答
  • 2021-01-14 09:49

    You are already doing what you need to do. Your example code sets self.diceList to some value. Anywhere else in your code you can directly use self.diceList.

    By the way -- you're writing code that is going to be hard to maintain over time. For example, what if you change the dice label to "Dice One" or simply "One" rather than "Dice 1"? Or, as your app progresses you might want graphical images instead of text on the buttons. You'll have to modify the code that parses the button name. You are essentially encoding information in a button label which is not a good idea.

    A simple solution, that also makes your chooseDice method simpler and easier to understand, is to pass in the dice number in the callback. For example:

    self.button1.configure(command=lambda btn=self.button1: self.chooseDice(btn, 1))
    

    The above passes two parameters to the chooseDice method: the button instance (so you can disable it) and the button number (so you don't have to parse the button name to get it)

    This also allows you to create your dice in a loop rather than hard-coding multiple copies of the same block of code. Here's a complete working example:

    from Tkinter import *
    
    class GraphicsInterface:
    
        def __init__(self):
            self.window = Tk()
            self.window.geometry("720x500")
            self.clicked=[] 
            self.buttons = []
    
            for n in range(1, 3):
                btn = Button(text="Button " + str(n))
                btn.configure(command=lambda btn=btn, n=n: self.chooseDice(btn, n))
                btn.pack()
                self.buttons.append(btn)
    
            btn = Button(text="Go!", command=self.go)
            btn.pack()
            self.window.mainloop()
    
    
        def go(self):
            print "buttons:", self.clicked
            self.reset()
    
        def reset(self):
            '''Reset all the buttons'''
            self.clicked = []
            for button in self.buttons:
                button.configure(state="normal")
    
        def chooseDice(self, widget, number):
            self.clicked.append(number)
            widget.configure(state="disabled")
    
    app = GraphicsInterface()
    

    Finally, some last bits of advice:

    Don't use place, it makes your GUIs harder to create, and they won't react well to changes in window size, changes in font, changes in platform, etc. Use pack and grid instead. Also, don't create fixed-width buttons. Again, this is to better handle changes in fonts. There are times when you want fixed width buttons, but it doesn't look like your code has any reason to use them.

    Finally, I don't know what you're actually trying to accomplish, but usually if you're using buttons to track state (is this thing pressed or not?) you want to use checkboxes (pick N of N) or radiobuttons (pick 1 of N). You might want to consider switching to those instead of to buttons.

    0 讨论(0)
  • 2021-01-14 09:50

    just add a self.result attribute to your class and set it at chooseDice()

    0 讨论(0)
  • 2021-01-14 10:03

    Refactor. Split this into two functions.

    One returns the proper result, usable by other objects.

    The other is bound to a GUI control, and uses the proper result to activate and deactivate GUI objects.

    Indeed, you should always do this. You should always have functions that do normal Python stuff, work correctly without the GUI and can be unit tested without the GUI. Then you connect this working "model" to the GUI.

    0 讨论(0)
提交回复
热议问题