Binding a keyboard key to a Tkinter button

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite
1












I'm specifically asking about binding a keyboard keystroke to a button in a GUI. Originally I planned to bind the keystroke to the GUI button itself, but that seemed impossible, and potentially unwise after I considered it later.



Is this the proper (pythonic) way to bind a keyboard key and GUI button?



## start.py
print 'start'

#from tkinter import *
from Tkinter import *
import os
from PIL import ImageTk, Image

class MyClass:
'''This is my class.'''

imgpath = '/Users/user/Dropbox/Camera Uploads'
imgfile = 'susshi.jpg'
#imgfilepath = os.path.join(self.imgpath, self.imgfile)
imgfilepath = os.path.join(imgpath, imgfile)

def __init__(self,master):
print 'in __init__'

# Create and load a frame into the tk (tkinter) window.
frame = Frame(master)
frame.pack()

# Create and load two buttons in to the above-created frame.
self.button = Button(frame, text="QUIT", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame, text="Hello", command = self.f)
self.slogan.pack(side=RIGHT)

# Bind a key to each button from above.
master.bind('q', quit)
master.bind('f', self.f)

# Open the image, resize it...
self.image = Image.open(self.imgfilepath)
self.image.thumbnail((600,600))
# Make a tkinter-friendly image object ...
self.display_image = ImageTk.PhotoImage(self.image)
# Make a tkinter canvas, plug in the image, and pack the canvas.
self.canvas = Canvas(master, bg='red')
self.canvas.create_image(0,0, image=self.display_image, anchor="nw")
self.canvas.pack(fill=BOTH, expand=1)
### FIXME: Set canvas focus!

def f(self, event=None):
print 'in f()'
return 'hello world'

def get_image_list(self):
pass

def next_image(self):
pass

def previous_image(self):
pass

def load_image(self):
#stub
pass

def update_image(self):
pass

root = Tk()
abc = MyClass(root)
root.mainloop()

print 'abc has been defined'
print '"abc.f()" returns "%s"' % abc.f()
#print str(abc.f)
#print repr(abc.f)

print 'end'


The intention of the project is to make a simple image viewer in python, with buttons in the GUI for basic navigation functions, and keys mapped to those same functions.







share|improve this question





















  • This is the actual code I'm using. I haven't implemented the other functions yet, and I was hoping to just get the code implemented thus-far reviewed. In fact, the original question was just asking about reviewing one specific portion of the code - that is, the binding of the keystrokes in association with the buttons in the GUI. However, that specific-level of question was downvoted and given a recommendation to adhere to the guidance in the help center. I understand there may be a common issue of incomplete code segments posted, but I have truly included the entire module.
    – user3.1415927
    Apr 7 at 15:03










  • This question has been brought to attention on meta.
    – Simon Forsberg♦
    Apr 7 at 15:53











  • On the last edit: There really isn't a GUI-agnostic way to ask this question. Each library will have its own way of handling button binding. An answer in PyQT would be useless for tkinter.
    – Steven Vascellaro
    May 1 at 15:39











  • @StevenVascellaro interesting, I am unfamiliar with any other GUI options for python. In fact, I'd be open to suggestions with those other frameworks, if they are also pythonic - hence the leaving of the wording. Although I do understand the wording change suggestion (since my code was already using tkinter), I'd be open to the correction I see from time to time on SE of: 'Yes, it will work this way, but a better way is to XYZ.' I'm here to learn! :)
    – user3.1415927
    May 1 at 15:42










  • @user3.1415927 I'm using tkinter myself, but PyQT is a popular alternative. (See Graphic User Interface FAQ)
    – Steven Vascellaro
    May 1 at 15:45

















up vote
4
down vote

favorite
1












I'm specifically asking about binding a keyboard keystroke to a button in a GUI. Originally I planned to bind the keystroke to the GUI button itself, but that seemed impossible, and potentially unwise after I considered it later.



Is this the proper (pythonic) way to bind a keyboard key and GUI button?



## start.py
print 'start'

#from tkinter import *
from Tkinter import *
import os
from PIL import ImageTk, Image

class MyClass:
'''This is my class.'''

