1.11M Members

Python GUI Programming

 
8
 

This 'sticky' thread is for working examples of Python GUI code. Note that wxPython examples have their own sticky.

Please use comments in your code to help the reader.

The example code should be usable as a template, so folks get a feel for the toolkit and can use those examples/templates as a basis for more complex programs.

We also welcome code that compares the various GUI toolkits.

Again, don't clutter up the sticky with questions. Ask question in the regular forum.

A brief history of GUI based Operating Systems migh be in order:
The first Graphical User Interface (GUI)) consisting of graphical elements such as windows, menus, radio buttons, check boxes and icons was developed by Xerox. Xerox created an integrated Operating System (OS) based in this. It allowed the use of a keyboard and a pointing device.

Apple in the early 1980s improved the GUI based OS, followed by Atari, Microsoft and IBM. Apple's Mac OS X uses a Unix-like OS as a base, and Microsoft's Windows sits on top of the original MS DOS. The first successful MS Windows version was Windows 3.0 (1990). The open source Linux OS (also a Unix-like OS) had people develop GUIs like KDE (1996, QT based) and GNOME (1997).

Here is a general discussion of some Python GUI toolkits: http://en.wikibooks.org/wiki/Python_Programming/GUI_Programming

For a typical installation of PyGame and PyQT for Windows see:
http://www.daniweb.com/software-development/python/threads/355545/1519470#post1519470

 
4
 

Here's an example of a basic window frame in pyQT.

You can get pyQT from here: http://www.riverbankcomputing.co.uk/software/pyqt/download

# Code Example: Display a window in PyQt4
# Python 2.6 with PyQt 4

import sys
from PyQt4 import QtGui

class MainFrame(QtGui.QMainWindow):

    def __init__(self):

        QtGui.QMainWindow.__init__(self)

        self.setWindowTitle("Window title") # title
        self.resize(1024, 768) # size
        self.setMinimumSize(800, 600) # minimum size
        self.move(0, 0) # position window frame at top left
        

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

    frame = MainFrame()
    frame.show()
    
    exit_code = app.exec_()
    sys.exit(exit_code)
 
0
 

This next pyQT example builds on the last and incorporates a simple box layout used with a button and a canvas. It also shows how to hook up a button event.

# Code Example: Display a window with a button, icon and canvas in PyQt4
# Python 2.6 with PyQt 4

# This example build on the last one by adding a button, changing the
# window icon, and adding a canvas where we can draw some shapes.

import sys
from PyQt4 import QtGui, QtCore

