Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Tkinter doesn’t suck!
                               Honest!




Saturday, 7 November 2009
“What GUI toolkit
                              should I use?”

                                 – random poster in random...
wxWindows!



Saturday, 7 November 2009
import wx

      class Application(wx.Frame):
          def __init__(self, parent):
              wx.Frame.__init__(self, ...
pyGTK



Saturday, 7 November 2009
import gtk

                            window = gtk.Window()
                            label = gtk.Label("Hello, world"...
PyQt!



Saturday, 7 November 2009
import sys
                            import PyQt4.Qt as qt

                            a=qt.QApplication(sys.argv)
    ...
“whatever you do...



Saturday, 7 November 2009
...don’t use Tkinter!”



Saturday, 7 November 2009
“Tkinter sucks!”



Saturday, 7 November 2009
import Tkinter as tk

                            root = tk.Tk()
                            tk.Label(root, text="Hello, w...
“yeah, OMG, Tkinter
                                   sucks!”


Saturday, 7 November 2009
I disagree



Saturday, 7 November 2009
1. it’s simple to use
                                               - rich base widget set
                              ...
2. it’s always there

                                               on Windows & OS X

                                  ...
3. it’s mature

                                         first release 1991
                                         8.0 r...
how I discovered this
                               I had this project that I wanted to be click-to-run, but needed to se...
filename = tkFileDialog.askopenfilename(parent=root,
                         filetypes=[('ReStructuredText Files', '.rst ...
Saturday, 7 November 2009
well, if it can do that...

                                     what about the program’s command-line options?




Saturd...
Saturday, 7 November 2009
self.root = tk.Tk()
   frame = Tk.Frame(self.root)
   frame.pack()

   Tk.Label(frame, text='Bruce, the Presentation Tool!...
specific Tkinter gripes



Saturday, 7 November 2009
1. it’s not pretty



Saturday, 7 November 2009
1. it’s not pretty
                             1. it doesn’t look native,
                             2. fonts are not a...
2. extending is tricky



Saturday, 7 November 2009
native look and feel
                                 (since Tk 8.0, 1999)




Saturday, 7 November 2009
native look and feel
                                   (since Tk 8.0, 1999)
                             (much improved i...
native look and feel
                                   (since Tk 8.0, 1999)
                             (much improved i...
Saturday, 7 November 2009
Saturday, 7 November 2009
truetype / opentype
                                   fonts
                                  (since Tk 8.5)




Saturday...
1. Simple to use



Saturday, 7 November 2009
Widgets



Saturday, 7 November 2009
import Tkinter as tk

                            root = tk.Tk()
                            tk.Label(root, text="Hello, w...
import Tkinter as tk

                            root = tk.Tk()
                            tk.Label(root, text="Hello, w...
from PIL import Image, ImageTk
                            image = ImageTk.PhotoImage(Image.open('kitten.jpg'))
          ...
def pressed():
                                print 'You pressed me!'

                            tk.Button(root, text='...
entry = tk.Entry(root)
                            entry.pack()
                            entry.insert(0, 'some text')

...
value = tk.IntVar()
                            tk.Checkbutton(root, text='Checked?',
                                    ...
value = tk.IntVar()
                            for n in range(4):
                                tk.Radiobutton(root, va...
value = tk.StringVar(value='One')
                            tk.OptionMenu(root, value, 'One', 'Two',
                   ...
listbox = tk.Listbox(root)
                            listbox.pack()
                            listbox.insert(tk.END, "...
text = tk.Text(root)
                            text.pack()
                            text.insert(tk.END, '''some text
...
scale = tk.Scale(root, from_=0, to=100)
                            scale.pack()




Saturday, 7 November 2009
w = tk.Canvas(root, width=200, height=100)
                            w.pack()
                            w.create_line(...
1. Simple to use



Saturday, 7 November 2009
Packing



Saturday, 7 November 2009
rows or columns
                                              the pack manager packs
                                     ...
in the beginning there is
                            a container, and it is
                            empty

          ...
tk.Button(root, text='Press me!').pack()




                                                                       pack a...
tk.Button(root, text='Press me!').pack()
                            tk.Button(root, text='Press me too!').pack()




    ...
tk.Button(root, text='Press me!').pack()
                            tk.Button(root, text='Press me too!').pack()
        ...
tk.Button(root, text='Press me!').pack(side=tk.LEFT)
                   tk.Button(root, text='Press me too!').pack(side=tk...
tk.Button(root, text='Press me!').pack(side=tk.RIGHT)
                   tk.Button(root, text='Press me too!').pack(side=t...
more complex packing?



Saturday, 7 November 2009
tk.Button(root, text='Press me!').pack()
               horizontal = tk.Frame(root)
               horizontal.pack()
     ...
grids



Saturday, 7 November 2009
tk.Button(root, text='Press me!').grid(row=0, column=0)
               tk.Message(root, text='Pressnmentoo!').grid(row=1, ...
... or place



Saturday, 7 November 2009
Widget values



Saturday, 7 November 2009
widgets with a variable
                            variable = tk.IntVar()
                            value = variable.ge...
text widgets
                            entry = tk.Entry()
                            value = entry.get()
              ...
list boxes
                            listbox = tk.Listbox(root)
                            listbox.pack()
             ...
Styling



Saturday, 7 November 2009
2 methods:
                            1. direct
                            2. themed (py2.6+, py3k+)




Saturday, 7 Nov...
tk.Label(root, text="Hello, world!",
                                     background='black',
                            ...
tk.Button(root, text="Hello, world!",
                                     background='black',
                           ...
Option 2: Themed



Saturday, 7 November 2009
from [tT]kinter import ttk
                             lower-case “t” in py3k+

                             If you want ...
complementary
                                  Though the themed widget commands work similarly to the originals,
       ...
Implements
                            button, checkbutton, entry, label,
                            menubutton, radiobut...
Added
                            combobox, notebook,
                            progressbar, separator,
                ...
Not present
                             canvas, listbox,
                            menu, spinbox, text


              ...
“classes” and “styles”
                            >>> from tkinter import ttk
                            >>> l = ttk.Lab...
layout example (button)



Saturday, 7 November 2009
>>> style = ttk.Style()
        >>> style.layout('TButton')
        [("Button.border", {"children": [("Button.focus", {"ch...
element options
     >>> style = ttk.Style()
     >>> style.element_options('Button.label')
     ('-compound', '-space', '...
style = ttk.Style()
          style.configure("Red.TLabel", foreground="red", font="Courier 32")
          ttk.Label(text=...
switching themes
                            style = ttk.Style()
                            current_theme = style.theme_u...
Events



Saturday, 7 November 2009
bind(), unbind()
                            def callback(event):
                                print "clicked at", even...
<modifier-type-detail>



Saturday, 7 November 2009
mouse event types
                            mouse button    <Button-1>, <Button-2>, <Button-3>

                        ...
keyboard event types
                               focus         <FocusIn>, <FocusOut>

                                 ...
special event types
                            configuration       <Configure>




                                       ...
Canvas
                            w = tk.Canvas(root, width=400, height=300)
                            w.pack()




Sat...
w.create_line(0, 0, 400, 300)




Saturday, 7 November 2009
w.create_line(0, 300, 400, 0,fill="red", dash=(4, 4))




Saturday, 7 November 2009
w.create_rectangle(150, 125, 250, 175, outline="green", fill="blue")




                                                 ...
w.create_arc(50, 50, 200, 200, outline="blue", fill="green")




Saturday, 7 November 2009
w.create_oval(200, 200, 250, 250, outline="blue", fill="green")




Saturday, 7 November 2009
from PIL import Image, ImageTk
                            image = ImageTk.PhotoImage(Image.open('kitten.jpg'))
          ...
Tips



Saturday, 7 November 2009
self.attributes('-topmost', True)




Saturday, 7 November 2009
Upcoming SlideShare
Loading in …5
×

Tkinter Does Not Suck

43,659 views

Published on

In which I attempt to convince the audience that Tkinter does not, in fact, suck.

Published in: Technology

Tkinter Does Not Suck

  1. 1. Tkinter doesn’t suck! Honest! Saturday, 7 November 2009
  2. 2. “What GUI toolkit should I use?” – random poster in random forum Saturday, 7 November 2009
  3. 3. wxWindows! Saturday, 7 November 2009
  4. 4. import wx class Application(wx.Frame): def __init__(self, parent): wx.Frame.__init__(self, parent, -1, 'My GUI', size=(300, 200)) panel = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) panel.SetSizer(sizer) txt = wx.StaticText(panel, -1, 'Hello, world') sizer.Add(txt, 0, wx.TOP|wx.LEFT, 20) self.Centre() self.Show(True) app = wx.App(0) Application(None) app.MainLoop() Saturday, 7 November 2009
  5. 5. pyGTK Saturday, 7 November 2009
  6. 6. import gtk window = gtk.Window() label = gtk.Label("Hello, world") window.add(label) window.show_all() gtk.main() Saturday, 7 November 2009
  7. 7. PyQt! Saturday, 7 November 2009
  8. 8. import sys import PyQt4.Qt as qt a=qt.QApplication(sys.argv) w=qt.QLabel("Hello, world") w.show() a.exec_() Saturday, 7 November 2009
  9. 9. “whatever you do... Saturday, 7 November 2009
  10. 10. ...don’t use Tkinter!” Saturday, 7 November 2009
  11. 11. “Tkinter sucks!” Saturday, 7 November 2009
  12. 12. import Tkinter as tk root = tk.Tk() tk.Label(root, text="Hello, world").pack() root.mainloop() Saturday, 7 November 2009
  13. 13. “yeah, OMG, Tkinter sucks!” Saturday, 7 November 2009
  14. 14. I disagree Saturday, 7 November 2009
  15. 15. 1. it’s simple to use - rich base widget set - which is not verbose - automatic packing Saturday, 7 November 2009
  16. 16. 2. it’s always there on Windows & OS X -- on Linuxes you might need to install an optional package Saturday, 7 November 2009
  17. 17. 3. it’s mature first release 1991 8.0 released August 1999 8.5 released December 2007 Saturday, 7 November 2009
  18. 18. how I discovered this I had this project that I wanted to be click-to-run, but needed to select a file Looked for a cross-platform “file dialog” solution and found some hacks Then I noticed a reference to Tkinter, and lo and behold... Saturday, 7 November 2009
  19. 19. filename = tkFileDialog.askopenfilename(parent=root, filetypes=[('ReStructuredText Files', '.rst .txt'), ('All Files', '.*')], title='Select your presentation file') Saturday, 7 November 2009
  20. 20. Saturday, 7 November 2009
  21. 21. well, if it can do that... what about the program’s command-line options? Saturday, 7 November 2009
  22. 22. Saturday, 7 November 2009
  23. 23. self.root = tk.Tk() frame = Tk.Frame(self.root) frame.pack() Tk.Label(frame, text='Bruce, the Presentation Tool!').pack() self.fullscreen = Tk.IntVar() Tk.Checkbutton(frame, text='Fullscreen?', variable=self.fullscreen).pack() # screen selection display = pyglet.window.get_platform().get_default_display() N = len(display.get_screens()) self.screen = Tk.IntVar(0) if N > 1: for n in range(N): Tk.Radiobutton(frame, text="Display on screen %d"%(n+1), variable=self.screen, value=n).pack() self.timer = Tk.IntVar() Tk.Checkbutton(frame, text='Show Timer?', variable=self.timer).pack() self.page_count = Tk.IntVar() Tk.Checkbutton(frame, text='Show Page Count?', variable=self.page_count).pack() self.bullet_mode = Tk.IntVar() Tk.Checkbutton(frame, text='Run in Bullet Mode?', variable=self.bullet_mode).pack() self.source = Tk.IntVar() Tk.Checkbutton(frame, text='Display source in console?', variable=self.source).pack() Tk.Button(frame, text='Play Presentation', command=self.go).pack() Saturday, 7 November 2009
  24. 24. specific Tkinter gripes Saturday, 7 November 2009
  25. 25. 1. it’s not pretty Saturday, 7 November 2009
  26. 26. 1. it’s not pretty 1. it doesn’t look native, 2. fonts are not anti-aliased Saturday, 7 November 2009
  27. 27. 2. extending is tricky Saturday, 7 November 2009
  28. 28. native look and feel (since Tk 8.0, 1999) Saturday, 7 November 2009
  29. 29. native look and feel (since Tk 8.0, 1999) (much improved in Tk 8.5, 2008) Saturday, 7 November 2009
  30. 30. native look and feel (since Tk 8.0, 1999) (much improved in Tk 8.5, 2008) (“less ugly but not perfect”) Saturday, 7 November 2009
  31. 31. Saturday, 7 November 2009
  32. 32. Saturday, 7 November 2009
  33. 33. truetype / opentype fonts (since Tk 8.5) Saturday, 7 November 2009
  34. 34. 1. Simple to use Saturday, 7 November 2009
  35. 35. Widgets Saturday, 7 November 2009
  36. 36. import Tkinter as tk root = tk.Tk() tk.Label(root, text="Hello, world").pack() root.mainloop() demo image display label properties: foreground, background, font, ??? Saturday, 7 November 2009
  37. 37. import Tkinter as tk root = tk.Tk() tk.Label(root, text="Hello, world").pack() root.mainloop() No point showing the other three lines in other examples Saturday, 7 November 2009
  38. 38. from PIL import Image, ImageTk image = ImageTk.PhotoImage(Image.open('kitten.jpg')) tk.Label(root, image=image).pack() Saturday, 7 November 2009
  39. 39. def pressed(): print 'You pressed me!' tk.Button(root, text='Press me!', command=pressed).pack() Saturday, 7 November 2009
  40. 40. entry = tk.Entry(root) entry.pack() entry.insert(0, 'some text') Saturday, 7 November 2009
  41. 41. value = tk.IntVar() tk.Checkbutton(root, text='Checked?', variable=value).pack() Saturday, 7 November 2009
  42. 42. value = tk.IntVar() for n in range(4): tk.Radiobutton(root, value=n text="Selection %d"%(n+1), variable=value).pack() Saturday, 7 November 2009
  43. 43. value = tk.StringVar(value='One') tk.OptionMenu(root, value, 'One', 'Two', 'Three').pack() 10 minutes Saturday, 7 November 2009
  44. 44. listbox = tk.Listbox(root) listbox.pack() listbox.insert(tk.END, "a list entry") for item in ‘one two three four’.split(): listbox.insert(tk.END, item) Saturday, 7 November 2009
  45. 45. text = tk.Text(root) text.pack() text.insert(tk.END, '''some text more text''') also allows: - embedding of images and widgets - searching - tagging (identification, useful for properties) - styles Saturday, 7 November 2009
  46. 46. scale = tk.Scale(root, from_=0, to=100) scale.pack() Saturday, 7 November 2009
  47. 47. w = tk.Canvas(root, width=200, height=100) w.pack() w.create_line(0, 0, 200, 100) w.create_line(0, 100, 200, 0, fill="red", dash=(4, 4)) w.create_rectangle(50, 25, 150, 75, fill="blue") - line (with arrows), arc, image, oval, polygon, rectangle, text, widgets - outline, fill - scrollable (limitable) - picking (with closest) Saturday, 7 November 2009
  48. 48. 1. Simple to use Saturday, 7 November 2009
  49. 49. Packing Saturday, 7 November 2009
  50. 50. rows or columns the pack manager packs into rows or columns the default is column, centered. Saturday, 7 November 2009
  51. 51. in the beginning there is a container, and it is empty we’re going to pack this container at the default tk.TOP Saturday, 7 November 2009
  52. 52. tk.Button(root, text='Press me!').pack() pack a button Saturday, 7 November 2009
  53. 53. tk.Button(root, text='Press me!').pack() tk.Button(root, text='Press me too!').pack() pack a button Saturday, 7 November 2009
  54. 54. tk.Button(root, text='Press me!').pack() tk.Button(root, text='Press me too!').pack() tk.Button(root, text='And me!').pack() pack a button Saturday, 7 November 2009
  55. 55. tk.Button(root, text='Press me!').pack(side=tk.LEFT) tk.Button(root, text='Press me too!').pack(side=tk.LEFT) tk.Button(root, text='And me!').pack(side=tk.LEFT) pack on tk.LEFT instead Saturday, 7 November 2009
  56. 56. tk.Button(root, text='Press me!').pack(side=tk.RIGHT) tk.Button(root, text='Press me too!').pack(side=tk.RIGHT) tk.Button(root, text='And me!').pack(side=tk.RIGHT) pack on tk.RIGHT instead Saturday, 7 November 2009
  57. 57. more complex packing? Saturday, 7 November 2009
  58. 58. tk.Button(root, text='Press me!').pack() horizontal = tk.Frame(root) horizontal.pack() tk.Button(horizontal, text='Press me too!').pack(side=tk.LEFT) tk.Button(horizontal, text='Press me too!').pack(side=tk.LEFT) Saturday, 7 November 2009
  59. 59. grids Saturday, 7 November 2009
  60. 60. tk.Button(root, text='Press me!').grid(row=0, column=0) tk.Message(root, text='Pressnmentoo!').grid(row=1, column=0) tk.Button(root, text='And me!').grid(row=1, column=1) those are tk.CENTER “sticky” other options are the 9 points of the compass pack() also allows the sticky side to be specified see I snuck in the multiline “Message” widget there? Saturday, 7 November 2009
  61. 61. ... or place Saturday, 7 November 2009
  62. 62. Widget values Saturday, 7 November 2009
  63. 63. widgets with a variable variable = tk.IntVar() value = variable.get() variable.set(value) Saturday, 7 November 2009
  64. 64. text widgets entry = tk.Entry() value = entry.get() entry.delete(0, tk.END) entry.insert(0, value) Saturday, 7 November 2009
  65. 65. list boxes listbox = tk.Listbox(root) listbox.pack() for item in ‘one two three four’.split(): listbox.insert(tk.END, item) selected = list.curselection() Saturday, 7 November 2009
  66. 66. Styling Saturday, 7 November 2009
  67. 67. 2 methods: 1. direct 2. themed (py2.6+, py3k+) Saturday, 7 November 2009
  68. 68. tk.Label(root, text="Hello, world!", background='black', foreground='white', font='Courier').pack() Saturday, 7 November 2009
  69. 69. tk.Button(root, text="Hello, world!", background='black', foreground='white', font='Courier').pack() some limitations (sometimes depending on your theme) Saturday, 7 November 2009
  70. 70. Option 2: Themed Saturday, 7 November 2009
  71. 71. from [tT]kinter import ttk lower-case “t” in py3k+ If you want it earlier you can install the tile extension Saturday, 7 November 2009
  72. 72. complementary Though the themed widget commands work similarly to the originals, there are important differences. Themed widgets are not a drop-in replacement. In particular, themed widgets generally provide less options for customizing their appearance than regular Tk widgets (e.g. they will often not have options like "-background"). Such changes, if needed (and they should be needed much less often) must be done by defining new widget styles, using the facilities offered by the themed widget package. Saturday, 7 November 2009
  73. 73. Implements button, checkbutton, entry, label, menubutton, radiobutton, scale, scrollbar, frame, labelframe, panedwindow Saturday, 7 November 2009
  74. 74. Added combobox, notebook, progressbar, separator, sizegrip Saturday, 7 November 2009
  75. 75. Not present canvas, listbox, menu, spinbox, text these aren’t really needed Saturday, 7 November 2009
  76. 76. “classes” and “styles” >>> from tkinter import ttk >>> l = ttk.Label('hello, world!') >>> l.winfo_class() 'TLabel' >>> l['style'] '' Saturday, 7 November 2009
  77. 77. layout example (button) Saturday, 7 November 2009
  78. 78. >>> style = ttk.Style() >>> style.layout('TButton') [("Button.border", {"children": [("Button.focus", {"children": [("Button.spacing", {"children": [("Button.label", {"sticky": "nswe"})], "sticky": "nswe"})], "sticky": "nswe"})], "sticky": "nswe", "border": "1"})] Saturday, 7 November 2009
  79. 79. element options >>> style = ttk.Style() >>> style.element_options('Button.label') ('-compound', '-space', '-text', '-font', '-foreground', '-underline', '-width', '-anchor', '-justify', '-wraplength', '-embossed', '-image', '-stipple', '-background') Saturday, 7 November 2009
  80. 80. style = ttk.Style() style.configure("Red.TLabel", foreground="red", font="Courier 32") ttk.Label(text="Test Styled", style="Red.TLabel").pack() ttk.Label(text="Test Unstyled").pack() Saturday, 7 November 2009
  81. 81. switching themes style = ttk.Style() current_theme = style.theme_use() new_theme = style.theme_create(...) style.theme_use(new_theme) Saturday, 7 November 2009
  82. 82. Events Saturday, 7 November 2009
  83. 83. bind(), unbind() def callback(event): print "clicked at", event.x, event.y frame = Frame(root, width=100, height=100) frame.bind("<Button-1>", callback) Saturday, 7 November 2009
  84. 84. <modifier-type-detail> Saturday, 7 November 2009
  85. 85. mouse event types mouse button <Button-1>, <Button-2>, <Button-3> mouse drag <B1-Motion> mouse release <ButtonRelease-1>, ... double click <Double-Button-1>, ... triple click <Triple-Button-1>, ... mouse entered <Enter> mouse left <Leave> Saturday, 7 November 2009
  86. 86. keyboard event types focus <FocusIn>, <FocusOut> <Enter>, <Delete>, <Left>, specific keys <Right>, ... any key <Key> any text a, b, 1, 2, ... <Shift-Up>, <Alt-Enter>, modified keys <Control-Tab>, ... Saturday, 7 November 2009
  87. 87. special event types configuration <Configure> The widget changed size (or location, on some platforms). The new size is provided in the width and height attributes of the event object passed to the callback. Saturday, 7 November 2009
  88. 88. Canvas w = tk.Canvas(root, width=400, height=300) w.pack() Saturday, 7 November 2009
  89. 89. w.create_line(0, 0, 400, 300) Saturday, 7 November 2009
  90. 90. w.create_line(0, 300, 400, 0,fill="red", dash=(4, 4)) Saturday, 7 November 2009
  91. 91. w.create_rectangle(150, 125, 250, 175, outline="green", fill="blue") specify corders, outline and fill colors Saturday, 7 November 2009
  92. 92. w.create_arc(50, 50, 200, 200, outline="blue", fill="green") Saturday, 7 November 2009
  93. 93. w.create_oval(200, 200, 250, 250, outline="blue", fill="green") Saturday, 7 November 2009
  94. 94. from PIL import Image, ImageTk image = ImageTk.PhotoImage(Image.open('kitten.jpg')) w.create_image((0, 0), image=image, anchor=tk.NW) Saturday, 7 November 2009
  95. 95. Tips Saturday, 7 November 2009
  96. 96. self.attributes('-topmost', True) Saturday, 7 November 2009

×