imgpath = '/Users/user/Dropbox/Camera Uploads'
imgfile = 'susshi.jpg'
#imgfilepath = os.path.join(self.imgpath, self.imgfile)
imgfilepath = os.path.join(imgpath, imgfile)

def __init__(self,master):
print 'in __init__'

# Create and load a frame into the tk (tkinter) window.
frame = Frame(master)
frame.pack()

# Create and load two buttons in to the above-created frame.
self.button = Button(frame, text="QUIT", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame, text="Hello", command = self.f)
self.slogan.pack(side=RIGHT)

# Bind a key to each button from above.
master.bind('q', quit)
master.bind('f', self.f)

# Open the image, resize it...
self.image = Image.open(self.imgfilepath)
self.image.thumbnail((600,600))
# Make a tkinter-friendly image object ...
self.display_image = ImageTk.PhotoImage(self.image)
# Make a tkinter canvas, plug in the image, and pack the canvas.
self.canvas = Canvas(master, bg='red')
self.canvas.create_image(0,0, image=self.display_image, anchor="nw")
self.canvas.pack(fill=BOTH, expand=1)
### FIXME: Set canvas focus!

def f(self, event=None):
print 'in f()'
return 'hello world'

def get_image_list(self):
pass

def next_image(self):
pass

def previous_image(self):
pass

def load_image(self):
#stub
pass

def update_image(self):
pass

root = Tk()
abc = MyClass(root)
root.mainloop()

print 'abc has been defined'
print '"abc.f()" returns "%s"' % abc.f()
#print str(abc.f)
#print repr(abc.f)

print 'end'


The intention of the project is to make a simple image viewer in python, with buttons in the GUI for basic navigation functions, and keys mapped to those same functions.







share|improve this question





















  • This is the actual code I'm using. I haven't implemented the other functions yet, and I was hoping to just get the code implemented thus-far reviewed. In fact, the original question was just asking about reviewing one specific portion of the code - that is, the binding of the keystrokes in association with the buttons in the GUI. However, that specific-level of question was downvoted and given a recommendation to adhere to the guidance in the help center. I understand there may be a common issue of incomplete code segments posted, but I have truly included the entire module.
    – user3.1415927
    Apr 7 at 15:03










  • This question has been brought to attention on meta.
    – Simon Forsberg♦
    Apr 7 at 15:53











  • On the last edit: There really isn't a GUI-agnostic way to ask this question. Each library will have its own way of handling button binding. An answer in PyQT would be useless for tkinter.
    – Steven Vascellaro
    May 1 at 15:39











  • @StevenVascellaro interesting, I am unfamiliar with any other GUI options for python. In fact, I'd be open to suggestions with those other frameworks, if they are also pythonic - hence the leaving of the wording. Although I do understand the wording change suggestion (since my code was already using tkinter), I'd be open to the correction I see from time to time on SE of: 'Yes, it will work this way, but a better way is to XYZ.' I'm here to learn! :)
    – user3.1415927
    May 1 at 15:42










  • @user3.1415927 I'm using tkinter myself, but PyQT is a popular alternative. (See Graphic User Interface FAQ)
    – Steven Vascellaro
    May 1 at 15:45













up vote
4
down vote

favorite
1









up vote
4
down vote

favorite
1






1





I'm specifically asking about binding a keyboard keystroke to a button in a GUI. Originally I planned to bind the keystroke to the GUI button itself, but that seemed impossible, and potentially unwise after I considered it later.



Is this the proper (pythonic) way to bind a keyboard key and GUI button?



## start.py
print 'start'

#from tkinter import *
from Tkinter import *
import os
from PIL import ImageTk, Image

class MyClass:
'''This is my class.'''

imgpath = '/Users/user/Dropbox/Camera Uploads'
imgfile = 'susshi.jpg'
#imgfilepath = os.path.join(self.imgpath, self.imgfile)
imgfilepath = os.path.join(imgpath, imgfile)

def __init__(self,master):
print 'in __init__'

# Create and load a frame into the tk (tkinter) window.
frame = Frame(master)
frame.pack()

# Create and load two buttons in to the above-created frame.
self.button = Button(frame, text="QUIT", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame, text="Hello", command = self.f)
self.slogan.pack(side=RIGHT)