class MainFrame(QtGui.QMainWindow):

    def __init__(self):

        QtGui.QMainWindow.__init__(self)

        self.setWindowTitle("Window title") # title
        self.resize(1024, 768) # size
        self.setMinimumSize(800, 600) # minimum size
        self.move(0, 0) # position window frame at top left

        # Adding the icon:
        self.setWindowIcon(QtGui.QIcon("myicon.png"))

        # Set the central widget for the main window
        cwidget = QtGui.QWidget(self)

        # Set up a layout for the button and canvas:
        layout = QtGui.QVBoxLayout() #vertical box layout
        #layout = QtGui.QHBoxLayout() #horizontal box layout

        self.add_button(layout)
        self.add_canvas(layout)
        cwidget.setLayout(layout)
        self.setCentralWidget(cwidget)

        # Now set up the shapes that we draw on each button click
        # get the button back from the layout
        button = layout.itemAt(0).widget()
    
        # Create objects used for drawing
        sol_pen =  QtGui.QPen(QtGui.QColor("black"))
        
        dot_pen =  QtGui.QPen(QtGui.QColor("black"))
        dot_pen.setStyle(QtCore.Qt.DotLine)

        dash_pen = QtGui.QPen(QtGui.QColor("black"))
        dash_pen.setStyle(QtCore.Qt.DashLine)
        
        r_brush = QtGui.QBrush(QtGui.QColor("red"))
        g_brush = QtGui.QBrush(QtGui.QColor("green"))
        b_brush = QtGui.QBrush(QtGui.QColor("blue"))

        triangle = QtGui.QPolygonF()
        triangle.append(QtCore.QPointF(100, 50))
        triangle.append(QtCore.QPointF(200, 200))
        triangle.append(QtCore.QPointF(0, 200))


        self.scene_data = []
        # add data for drawing circle
        #self.scene.addEllipse(0, 0, 150, 150, sol_pen, r_brush) #x, y, w, h etc
        self.scene_data.append({'routine':self.scene.addEllipse,
                                'args':(0,0,150,150,sol_pen,r_brush),
                                'z': 0, #z-index
                                'next': "Draw Rectangle"})

        # add data for drawing square
        #self.scene.addRect(100, 100, 150, 150, dot_pen, g_brush) #x, y, w, h etc
        self.scene_data.append({'routine':self.scene.addRect,
                                'args':(100,100,150,150, dot_pen, g_brush),
                                'z':1,
                                'next': "Draw Triangle."})

        # add data for drawing triangle
        #self.scene.addPolygon(triangle, dash_pen, b_brush)
        self.scene_data.append({'routine':self.scene.addPolygon,
                                'z':2,
                                'args':(triangle, dash_pen, b_brush)})

        # Set up self.draw_next_item to fire when button is clicked.
        self.connect(button, QtCore.SIGNAL("clicked()"), self.draw_next_item)
        

    def add_button(self, layout):
        """Create a button and then add it to the layout."""
        button = QtGui.QPushButton("Draw Circle")
        layout.addWidget(button)

    def add_canvas(self, layout):
        """Create a canvas and then add it to the layout."""
        canvas = QtGui.QGraphicsView()
        layout.addWidget(canvas)

        # Now create a graphics scene to draw shapes to.
        # Now remember to keep a reference to GraphicsScene for as long as
        # you're using it, because unlike widgets, these are automatically
        # destroyed when they lose reference count
        self.scene = QtGui.QGraphicsScene()
        canvas.setScene(self.scene)

    def draw_next_item(self):
        # get the button. could've just saved as self.button, but I wanted to
        # show how it could be done this way
        button = self.centralWidget().layout().itemAt(0).widget()

        d = self.scene_data.pop(0) # get first item
        item = d['routine'](*d['args']) # just a little python magic
        item.setZValue(d['z'])

        if len(self.scene_data):
            # more stuff to draw, set button label
            button.setText(d['next'])
        else:
            # no more left, disable button
            button.setText("No more shapes!")
            button.setDisabled(True)
            
        

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

    frame = MainFrame()
    frame.show()
    
    exit_code = app.exec_()
    sys.exit(exit_code)
 
-1
 

I want write a program with GUI but I don't know which one is better gtk- wx-qt and etc. please guide me.please compair them.
thank.

 
6
 

Here is a comparison of some common Python GUI toolkits. These were created on my Ubuntu/Linux machine, because I could never get PyGTK to go on my Windows Vista machine. I followed the installation routine carefully, but there was always a dll missing, or an entry point wasn't found, or a version missmatch, so I gave up. GTK and PyGTK are more natural on Linux.

Let's take a look at typical PyGTK code:

#!/usr/bin/env python

# display an image using PyGTK + GTK

import pygtk
pygtk.require('2.0')
import gtk

class ShowImage(object):

    def __init__(self):
        # create the main window, and
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        # attach destroy signal to terminate the application
        window.connect("destroy", lambda w: gtk.main_quit())
        window.set_border_width(10)
        window.show()

        # a horizontal box to hold the buttons
        hbox = gtk.HBox()
        hbox.show()
        window.add(hbox)
        
        # pick an image file you have in the working directory, or give
        # the full path, can be a .jpg, .png, ,gif, .bmp image file
        # (filenames are case sensitive on Ubuntu/Linux)
        image_file = "LAKE2.gif"
        image = gtk.Image()
        image.set_from_file(image_file)
        image.show()
        # create a button to contain the image widget
        # auto adjusts to image size
        button = gtk.Button()
        button.add(image)
        button.show()
        hbox.pack_start(button)


ShowImage()
gtk.main()

The same test program using PyQT, PyQT installs easily on Windows and Linux machines:

#!/usr/bin/env python

# display an image using PyQT

import sys
from PyQt4 import QtGui

class MyImage(QtGui.QWidget):
    def __init__(self, parent, width, height):
        QtGui.QWidget.__init__(self, parent)

        # pick an image file you have in the working directory, or give
        # the full path, can be a .jpg, .png, ,gif, .bmp image file
        # (filenames are case sensitive on Ubuntu/Linux)
        image_file = "LAKE2.gif"
        image = QtGui.QPixmap(image_file)
        # show the image name in the title
        self.setWindowTitle(image_file)

        # use a label to display the image in
        label = QtGui.QLabel(self)
        label.setGeometry(10, 10, width, height)
        label.setPixmap(image)


