Tkinter Does Not Suck
Upcoming SlideShare
Loading in...5
×
 

Tkinter Does Not Suck

on

  • 22,521 views

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

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

Statistics

Views

Total Views
22,521
Views on SlideShare
21,547
Embed Views
974

Actions

Likes
9
Downloads
189
Comments
2

10 Embeds 974

http://www.redditmedia.com 767
http://sukhbinder.wordpress.com 148
http://www.slideshare.net 40
https://twitter.com 4
http://www.linkedin.com 4
http://www.techgig.com 4
http://plus.url.google.com 3
http://us-w1.rockmelt.com 2
https://si0.twimg.com 1
http://feedly.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Tkinter Does Not Suck Tkinter Does Not Suck Presentation Transcript

  • Tkinter doesn’t suck! Honest! Saturday, 7 November 2009
  • “What GUI toolkit should I use?” – random poster in random forum Saturday, 7 November 2009
  • wxWindows! Saturday, 7 November 2009
  • 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
  • pyGTK Saturday, 7 November 2009
  • import gtk window = gtk.Window() label = gtk.Label("Hello, world") window.add(label) window.show_all() gtk.main() Saturday, 7 November 2009
  • PyQt! Saturday, 7 November 2009
  • 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
  • “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, world").pack() root.mainloop() Saturday, 7 November 2009
  • “yeah, OMG, Tkinter sucks!” Saturday, 7 November 2009
  • I disagree Saturday, 7 November 2009
  • 1. it’s simple to use - rich base widget set - which is not verbose - automatic packing Saturday, 7 November 2009
  • 2. it’s always there on Windows & OS X -- on Linuxes you might need to install an optional package Saturday, 7 November 2009
  • 3. it’s mature first release 1991 8.0 released August 1999 8.5 released December 2007 Saturday, 7 November 2009
  • 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
  • filename = tkFileDialog.askopenfilename(parent=root, filetypes=[('ReStructuredText Files', '.rst .txt'), ('All Files', '.*')], title='Select your presentation file') Saturday, 7 November 2009
  • Saturday, 7 November 2009
  • well, if it can do that... what about the program’s command-line options? Saturday, 7 November 2009
  • Saturday, 7 November 2009
  • 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
  • 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 anti-aliased Saturday, 7 November 2009
  • 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 in Tk 8.5, 2008) Saturday, 7 November 2009
  • 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
  • Saturday, 7 November 2009
  • Saturday, 7 November 2009
  • truetype / opentype fonts (since Tk 8.5) Saturday, 7 November 2009
  • 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, world").pack() root.mainloop() demo image display label properties: foreground, background, font, ??? Saturday, 7 November 2009
  • 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
  • from PIL import Image, ImageTk image = ImageTk.PhotoImage(Image.open('kitten.jpg')) tk.Label(root, image=image).pack() Saturday, 7 November 2009
  • def pressed(): print 'You pressed me!' tk.Button(root, text='Press me!', command=pressed).pack() Saturday, 7 November 2009
  • entry = tk.Entry(root) entry.pack() entry.insert(0, 'some text') Saturday, 7 November 2009
  • value = tk.IntVar() tk.Checkbutton(root, text='Checked?', variable=value).pack() Saturday, 7 November 2009
  • 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
  • value = tk.StringVar(value='One') tk.OptionMenu(root, value, 'One', 'Two', 'Three').pack() 10 minutes Saturday, 7 November 2009
  • 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
  • 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
  • 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(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
  • 1. Simple to use Saturday, 7 November 2009
  • Packing Saturday, 7 November 2009
  • rows or columns the pack manager packs into rows or columns the default is column, centered. Saturday, 7 November 2009
  • 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
  • tk.Button(root, text='Press me!').pack() pack a button Saturday, 7 November 2009
  • tk.Button(root, text='Press me!').pack() tk.Button(root, text='Press me too!').pack() pack a button Saturday, 7 November 2009
  • 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
  • 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
  • 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
  • more complex packing? Saturday, 7 November 2009
  • 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
  • grids Saturday, 7 November 2009
  • 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
  • ... or place Saturday, 7 November 2009
  • Widget values Saturday, 7 November 2009
  • widgets with a variable variable = tk.IntVar() value = variable.get() variable.set(value) Saturday, 7 November 2009
  • text widgets entry = tk.Entry() value = entry.get() entry.delete(0, tk.END) entry.insert(0, value) Saturday, 7 November 2009
  • 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
  • Styling Saturday, 7 November 2009
  • 2 methods: 1. direct 2. themed (py2.6+, py3k+) Saturday, 7 November 2009
  • tk.Label(root, text="Hello, world!", background='black', foreground='white', font='Courier').pack() Saturday, 7 November 2009
  • tk.Button(root, text="Hello, world!", background='black', foreground='white', font='Courier').pack() some limitations (sometimes depending on your theme) Saturday, 7 November 2009
  • Option 2: Themed Saturday, 7 November 2009
  • 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
  • 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
  • Implements button, checkbutton, entry, label, menubutton, radiobutton, scale, scrollbar, frame, labelframe, panedwindow Saturday, 7 November 2009
  • Added combobox, notebook, progressbar, separator, sizegrip Saturday, 7 November 2009
  • Not present canvas, listbox, menu, spinbox, text these aren’t really needed Saturday, 7 November 2009
  • “classes” and “styles” >>> from tkinter import ttk >>> l = ttk.Label('hello, world!') >>> l.winfo_class() 'TLabel' >>> l['style'] '' Saturday, 7 November 2009
  • layout example (button) Saturday, 7 November 2009
  • >>> 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
  • 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
  • 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
  • switching themes style = ttk.Style() current_theme = style.theme_use() new_theme = style.theme_create(...) style.theme_use(new_theme) Saturday, 7 November 2009
  • Events Saturday, 7 November 2009
  • 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
  • <modifier-type-detail> Saturday, 7 November 2009
  • 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
  • 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
  • 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
  • Canvas w = tk.Canvas(root, width=400, height=300) w.pack() Saturday, 7 November 2009
  • 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") specify corders, outline and fill colors Saturday, 7 November 2009
  • 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')) w.create_image((0, 0), image=image, anchor=tk.NW) Saturday, 7 November 2009
  • Tips Saturday, 7 November 2009
  • self.attributes('-topmost', True) Saturday, 7 November 2009