# Bind a key to each button from above.
master.bind('q', quit)
master.bind('f', self.f)

# Open the image, resize it...
self.image = Image.open(self.imgfilepath)
self.image.thumbnail((600,600))
# Make a tkinter-friendly image object ...
self.display_image = ImageTk.PhotoImage(self.image)
# Make a tkinter canvas, plug in the image, and pack the canvas.
self.canvas = Canvas(master, bg='red')
self.canvas.create_image(0,0, image=self.display_image, anchor="nw")
self.canvas.pack(fill=BOTH, expand=1)
### FIXME: Set canvas focus!

def f(self, event=None):
print 'in f()'
return 'hello world'

def get_image_list(self):
pass

def next_image(self):
pass

def previous_image(self):
pass

def load_image(self):
#stub
pass

def update_image(self):
pass

root = Tk()
abc = MyClass(root)
root.mainloop()

print 'abc has been defined'
print '"abc.f()" returns "%s"' % abc.f()
#print str(abc.f)
#print repr(abc.f)

print 'end'


The intention of the project is to make a simple image viewer in python, with buttons in the GUI for basic navigation functions, and keys mapped to those same functions.







share|improve this question













I'm specifically asking about binding a keyboard keystroke to a button in a GUI. Originally I planned to bind the keystroke to the GUI button itself, but that seemed impossible, and potentially unwise after I considered it later.



Is this the proper (pythonic) way to bind a keyboard key and GUI button?



## start.py
print 'start'

#from tkinter import *
from Tkinter import *
import os
from PIL import ImageTk, Image

class MyClass:
'''This is my class.'''

imgpath = '/Users/user/Dropbox/Camera Uploads'
imgfile = 'susshi.jpg'
#imgfilepath = os.path.join(self.imgpath, self.imgfile)
imgfilepath = os.path.join(imgpath, imgfile)

def __init__(self,master):
print 'in __init__'

# Create and load a frame into the tk (tkinter) window.
frame = Frame(master)
frame.pack()

# Create and load two buttons in to the above-created frame.
self.button = Button(frame, text="QUIT", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame, text="Hello", command = self.f)
self.slogan.pack(side=RIGHT)

# Bind a key to each button from above.
master.bind('q', quit)
master.bind('f', self.f)

# Open the image, resize it...
self.image = Image.open(self.imgfilepath)
self.image.thumbnail((600,600))
# Make a tkinter-friendly image object ...
self.display_image = ImageTk.PhotoImage(self.image)
# Make a tkinter canvas, plug in the image, and pack the canvas.
self.canvas = Canvas(master, bg='red')
self.canvas.create_image(0,0, image=self.display_image, anchor="nw")
self.canvas.pack(fill=BOTH, expand=1)
### FIXME: Set canvas focus!

def f(self, event=None):
print 'in f()'
return 'hello world'

def get_image_list(self):
pass

def next_image(self):
pass

def previous_image(self):
pass

def load_image(self):
#stub
pass

def update_image(self):
pass

root = Tk()
abc = MyClass(root)
root.mainloop()

print 'abc has been defined'
print '"abc.f()" returns "%s"' % abc.f()
#print str(abc.f)
#print repr(abc.f)

print 'end'


The intention of the project is to make a simple image viewer in python, with buttons in the GUI for basic navigation functions, and keys mapped to those same functions.









share|improve this question












share|improve this question




share|improve this question








edited May 1 at 15:33
























asked Apr 7 at 14:09









user3.1415927

264