app = QtGui.QApplication(sys.argv)
# assume image is about 400x300 pixels in size
width = 400
height = 300
w = MyImage(None, width, height)
# setGeometry(x, y, width, height) ULC coordinates x.y
w.setGeometry(100, 100, width+20, height+20)
w.show()
app.exec_()

Here is a simplified wxPython program (could have used a class):

#!/usr/bin/env python

# display an image using wxPython

import wx

app = wx.App(0)
frame = wx.Frame(None, wx.ID_ANY, "Show an image file")

# pick an image file you have in the working directory, or give
# the full path, can be a .jpg, .png, ,gif, .bmp image file
# (filenames are case sensitive on Ubuntu/Linux)
image_file = 'LAKE2.gif'
image = wx.Bitmap(image_file)
image_width = image.GetWidth()
image_height = image.GetHeight()
# set frame size to image size
frame.SetClientSize((image_width, image_height))
# show the image as static bitmap
wx.StaticBitmap(frame, wx.ID_ANY, image)
# show the image name in the title
frame.SetTitle(image_file)

frame.Show()
app.MainLoop()

Last not least Tkinter, which usually ships with Python:

#!/usr/bin/env python

# display an image using Tkinter

import Tkinter as tk

root = tk.Tk()

# pick an image file you have in your working directory
# or use full path, Tkinter only reads .gif image files
# (filenames are case sensitive on Ubuntu/Linux)
image_file = "LAKE2.gif"
photo = tk.PhotoImage(file=image_file)
root.title(image_file)

# put the image on a typical widget
label = tk.Label(root,image=photo)
label.pack(padx=5, pady=5)

root.mainloop()

Editor's note:
The first line in snee's code
#!/usr/bin/env python
tells Linux where it can find the Python interpreter
it is simply ignored on Windows machines.

Attachments LAKE2.gif 46.13KB
 
1
 

Thanks for the sample code and the nice picture. I thought I should add pyglet, which is an audio-visual module using GL and FFmpeg available for Windows and Unix systems ...

# show an image using pyglet
# download pyglet from: http://www.pyglet.org/download.html
# (the event handler is attached via a function decorator)

import pyglet

# pick an image file you have in the working directory, or give
# the full path, can be a .jpg, .png, ,gif, .bmp image file
# (I understand filenames are case sensitive on Linux)
image_file = 'LAKE2.gif'
img = pyglet.image.load(image_file)

# create and size the window to the picture size + 
# a small frame around it
w = img.width + 10
h = img.height + 10
win = pyglet.window.Window(width=w, height=h)

# give the window a title
win.set_caption(image_file)

@win.event
def on_draw():
    win.clear()
    # draw image in window at coordinates x=5, y=5
    # note that coordinates start at lower left corner 
    img.blit(5, 5)

pyglet.app.run()

Pyglet is not a full GUI toolkit, but has its strength in audio and video presentations.

 
1
 

PyQT was no problem on Windows XP. I downloaded and installed:
http://www.riverbankcomputing.com/static/Downloads/PyQt4/PyQt-Py2.5-gpl-4.4.3-1.exe

The cumbersome split between QtCore and QtGui is made simpler if you use the import statements show below ...

# a simple window using PyQT 
# with 2 buttons and a label

import sys
# might be easier to use this import option
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyForm(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 150, 320, 100)
        self.setWindowTitle("A simple window")

        # use a grid layout for the widgets
        grid = QGridLayout()

        btn_hello = QPushButton("Hello")
        # bind the button click to a function reference
        self.connect(btn_hello, SIGNAL("clicked()"), self.on_click)
        
        btn_quit = QPushButton("Quit")
        self.connect(btn_quit, SIGNAL("clicked()"), app.quit)
        
        self.label = QLabel("-------------")

        # addWidget(widget, row, column, rowSpan=1, columnSpan=1)
        grid.addWidget(btn_hello, 0, 0)
        # this will span the label over 3 columns
        grid.addWidget(self.label, 1, 0, 1, 3)
        grid.addWidget(btn_quit, 2, 0)

        self.setLayout(grid)
    
    def on_click(self):
        self.label.setText("You clicked the Hello button!")


app =  QApplication(sys.argv)
form = MyForm()
form.show()
app.exec_()

This little PyQT template can be used for quite a few basic programs. Now, if I could introduce some color! Hey, I am a slow learner!

 
1
 

One of my standard test programs for any GUI toolkit, creating, loading a listbox and selecting an item. Here is the PyQT code ...

# a simple window using PyQT 
# with a button and a listbox to load and select