264











  • This is the actual code I'm using. I haven't implemented the other functions yet, and I was hoping to just get the code implemented thus-far reviewed. In fact, the original question was just asking about reviewing one specific portion of the code - that is, the binding of the keystrokes in association with the buttons in the GUI. However, that specific-level of question was downvoted and given a recommendation to adhere to the guidance in the help center. I understand there may be a common issue of incomplete code segments posted, but I have truly included the entire module.
    – user3.1415927
    Apr 7 at 15:03










  • This question has been brought to attention on meta.
    – Simon Forsberg♦
    Apr 7 at 15:53











  • On the last edit: There really isn't a GUI-agnostic way to ask this question. Each library will have its own way of handling button binding. An answer in PyQT would be useless for tkinter.
    – Steven Vascellaro
    May 1 at 15:39











  • @StevenVascellaro interesting, I am unfamiliar with any other GUI options for python. In fact, I'd be open to suggestions with those other frameworks, if they are also pythonic - hence the leaving of the wording. Although I do understand the wording change suggestion (since my code was already using tkinter), I'd be open to the correction I see from time to time on SE of: 'Yes, it will work this way, but a better way is to XYZ.' I'm here to learn! :)
    – user3.1415927
    May 1 at 15:42










  • @user3.1415927 I'm using tkinter myself, but PyQT is a popular alternative. (See Graphic User Interface FAQ)
    – Steven Vascellaro
    May 1 at 15:45

















  • This is the actual code I'm using. I haven't implemented the other functions yet, and I was hoping to just get the code implemented thus-far reviewed. In fact, the original question was just asking about reviewing one specific portion of the code - that is, the binding of the keystrokes in association with the buttons in the GUI. However, that specific-level of question was downvoted and given a recommendation to adhere to the guidance in the help center. I understand there may be a common issue of incomplete code segments posted, but I have truly included the entire module.
    – user3.1415927
    Apr 7 at 15:03










  • This question has been brought to attention on meta.
    – Simon Forsberg♦
    Apr 7 at 15:53











  • On the last edit: There really isn't a GUI-agnostic way to ask this question. Each library will have its own way of handling button binding. An answer in PyQT would be useless for tkinter.
    – Steven Vascellaro
    May 1 at 15:39











  • @StevenVascellaro interesting, I am unfamiliar with any other GUI options for python. In fact, I'd be open to suggestions with those other frameworks, if they are also pythonic - hence the leaving of the wording. Although I do understand the wording change suggestion (since my code was already using tkinter), I'd be open to the correction I see from time to time on SE of: 'Yes, it will work this way, but a better way is to XYZ.' I'm here to learn! :)
    – user3.1415927
    May 1 at 15:42










  • @user3.1415927 I'm using tkinter myself, but PyQT is a popular alternative. (See Graphic User Interface FAQ)
    – Steven Vascellaro
    May 1 at 15:45
















This is the actual code I'm using. I haven't implemented the other functions yet, and I was hoping to just get the code implemented thus-far reviewed. In fact, the original question was just asking about reviewing one specific portion of the code - that is, the binding of the keystrokes in association with the buttons in the GUI. However, that specific-level of question was downvoted and given a recommendation to adhere to the guidance in the help center. I understand there may be a common issue of incomplete code segments posted, but I have truly included the entire module.
– user3.1415927
Apr 7 at 15:03




This is the actual code I'm using. I haven't implemented the other functions yet, and I was hoping to just get the code implemented thus-far reviewed. In fact, the original question was just asking about reviewing one specific portion of the code - that is, the binding of the keystrokes in association with the buttons in the GUI. However, that specific-level of question was downvoted and given a recommendation to adhere to the guidance in the help center. I understand there may be a common issue of incomplete code segments posted, but I have truly included the entire module.
– user3.1415927
Apr 7 at 15:03












This question has been brought to attention on meta.
– Simon Forsberg♦
Apr 7 at 15:53





This question has been brought to attention on meta.
– Simon Forsberg♦
Apr 7 at 15:53













On the last edit: There really isn't a GUI-agnostic way to ask this question. Each library will have its own way of handling button binding. An answer in PyQT would be useless for tkinter.
– Steven Vascellaro
May 1 at 15:39





On the last edit: There really isn't a GUI-agnostic way to ask this question. Each library will have its own way of handling button binding. An answer in PyQT would be useless for tkinter.
– Steven Vascellaro
May 1 at 15:39













@StevenVascellaro interesting, I am unfamiliar with any other GUI options for python. In fact, I'd be open to suggestions with those other frameworks, if they are also pythonic - hence the leaving of the wording. Although I do understand the wording change suggestion (since my code was already using tkinter), I'd be open to the correction I see from time to time on SE of: 'Yes, it will work this way, but a better way is to XYZ.' I'm here to learn! :)
– user3.1415927
May 1 at 15:42




@StevenVascellaro interesting, I am unfamiliar with any other GUI options for python. In fact, I'd be open to suggestions with those other frameworks, if they are also pythonic - hence the leaving of the wording. Although I do understand the wording change suggestion (since my code was already using tkinter), I'd be open to the correction I see from time to time on SE of: 'Yes, it will work this way, but a better way is to XYZ.' I'm here to learn! :)
– user3.1415927
May 1 at 15:42












@user3.1415927 I'm using tkinter myself, but PyQT is a popular alternative. (See Graphic User Interface FAQ)
– Steven Vascellaro
May 1 at 15:45





@user3.1415927 I'm using tkinter myself, but PyQT is a popular alternative. (See Graphic User Interface FAQ)
– Steven Vascellaro
May 1 at 15:45











2 Answers
2






active

oldest

votes

















up vote
1
down vote













TL;DR: Yes, binding the keyboard key and button to the same function is a proper solution.



How to bind a keyboard key to a tkinter button



There are two ways to share a function between a bind keypress a command button.



Method 1: Use an optional event parameter



As you have already discovered yourself, you can use an optional event parameter that you don't depend on.



Since the parameter is unused, you can prefix it with an underscore (_event) to prevent warnings.



 self.button = Button(frame, text="Hello", command=self.func)
master.bind('f', self.func)

def func(self, _event=None):
print("Hello, world")


Full Example:



# from tkinter import Button, Frame, Tk # Python 3
from Tkinter import Button, Frame, Tk # Python 2

class MyClass:
def __init__(self, master):
frame = Frame(master)
frame.pack()

self.button = Button(frame, text="Hello", command=self.func)
self.button.pack(side='left')

master.bind('f', self.func)

def func(self, _event=None):
print("Hello, world")

root = Tk()
abc = MyClass(root)
root.mainloop()


Method 2: Use lambdas



If the event parameter isn't being used, you can discard it by binding your key to a lambda function.



 self.button = Button(frame, text="Hello", command=self.func)
master.bind('f', lambda event: self.func())

def func(self):
print("Hello, world")


Full Example:



# from tkinter import Button, Frame, Tk # Python 3
from Tkinter import Button, Frame, Tk # Python 2

class MyClass:
def __init__(self, master):
frame = Frame(master)
frame.pack()

self.button = Button(frame, text="Hello", command=self.func)
self.button.pack(side='left')

master.bind('f', lambda event: self.func())

def func(self):
print("Hello, world!")

root = Tk()
abc = MyClass(root)
root.mainloop()


(See How do I make Bind and Command do the same thing in tkinter?)




Miscellaneous tips



Avoid using wildcard imports



You should try to be explicit whenever you import in Python.



Yes



from Tkinter import Tk, Button, Frame


Yes



import Tkinter as tk


No



from Tkinter import *


(See Why is “import *” bad?)



Switch to Python 3



As coal_'s answer mentioned, development on Python 2 is scheduled to end in 2020. To ensure continued support, you should transition to Python 3 or later.



Use strings when packing constants



This is more personal preference than a rule, but I usually try to use strings when packing in tkinter. It means you don't have to import as many things.



Yes



self.button.pack(side="left")


No



self.button.pack(side=LEFT)





share|improve this answer























  • Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
    – Daniel
    May 1 at 15:33










  • @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
    – Steven Vascellaro
    May 1 at 15:37











  • As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
    – Daniel
    May 1 at 15:56






  • 1




    I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
    – Steven Vascellaro
    May 1 at 16:00


















up vote
0
down vote














Is this the proper(, pythonic) way to bind a keyboard key and GUI button?




Sure. It's hard to judge exactly what you mean by 'proper', but it works, and I don't see any major caveats with this approach. Binding the callback to the button and calling button.focus_set() works just as well, but your approach makes more sense. Think about it: Does the callback apply only to the button? At least in the case of the quit-callback, no; no matter what widget has focus, pressing 'q' should quit the application.