import sys
# might be easier to use this import option
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyForm(QWidget):
    def __init__(self, name_list):
        QWidget.__init__(self)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 150, 300, 220)
        self.setWindowTitle("Load the listbox first")
        
        # make name_list available for methods
        self.name_list = name_list

        # use a grid layout for the widgets
        grid = QGridLayout()

        btn_load = QPushButton("Load List")
        # bind the button click to a function reference
        self.connect(btn_load, SIGNAL("clicked()"), self.on_click)
        
        self.listbox = QListWidget()
        self.connect(self.listbox, SIGNAL("itemSelectionChanged()"), self.on_select)
        
        # addWidget(widget, row, column, rowSpan, columnSpan)
        grid.addWidget(btn_load, 0, 0, 1, 1)
        # listbox spans over 5 rows and 2 columns
        grid.addWidget(self.listbox, 1, 0, 5, 2)
        self.setLayout(grid)
    
    def on_click(self):
        """the load button has been clicked, load the listbox"""
        self.listbox.addItems(self.name_list)
    
    def on_select(self):
        """an item in the listbox has been clicked/selected"""
        selected_name =  self.listbox.selectedItems()[0].text()
        self.setWindowTitle(selected_name)
        

name_list = [
"Erich Meitinger",
"Udo Baus",
"Jens Klein",
"Bjorn Bork",
"Heidrun Lovelace",
"Klaus Abraham",
"Ulla Jorgens",
"Volger Jenkings",
"Helmut Schmidt",
"Freja Larse",
"Larry Orkan",
"Andreas Mauser",
"Harry Heimlich"
]

app =  QApplication(sys.argv)
form = MyForm(name_list)
form.show()
app.exec_()

I do miss the colors. Here is the corresponding wxPython code with some colors added ...

# a simple window using wxPython 
# with a button and a listbox to load and select

import wx

class MyFrame(wx.Frame):
    def __init__(self, name_list):
        wx.Frame.__init__(self, parent=None)
        self.SetBackgroundColour("green")  # ah, color!
        self.SetTitle('Load the listbox first')
        
        # make name_list available for methods
        self.name_list = name_list        

        # use a grid layout for the widgets
        grid = wx.GridBagSizer()
        
        self.btn_load = wx.Button(self, -1, "Load List")
        # bind the button click to a function reference
        self.btn_load.Bind(wx.EVT_BUTTON, self.on_click)
        
        self.listbox = wx.ListBox(self)
        self.listbox.SetBackgroundColour("yellow")
        self.listbox.Bind(wx.EVT_LISTBOX, self.on_select)
        
        # Add(widget, pos=(row, column), span=(rowspan, columnspan))
        grid.Add(self.btn_load, pos=(0, 0), flag=wx.ALL, border=5)
        # add a 180 pixel wide spacer
        grid.Add((180, 0), pos=(0, 1))
        grid.Add(self.listbox, pos=(1,0), span=(10,2),
            flag=wx.ALL|wx.EXPAND, border=5)
        self.SetSizerAndFit(grid)
        
    def on_click(self, event):
        """the load button has been clicked, load the listbox"""
        self.listbox.Set(self.name_list)        
        
    def on_select(self, event):
        """an item in the listbox has been clicked/selected"""
        selected_name = self.listbox.GetStringSelection()
        self.SetTitle(selected_name)        


name_list = [
"Erich Meitinger",
"Udo Baus",
"Jens Klein",
"Bjorn Bork",
"Heidrun Lovelace",
"Klaus Abraham",
"Ulla Jorgens",
"Volger Jenkings",
"Helmut Schmidt",
"Freja Larse",
"Larry Orkan",
"Andreas Mauser",
"Harry Heimlich"
]

app = wx.App(0)
MyFrame(name_list).Show()
app.MainLoop()

The wx.GridBagSizer() seems to be more complex.

 
1
 

I got PyQT4 istalled and working on my Vista computer. Here is an example of my first program:

# display a bunch of random circles using PyQT4