Some other remarks:



  1. Using wildcard imports (from <module> import *) is discouraged for a number of reasons. For one, using wildcard imports can cause conflicts if two symbols with the same name, defined in different namespaces, are imported into the global namespace. Secondly, for other developers, there's no way to quickly tell where an object was defined.


  2. PEP-8 proposes sorting import statements alphabetically.


  3. Unless you have compelling reasons to use Python 2, switch to Python 3! Version 2.7 will only be supported until 2020 (see PEP-373).






share|improve this answer





















    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191477%2fbinding-a-keyboard-key-to-a-tkinter-button%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    TL;DR: Yes, binding the keyboard key and button to the same function is a proper solution.



    How to bind a keyboard key to a tkinter button



    There are two ways to share a function between a bind keypress a command button.



    Method 1: Use an optional event parameter



    As you have already discovered yourself, you can use an optional event parameter that you don't depend on.



    Since the parameter is unused, you can prefix it with an underscore (_event) to prevent warnings.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    Method 2: Use lambdas



    If the event parameter isn't being used, you can discard it by binding your key to a lambda function.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world!")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    (See How do I make Bind and Command do the same thing in tkinter?)




    Miscellaneous tips



    Avoid using wildcard imports



    You should try to be explicit whenever you import in Python.



    Yes



    from Tkinter import Tk, Button, Frame


    Yes



    import Tkinter as tk


    No



    from Tkinter import *


    (See Why is “import *” bad?)



    Switch to Python 3



    As coal_'s answer mentioned, development on Python 2 is scheduled to end in 2020. To ensure continued support, you should transition to Python 3 or later.



    Use strings when packing constants



    This is more personal preference than a rule, but I usually try to use strings when packing in tkinter. It means you don't have to import as many things.



    Yes



    self.button.pack(side="left")


    No



    self.button.pack(side=LEFT)





    share|improve this answer























    • Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
      – Daniel
      May 1 at 15:33










    • @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
      – Steven Vascellaro
      May 1 at 15:37











    • As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
      – Daniel
      May 1 at 15:56






    • 1




      I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
      – Steven Vascellaro
      May 1 at 16:00















    up vote
    1
    down vote













    TL;DR: Yes, binding the keyboard key and button to the same function is a proper solution.



    How to bind a keyboard key to a tkinter button



    There are two ways to share a function between a bind keypress a command button.



    Method 1: Use an optional event parameter



    As you have already discovered yourself, you can use an optional event parameter that you don't depend on.



    Since the parameter is unused, you can prefix it with an underscore (_event) to prevent warnings.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    Method 2: Use lambdas



    If the event parameter isn't being used, you can discard it by binding your key to a lambda function.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world!")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    (See How do I make Bind and Command do the same thing in tkinter?)




    Miscellaneous tips



    Avoid using wildcard imports



    You should try to be explicit whenever you import in Python.



    Yes



    from Tkinter import Tk, Button, Frame


    Yes



    import Tkinter as tk


    No



    from Tkinter import *


    (See Why is “import *” bad?)



    Switch to Python 3



    As coal_'s answer mentioned, development on Python 2 is scheduled to end in 2020. To ensure continued support, you should transition to Python 3 or later.



    Use strings when packing constants



    This is more personal preference than a rule, but I usually try to use strings when packing in tkinter. It means you don't have to import as many things.



    Yes



    self.button.pack(side="left")


    No



    self.button.pack(side=LEFT)





    share|improve this answer























    • Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
      – Daniel
      May 1 at 15:33










    • @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
      – Steven Vascellaro
      May 1 at 15:37











    • As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
      – Daniel
      May 1 at 15:56






    • 1




      I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
      – Steven Vascellaro
      May 1 at 16:00













    up vote
    1
    down vote










    up vote
    1
    down vote









    TL;DR: Yes, binding the keyboard key and button to the same function is a proper solution.



    How to bind a keyboard key to a tkinter button



    There are two ways to share a function between a bind keypress a command button.



    Method 1: Use an optional event parameter



    As you have already discovered yourself, you can use an optional event parameter that you don't depend on.



    Since the parameter is unused, you can prefix it with an underscore (_event) to prevent warnings.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    Method 2: Use lambdas



    If the event parameter isn't being used, you can discard it by binding your key to a lambda function.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world!")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    (See How do I make Bind and Command do the same thing in tkinter?)




    Miscellaneous tips



    Avoid using wildcard imports



    You should try to be explicit whenever you import in Python.



    Yes



    from Tkinter import Tk, Button, Frame


    Yes



    import Tkinter as tk


    No



    from Tkinter import *


    (See Why is “import *” bad?)



    Switch to Python 3



    As coal_'s answer mentioned, development on Python 2 is scheduled to end in 2020. To ensure continued support, you should transition to Python 3 or later.



    Use strings when packing constants



    This is more personal preference than a rule, but I usually try to use strings when packing in tkinter. It means you don't have to import as many things.



    Yes



    self.button.pack(side="left")


    No



    self.button.pack(side=LEFT)





    share|improve this answer















    TL;DR: Yes, binding the keyboard key and button to the same function is a proper solution.



    How to bind a keyboard key to a tkinter button



    There are two ways to share a function between a bind keypress a command button.



    Method 1: Use an optional event parameter



    As you have already discovered yourself, you can use an optional event parameter that you don't depend on.



    Since the parameter is unused, you can prefix it with an underscore (_event) to prevent warnings.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', self.func)

    def func(self, _event=None):
    print("Hello, world")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    Method 2: Use lambdas



    If the event parameter isn't being used, you can discard it by binding your key to a lambda function.



     self.button = Button(frame, text="Hello", command=self.func)
    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world")


    Full Example:



    # from tkinter import Button, Frame, Tk # Python 3
    from Tkinter import Button, Frame, Tk # Python 2

    class MyClass:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack()

    self.button = Button(frame, text="Hello", command=self.func)
    self.button.pack(side='left')

    master.bind('f', lambda event: self.func())

    def func(self):
    print("Hello, world!")

    root = Tk()
    abc = MyClass(root)
    root.mainloop()


    (See How do I make Bind and Command do the same thing in tkinter?)




    Miscellaneous tips



    Avoid using wildcard imports



    You should try to be explicit whenever you import in Python.



    Yes



    from Tkinter import Tk, Button, Frame


    Yes



    import Tkinter as tk


    No



    from Tkinter import *


    (See Why is “import *” bad?)



    Switch to Python 3



    As coal_'s answer mentioned, development on Python 2 is scheduled to end in 2020. To ensure continued support, you should transition to Python 3 or later.



    Use strings when packing constants



    This is more personal preference than a rule, but I usually try to use strings when packing in tkinter. It means you don't have to import as many things.



    Yes



    self.button.pack(side="left")


    No



    self.button.pack(side=LEFT)






    share|improve this answer















    share|improve this answer



    share|improve this answer








    edited May 1 at 17:40


























    answered May 1 at 15:11









    Steven Vascellaro

    1277




    1277











    • Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
      – Daniel
      May 1 at 15:33










    • @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
      – Steven Vascellaro
      May 1 at 15:37











    • As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
      – Daniel
      May 1 at 15:56






    • 1




      I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
      – Steven Vascellaro
      May 1 at 16:00

















    • Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
      – Daniel
      May 1 at 15:33










    • @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
      – Steven Vascellaro
      May 1 at 15:37











    • As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
      – Daniel
      May 1 at 15:56






    • 1




      I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
      – Steven Vascellaro
      May 1 at 16:00
















    Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
    – Daniel
    May 1 at 15:33




    Unused variables are typically named _. Prefixing a name with an underscore is usually done to distinguish 'private' names from 'public' names (those listed in __all__, or at least those part of the API).
    – Daniel
    May 1 at 15:33












    @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
    – Steven Vascellaro
    May 1 at 15:37





    @Coal_ I remember seeing unused _ arguments suggested as a PEP proposal. Was that proposal ever approved?
    – Steven Vascellaro
    May 1 at 15:37













    As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
    – Daniel
    May 1 at 15:56




    As a PEP on its own? I'm looking through the list of PEPs now, but can't find it.
    – Daniel
    May 1 at 15:56




    1




    1




    I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
    – Steven Vascellaro
    May 1 at 16:00





    I may have been mistaken about PEP. I’ve found there isn’t much consensus on how to name unused arguments, but Pylint favors descriptive names prefixed with underscore.
    – Steven Vascellaro
    May 1 at 16:00













    up vote
    0
    down vote














    Is this the proper(, pythonic) way to bind a keyboard key and GUI button?




    Sure. It's hard to judge exactly what you mean by 'proper', but it works, and I don't see any major caveats with this approach. Binding the callback to the button and calling button.focus_set() works just as well, but your approach makes more sense. Think about it: Does the callback apply only to the button? At least in the case of the quit-callback, no; no matter what widget has focus, pressing 'q' should quit the application.



    Some other remarks:



    1. Using wildcard imports (from <module> import *) is discouraged for a number of reasons. For one, using wildcard imports can cause conflicts if two symbols with the same name, defined in different namespaces, are imported into the global namespace. Secondly, for other developers, there's no way to quickly tell where an object was defined.


    2. PEP-8 proposes sorting import statements alphabetically.


    3. Unless you have compelling reasons to use Python 2, switch to Python 3! Version 2.7 will only be supported until 2020 (see PEP-373).






    share|improve this answer

























      up vote
      0
      down vote














      Is this the proper(, pythonic) way to bind a keyboard key and GUI button?




      Sure. It's hard to judge exactly what you mean by 'proper', but it works, and I don't see any major caveats with this approach. Binding the callback to the button and calling button.focus_set() works just as well, but your approach makes more sense. Think about it: Does the callback apply only to the button? At least in the case of the quit-callback, no; no matter what widget has focus, pressing 'q' should quit the application.



      Some other remarks:



      1. Using wildcard imports (from <module> import *) is discouraged for a number of reasons. For one, using wildcard imports can cause conflicts if two symbols with the same name, defined in different namespaces, are imported into the global namespace. Secondly, for other developers, there's no way to quickly tell where an object was defined.


      2. PEP-8 proposes sorting import statements alphabetically.


      3. Unless you have compelling reasons to use Python 2, switch to Python 3! Version 2.7 will only be supported until 2020 (see PEP-373).






      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote










        Is this the proper(, pythonic) way to bind a keyboard key and GUI button?




        Sure. It's hard to judge exactly what you mean by 'proper', but it works, and I don't see any major caveats with this approach. Binding the callback to the button and calling button.focus_set() works just as well, but your approach makes more sense. Think about it: Does the callback apply only to the button? At least in the case of the quit-callback, no; no matter what widget has focus, pressing 'q' should quit the application.



        Some other remarks:



        1. Using wildcard imports (from <module> import *) is discouraged for a number of reasons. For one, using wildcard imports can cause conflicts if two symbols with the same name, defined in different namespaces, are imported into the global namespace. Secondly, for other developers, there's no way to quickly tell where an object was defined.


        2. PEP-8 proposes sorting import statements alphabetically.


        3. Unless you have compelling reasons to use Python 2, switch to Python 3! Version 2.7 will only be supported until 2020 (see PEP-373).






        share|improve this answer














        Is this the proper(, pythonic) way to bind a keyboard key and GUI button?




        Sure. It's hard to judge exactly what you mean by 'proper', but it works, and I don't see any major caveats with this approach. Binding the callback to the button and calling button.focus_set() works just as well, but your approach makes more sense. Think about it: Does the callback apply only to the button? At least in the case of the quit-callback, no; no matter what widget has focus, pressing 'q' should quit the application.



        Some other remarks:



        1. Using wildcard imports (from <module> import *) is discouraged for a number of reasons. For one, using wildcard imports can cause conflicts if two symbols with the same name, defined in different namespaces, are imported into the global namespace. Secondly, for other developers, there's no way to quickly tell where an object was defined.


        2. PEP-8 proposes sorting import statements alphabetically.


        3. Unless you have compelling reasons to use Python 2, switch to Python 3! Version 2.7 will only be supported until 2020 (see PEP-373).







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered Apr 10 at 10:08









        Daniel

        4,1132836




        4,1132836






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191477%2fbinding-a-keyboard-key-to-a-tkinter-button%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Python Lists

            Aion

            JavaScript Array Iteration Methods