import random
import sys
# pray for minimal namespace conflicts
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class DrawPoints(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(200, 200, 400, 400)
        self.setWindowTitle('Draw random Circles')

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        # pen sets the edge color of the circles
        painter.setPen(Qt.black)
        w = self.size().width()
        h = self.size().height()
        # draw 150 circles of random sizes, locations and colors
        for i in range(150):
            # color uses red, green, blue values (0 to 255)
            r = random.randint(0, 255)
            g = random.randint(0, 255)
            b = random.randint(0, 255)
            # brush sets the fill color of the circles
            painter.setBrush(QBrush(QColor(r, g, b)))
            # get center coordinates x,y of the circle
            x = random.randint(1, w-1)
            y = random.randint(1, h-1)
            # get the radius of the circle
            radius = random.randint(5, 80)
            # to draw circles match the radius
            painter.drawEllipse(QPoint(x, y), radius, radius)

        painter.end()


app = QApplication(sys.argv)
dp = DrawPoints()
dp.show()
app.exec_()
 
2
 

An example how to use the QPainter to create a wallpaper background:

# a simple window using PyQT 
# using a canvas with a texture/wallpaper background

import sys
# pray for minimal namespace conflicts
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyForm(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 150, 350, 300)
        self.setWindowTitle("Creating a Canvas Wallpaper")
        
    def paintEvent(self, event):
        """create a painting canvas"""
        painter = QPainter()
        painter.begin(self)
        painter.setRenderHint(QPainter.Antialiasing)
        # use the brush for a texture/wallpaper background
        # supply a background image file you have (add needed path)
        painter.setBrush(QBrush(QPixmap("BG_GoldSwirl.gif")))
        painter.drawRect(event.rect())
        
        # optionally write something in the wallpaper
        # (check the fonts available on your computer)
        painter.setFont(QFont('Freestyle Script', 48))
        painter.drawText(50, 160, "Hello World!")
        
        painter.end()


app =  QApplication(sys.argv)
form = MyForm()
form.show()
app.exec_()
Attachments BG_GoldSwirl.gif 4.7KB
 
1
 

A small Python/PyQT4 utility program to find out what kind of fonts your computer has:

# bring up a font dialog with PyQT4
# show the selected font using a sample text

import sys
# hopefully no namespace conflicts
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class FontDialog(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setGeometry(10, 100, 250, 110)
        self.setWindowTitle('QFontDialog')

        hbox = QVBoxLayout()

        button = QPushButton('Font Dialog')
        self.connect(button, SIGNAL('clicked()'), self.showDialog)
        
        # the label autosizes to the text
        text = "The quick brown fox jumps over the lazy dog"
        self.label = QLabel(text)
        self.label.move(130, 20)
        
        self.edit = QTextEdit()

        hbox.addWidget(button)
        hbox.addWidget(self.label)
        hbox.addWidget(self.edit)
        self.setLayout(hbox)

    def showDialog(self):
        font, ok = QFontDialog.getFont()
        if ok:
            # display the label's text in the selected font
            self.label.setFont(font)
        # display the font name in the edit box for copying
        self.edit.append(QFontInfo(font).family())


app = QApplication(sys.argv)
fd = FontDialog()
fd.show()
app.exec_()

Save the code as pqt_FontLister.pyw

 
2
 

Tkinter has the reputation to look kind of homely on Windows computers. Actually, on my Ubuntu/Linux computer it doesn't look bad at all. Here is a typical listbox example using the Tkinter GUI toolkit that comes with just about every Python installation. Yes, if you use the new Python3, it comes with Tkinter too. Just remember that Tkinter is now a package and you have to import tkinter rather than Tkinter:

#!/usr/bin/env python

# create a scrollable listbox using Tkinter
# load the listbox with tasty cheese data
# and select your favorite cheese with the mouse
# with Python3 use   import tkinter as tk

import Tkinter as tk

def get_list(event):
    """
    function to read the listbox selection
    and put the result in a label widget
    """
    # get selected line index
    index = listbox.curselection()[0]
    # get the line's text
    seltext = listbox.get(index)
    # put the selected text in the label
    label['text'] = seltext

root = tk.Tk()
root.title("Cheeses")
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("180x300+30+50")

# create a label (width in characters)
s = "Click on a cheese"
label = tk.Label(root, text= s, width=15)
label.grid(row=0, column=0)

# create a listbox (height in characters/lines)
# give it a nice yellow background (bg) color
listbox = tk.Listbox(root, height=15, bg='yellow')
listbox.grid(row=1, column=0)

# the Tkinter listbox does not automatically scroll, you need
# to create a vertical scrollbar to the right of the listbox
yscroll = tk.Scrollbar(command=listbox.yview, orient=tk.VERTICAL)
yscroll.grid(row=1, column=1, sticky='n'+'s')
listbox.configure(yscrollcommand=yscroll.set)

cheese_list = [
'Feta', 'Limburger', 'Camembert', 'Roquefort', 'Edam',
'Romadur', 'Liptauer', 'Dubliner', 'Gouda', 'Gorgonzola',
'Jarlsberg', 'Golka', 'Garrotxa', 'Swiss', 'Quesillo',
'Emmentaler', 'Appenzeller', 'Raclette', 'Asiago', 'Zuvi',
'Ricotta', 'Mozzarella', 'Munster', 'Parmesan']

# load the listbox
for item in cheese_list:
    listbox.insert('end', item)
    
# use left mouse click on a list item to display selection
listbox.bind('<ButtonRelease-1>', get_list)

root.mainloop()

Again, the first line in my code is for Linux to find the Python interpreter. I really like the Firefox web browser and its built in automatic spell checker.

 
1
 

The nice thing about using a GUI toolkit is that you have a large number of widgets available to supply the data input. Here is a Tkinter Temperature Converter example using radio buttons to select the type of conversion and a scale (slider) to set the temperature. Notice that the result is updated as changes to the inputs are made:

#!/usr/bin/env python

# use Tkinter's scale/slider and radiobutton widgets
# for input data to convert temperature values

import Tkinter as tk

def on_click():
    """radio button clicked, change results too"""
    on_move()

def on_move(value=0):
    """use slider position to calculate and display result"""
    # radio button1 is set convert C to F
    if rb_v.get() == id_rb1:
        c = scale.get()
        f = c*9/5.0 + 32
        result = "%s celsius --> %s Fahrenheit" % (c, f)
    # radio button2 is set convert F to C
    else:
        f = scale.get()
        c = (f - 32)*5/9.0
        result = "%s Fahrenheit --> %s Celsius" % (f, c)
    label['text'] = result

root = tk.Tk()
root.title('Temperature Converter')
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("620x110+30+50")

# used by the radio button_id
rb_v  = tk.IntVar()

# the radio buttons allow selection of Celsius or Fahrenheit
id_rb1 = 101
rb1 = tk.Radiobutton(root, text='Celsius to Fahrenheit',
    value=id_rb1, variable=rb_v, command=on_click)
id_rb2 = 102
rb2 = tk.Radiobutton(root, text='Fahrenheit to Celsius',
    value=id_rb2, variable=rb_v, command=on_click)
# start with rb1 selected
rb_v.set(id_rb1)

# the scale (or slider) selects the temperature
# from -50 to +300
# (from_ is used because from is a reserved word in Python)
scale = tk.Scale(root, label="select temperature",
    from_=-50, to=300, tickinterval=0, resolution=1, length=600,
    showvalue='yes', orient='horizontal', command=on_move)
# set the starting position of the scale
scale.set(50)

# show the result in a label
label = tk.Label(root, text='---', bg='yellow')

# place the widgets in a grid
rb1.grid(row=0, column=0)
rb2.grid(row=0, column=1)
scale.grid(row=1, columnspan=2)
label.grid(row=2, columnspan=2, pady=5)

root.mainloop()

Once more, the first line in my code is for Linux to find the Python interpreter. If you have Windows, Windows will ignore this line or you can. Also, if you use the newer Python3 version, use import tkinter as tk.

 
1
 

Tkinter has some nice pop-up dialogs that can also be used for regular console programs. Here is an example to use if you want to get a filename from a pop-up window. It works with Python2x or Python3x, just read the comments:

# use Tkinter's file dialog window to get
# a file name with full path, you can also use
# this to get filenames for a console program
# askopenfilename() gives one selected filename

# with Python25 use ...
#import Tkinter as tk
#from tkFileDialog import askopenfilename

# with Python30 use ...
import tkinter as tk
from tkinter.filedialog import askopenfilename

root = tk.Tk()
# show askopenfilename dialog without the Tkinter window
root.withdraw()

# default is all file types
file_name = askopenfilename()

print(file_name)
 
1
 

This code sample shows you how to select and display multiple lines from a Tkinter Listbox ...

# a simple Tkinter Listbox example
# press the shift or ctrl key to select multiple items
# source: snee

import Tkinter as tk

def get_list():
    """
    function to read the listbox selection(s)
    (mutliple lines can be selected)
    and put the result(s) in a label
    """
    # tuple of line index(es)
    sel = listbox.curselection()
    # get the text, might be multi-line
    seltext = '\n'.join([listbox.get(x) for x in sel])
    label_text.set(seltext)

root = tk.Tk()
# used for label text
label_text = tk.StringVar(root)

# extended mode allows CTRL/SHIFT mouse selections
listbox = tk.Listbox(root, selectmode=tk.EXTENDED)
listbox.pack()

# click the button to show the selection(s)
button = tk.Button(root, text="Get Selection(s)", command=get_list)
button.pack()

# used to display selection(s)
label = tk.Label(root, textvariable=label_text)
label.pack()

# load some datalines into the listbox
items = ["one", "two", "three", "four", "five", "six"]
for item in items:
    listbox.insert(tk.END, item)

# highlight/preselect line 3 of listbox (starts with zero)
# lb.selection_set(first, last=None) can preselect more than 1 line
listbox.selection_set(3)

root.mainloop()

Left mouse click with and without pressing the SHIFT or CTRL key to see how the multiple selection works.

 
0
 

I modernized an old snippet of mine ...

# Tkinter GUI program with 2 data entry, labels and a button
# a general template to input 2 numbers and calculate something
# here the resistance of 2 resistors in parallel
# for Python3 use: import tkinter as tk
# vegaseat

import Tkinter as tk

def calculate():
    """ calculate the resistance of 2 resistors in parallel """
    try:
        r1 = float(enter1.get())
        r2 = float(enter2.get())
        if r1 + r2 > 0:
            rp = (r1 * r2) / (r1 + r2)
            result = "Result = %0.2f" % rp
            label3.config(text=result)
        else:
            label3.config(text='Division by zero error')
    except ValueError:
        label3.config(text='Need numeric values')

def setfocus2(event):
    enter2.focus_set()

        
# create root window
root = tk.Tk()
root.title("Parallel resistance ...")

# create all the components
label1 = tk.Label(root, text=' Enter value of resistor1:')
enter1 = tk.Entry(root, bg='yellow')
label2 = tk.Label(root, text=' Enter value of resistor2:')
enter2 = tk.Entry(root, bg='yellow')
btn1 = tk.Button(root, text=' Calculate ', command=calculate)
label3 = tk.Label(root, text='')

# use a grid for component layout
label1.grid(row=0, column=0)
enter1.grid(row=0, column=1, padx=5, pady=5)
label2.grid(row=1, column=0)
enter2.grid(row=1, column=1)
btn1.grid(row=2, column=0, pady=5)
label3.grid(row=2, column=1)

# start cursor in enter1
enter1.focus_set()

# return key in enter1 sets focus to enter2
enter1.bind("<Return>", func=setfocus2)

# start event loop and program
root.mainloop()
Attachments Tk_ParResistor.jpg 10.43KB
 
0
 

Those little animated gif image files are fun. Here is an example of using PyQt's QMovie() widget to play them ...

# use PyQt's QMovie() widget to play an animated gif
# tested with PyQt4.4 and Python 2.5
# also tetsed with PyQt4.5 and Python 3.0
# vegaseat

import sys 
# expect minimal namespace conflicts
from PyQt4.QtCore import *
from PyQt4.QtGui import * 

class MoviePlayer(QWidget): 
    def __init__(self, parent=None): 
        QWidget.__init__(self, parent) 
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(200, 200, 400, 300)
        self.setWindowTitle("QMovie to show animated gif")

        # set up the movie screen on a label
        self.movie_screen = QLabel()
        # expand and center the label 
        self.movie_screen.setSizePolicy(QSizePolicy.Expanding, 
            QSizePolicy.Expanding)        
        self.movie_screen.setAlignment(Qt.AlignCenter) 

        main_layout = QVBoxLayout() 
        main_layout.addWidget(self.movie_screen) 
        self.setLayout(main_layout) 

        # use an animated gif file you have in the working folder
        # or give the full file path                
        movie = QMovie("AG_Dog.gif", QByteArray(), self) 
        movie.setCacheMode(QMovie.CacheAll) 
        movie.setSpeed(100) 
        self.movie_screen.setMovie(movie) 
        movie.start() 
        

app = QApplication(sys.argv) 
player = MoviePlayer() 
player.show() 
sys.exit(app.exec_())
Attachments AG_Dog.gif 6.58KB
 
1
 

Draw a simple bar chart with PyQT:

# use PyQT to draw a simple vertical bar chart
# tested with PyQT4.5 and Python3.0
# ene

import sys
# simplified import, hopefully no namespace conflicts
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class BarChart(QWidget):
    def __init__(self, data, parent=None):
        QWidget.__init__(self, parent)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 300, 360, 320)
        self.setWindowTitle('A Simple Bar Chart')
        self.data = data

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        
        # set color and width of line drawing pen
        painter.setPen(QPen(Qt.black, 2))
        
        # drawLine(x1, y1, x2, y2) from point (x1,y1) to (x2,y2)
        # draw the baseline
        painter.drawLine(20, 280, 340, 280)        

        # set up color and width of the bars
        width = 20
        painter.setPen(QPen(Qt.red, width))
        delta = width + 5
        x = 30
        for y in self.data:
            # correct for width
            y1 = 280 - width/2
            y2 = y1 - y + width/2
            # draw each bar
            painter.drawLine(x, y1, x, y2)
            # add values to the top of each bar
            s = str(y)
            painter.drawText(x-8, y2-15, s)
            x += delta        

        painter.end()


# data to be graphed
data = [30, 45, 80, 150, 220, 180, 110, 75, 50, 35, 20, 10]
app = QApplication(sys.argv)
bc = BarChart(data)
bc.show()
app.exec_()
 
1
 

PyQT has an interesting widget called a dial (circular slider). Here is a simple applcation:

# use a PyQT QDial knob to select a temperature
# show Celsius and corresponding Fahrenheit values
# as the knob is rotated
# tested with PyQT4.5 and Python3.0
# ene

import sys
# has minimal namespace conflicts
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyFrame(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(150, 150, 328, 440)
        self.setWindowTitle('Convert Temperature')
        
        self.dial = QDial(self)
        self.dial.setGeometry(QRect(10, 20, 311, 351))
        self.dial.setMinimum(-50)
        self.dial.setMaximum(310)
        self.dial.setPageStep(10)
        # initial dial pointer position
        dial_pos = 50
        self.dial.setSliderPosition(dial_pos)
        self.dial.setWrapping(True)
        self.dial.setNotchTarget(3.6)
        self.dial.setNotchesVisible(True)

        self.label_c = QLabel(self)
        self.label_c.setGeometry(QRect(30, 390, 121, 31))
        font = QFont()
        font.setPointSize(11)
        self.label_c.setFont(font)
        self.label_c.setAlignment(Qt.AlignCenter)

        self.label_f = QLabel(self)
        self.label_f.setGeometry(QRect(170, 390, 131, 31))
        font = QFont()
        font.setPointSize(11)
        self.label_f.setFont(font)
        self.label_f.setAlignment(Qt.AlignCenter)
        
        # start up
        self.show_temps()
        # update show_temps()
        self.connect(self.dial, SIGNAL("sliderMoved(int)"),
            self.show_temps)

    def show_temps(self):
        """
        get the C value from the dial label
        calculate F value and show
        """ 
        c = float(self.dial.value())
        s_c = "%0.1f Celsius" % c
        self.label_c.setText(s_c)
        f = c*9/5.0 + 32
        s_f = "%0.1f Fahrenheit" % f
        self.label_f.setText(s_f)
        

app = QApplication(sys.argv)
frame = MyFrame()
frame.show()
sys.exit(app.exec_())

Sorry, I am having real problems with my HP notebook, the keyboard is of very poor quality and misses keystrokes a lot!

 
1
 

An example how to use an image as a background. In order to make added text transparent, use the Tkinter canvas:

# use a Tkinter canvas for a background image
# add transparent text and other widgets
# with Python3 use   import tkinter as tk
# snee

import Tkinter as tk
 
root = tk.Tk()
root.title('background image')

# pick a .gif image file you have in the working directory
bg_image = tk.PhotoImage(file="Flowers.gif")
w = bg_image.width()
h = bg_image.height()
 
# size the window so the image will fill it
root.geometry("%dx%d+0+0" % (w, h))

cv = tk.Canvas(width=w, height=h)
cv.pack(side='top', fill='both', expand='yes')
cv.create_image(0, 0, image=bg_image, anchor='nw')
 
# add canvas text at coordinates x=15, y=30
# anchor='nw' implies upper left corner coordinates
cv.create_text(15, 30, text="Python Greetings", fill="red", anchor='nw')

# now some button widgets
btn1 = tk.Button(cv, text="Click")
btn1.pack(side='left', padx=10, pady=5, anchor='sw')

btn2 = tk.Button(cv, text="Quit")
btn2.pack(side='left', padx=10, pady=5, anchor='sw')

root.mainloop()
Isn't it about time forums rewarded their contributors?

Earn rewards points for helping others. Gain kudos. Cash out. Get better answers yourself.

It's as simple as contributing editorial or replying to discussions labeled or OP Kudos

You
This is an OP Kudos discussion and contributors may be rewarded
Post:
Start New Discussion
View similar articles that have also been tagged: