Pygame code to show how to make a grid and display the grid position as the mouse pointer moves over it.
The start of a battleship game perhaps?

'

'''pg_mouse_grid_position1.py
draw a grid with PyGame and show grid_position of
the grid the mouse is pointing to

exploring the Python module pygame
pygame free from: http://www.pygame.org/
or: http://www.lfd.uci.edu/~gohlke/pythonlibs/
pygame is available for Python27 or Python32
'''

import pygame as pg
import os

# this will center the pygame window on the display screen
os.environ['SDL_VIDEO_CENTERED'] = '1'

pg.init()

class Grid:
    def __init__(self,size):
        self.size = size
        self.font = pg.font.Font(None, 24)
        self.pos = [0,0]
        self.rend = self.font.render("{0}, {1}".format(*self.pos),
                                     1,(0,100,0))

    def draw(self, surface):
        w, h = self.size
        for ww in range(w, 800, w):
            pg.draw.line(surface,(120,120,120), (ww,0), (ww,600))
        for hh in range(h, 600, h):
            pg.draw.line(surface,(120,120,120), (0,hh), (800,hh))

        mouse = pg.mouse.get_pos()
        # find mouse position
        mouse = map(int,(mouse[0]/self.size[0],
                         mouse[1]/self.size[1]))
        if mouse != self.pos:
            self.pos = mouse
            self.rend = self.font.render("{0}, {1}".format(*self.pos),
                                         1,(0,200,0))
        surface.blit(self.rend, (10,10))

def main():
    screen = pg.display.set_mode((800,600))
    title = 'move mouse pointer over grid to show the grid position'
    pg.display.set_caption(title)
    # needed for frame rate
    clock = pg.time.Clock()
    grid = Grid((50,50))
    Run = True
    while Run:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                Run = False
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    Run = False
        screen.fill((0,0,0))
        grid.draw(screen)
        pg.display.flip()
        # set frame rate
        clock.tick(30)
    pg.quit()

if __name__ == "__main__":
    main()

This PySide code allows you to play a specified frequency sound/tone:

'''ps_Multimedia_play_sound1.py
explore PySide QtMultimedia to play a sepecific sound

modified PyQT code from:
http://www.diotavelli.net/PyQtWiki/Playing%20a%20sound%20with%20QtMultimedia
tested with pyside474 and Python27/Python32
'''

from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtMultimedia import *

from math import pi, sin
import struct

class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.setWindowTitle("play a sound")

        format = QAudioFormat()
        format.setChannels(1)
        format.setFrequency(22050)
        format.setSampleSize(16)
        format.setCodec("audio/pcm")
        format.setByteOrder(QAudioFormat.LittleEndian)
        format.setSampleType(QAudioFormat.SignedInt)
        self.output = QAudioOutput(format, self)

        self.frequency = 440
        self.volume = 3000
        self.buffer = QBuffer()
        self.data = QByteArray()

        self.deviceLineEdit = QLineEdit()
        self.deviceLineEdit.setReadOnly(True)
        device = QAudioDeviceInfo.defaultOutputDevice().deviceName()
        self.deviceLineEdit.setText(device)

        self.pitchSlider = QSlider(Qt.Horizontal)
        self.pitchSlider.setMaximum(100)
        self.volumeSlider = QSlider(Qt.Horizontal)
        self.volumeSlider.setMaximum(32767)
        self.volumeSlider.setPageStep(1024)
        self.volumeSlider.setValue(self.volume)

        #self.playButton = QPushButton(self.tr("&Play"))
        self.playButton = QPushButton("&Play")

        self.pitchSlider.valueChanged.connect(self.changeFrequency)
        self.volumeSlider.valueChanged.connect(self.changeVolume)
        self.playButton.clicked.connect(self.play)

        formLayout = QFormLayout()
        formLayout.addRow(self.tr("Device:"), self.deviceLineEdit)
        formLayout.addRow(self.tr("P&itch:"), self.pitchSlider)
        formLayout.addRow(self.tr("&Volume:"), self.volumeSlider)

        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(self.playButton)
        buttonLayout.addStretch()

        horizontalLayout = QHBoxLayout(self)
        horizontalLayout.addLayout(formLayout)
        horizontalLayout.addLayout(buttonLayout)

    def changeFrequency(self, value):
        self.frequency = 440 + (value * 2)

    def play(self):
        if self.output.state() == QAudio.ActiveState:
            self.output.stop()
        if self.buffer.isOpen():
            self.buffer.close()
        self.createData()
        self.buffer.setData(self.data)
        self.buffer.open(QIODevice.ReadOnly)
        self.buffer.seek(0)
        self.output.start(self.buffer)

    def changeVolume(self, value):
        self.volume = value

    def createData(self):
        """
        create 2 seconds of data with 22050 samples per second,
        each sample being 16 bits (2 bytes)
        """
        self.data.clear()
        for k in range(2 * 22050):
            t = k / 22050.0
            value = int(self.volume * sin(2 * pi * self.frequency * t))
            self.data.append(struct.pack("<h", value))


# test the module
if __name__ == "__main__":
    app = QApplication([])
    window = Window()
    window.show()
    app.exec_()

PyTony remark:

Nice, only to correct after call comment, that is not recursive call, as after setting the timed call the function exits and function is not running until the timer fires the scheduled call.

So, I would call it scheduled call.

Can you show proof that the function actually exits?

It is logical, but of course you can allways add print statements, here recursive factorial function with same kind of prints for comparison

# display GMT time with Tkinter

import time
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def update_gmt():
    t= time.strftime("%H:%M:%S", time.gmtime())
    print('entered update_gmt time %s' % t)
    gmt_string.set(t)
    #  every second new function call
    app.after(1000, update_gmt)
    print('exiting update_gmt time %s' % t)


def factorial(n):
    print('Entering factorial(%i)' % n)    
    result = n * factorial(n-1) if n > 0 else 1
    print('Exiting factorial(%i) = %i' % (n, result))
    return result

def main():
    myfont = ('times', 48, 'bold')
    gmt_label = tk.Label(app, textvariable=gmt_string,
        font=myfont, fg='red', bg='yellow')
    gmt_label.grid()
    update_gmt()


print('Example of recursive call sequence, factorial(10)')
factorial(10)
print('Starting GMT clock')
app = tk.Tk()
app.title("GMT")

gmt_string = tk.StringVar()

main()

app.mainloop()

A little bit about PYQT/PySide frames with color:

# explore multiple QFrame() in a QGridLayout()

from PySide.QtCore import *
from PySide.QtGui import *

class FrameTester(QWidget):
    def __init__(self, title, width, height, parent=None):
        # create the window (this will be instance self)
        QWidget.__init__(self, parent)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 150, width, height)
        self.setWindowTitle(title)
        self.make_frames()

    def make_frames(self):
        # ps/pyqt takes colors in '#RRGGBB' format
        red = '#FF0000'
        green = '#00FF00'
        blue = '#0000FF'

        frame1 = QFrame(self)
        frame1.setLineWidth(3)
        frame1.setFrameStyle(QFrame.Box|QFrame.Sunken)
        # set frame1 color with this style string
        sf = "QWidget { background-color: %s }" % red
        frame1.setStyleSheet(sf)

        frame2 = QFrame(self)
        frame2.setLineWidth(3)
        frame2.setFrameStyle(QFrame.Box|QFrame.Sunken)
        sf = "QWidget { background-color: %s }" % green
        frame2.setStyleSheet(sf)

        frame3 = QFrame(self)
        frame3.setLineWidth(3)
        frame3.setFrameStyle(QFrame.Box|QFrame.Sunken)
        sf = "QWidget { background-color: %s }" % blue
        frame3.setStyleSheet(sf)

        grid = QGridLayout()
        grid.setSpacing(10)
        # addWidget(QWidget, row, column, rowSpan, columnSpan)
        # span 2 rows and 1 column each
        grid.addWidget(frame1, 1, 1, 2, 1)
        grid.addWidget(frame2, 1, 2, 2, 1)
        # span 1 row and 2 columns
        # note that you occupy row 3 now
        # since a rowSpan of 2 was used before that
        grid.addWidget(frame3, 3, 1, 1, 2)

        self.setLayout(grid)


# create the Application
app = QApplication([])

title = "3 colorful frames in a grid layout"
width = 600
height = 400
tester = FrameTester(title, width, height)
tester.show()

# run the main event loop
app.exec_()

Now back to some PyGame exploration ...

'''PG_rectangle1.py
exploring Python game module pygame
free from: http://www.pygame.org

draw a number of rectangles on a white background
use pygame class Rect and its methods inflate() and move()
'''

import pygame as pg

# pygame uses (r, g, b) color tuples
white = (255, 255, 255)
blue = (0, 0, 255)
red = (255, 0, 0)
green = (0, 255, 0)

# create a 300 x 300 pixel display window
win = pg.display.set_mode((300, 300))
# optional title bar caption
pg.display.set_caption('Pygame Rectangle Drawings')
# default background is black, so make it white
win.fill(white)


# x1 and y1 are the upper left corner coordinates
# w and h are the width and height of rect
x1 = y1 = 50
w = h = 200
# set up rect via pg class Rect(left, top, width, height)
# to get utility method access
rect = pg.Rect(x1, y1, w, h)
print(rect, type(rect))  # test
# width of 0 (default) fills the rectangle
# otherwise it is thickness of outline
width = 2
# draw a blue rectangle ...
# draw.rect(Surface, color, rect, width)
pg.draw.rect(win, blue, rect, width)

# shrink rect and draw again
rect2 = rect.inflate(-20, -20)
pg.draw.rect(win, red, rect2, width)
print(rect2)  # test

# expand rect and draw again
rect3 = rect.inflate(20, 20)
pg.draw.rect(win, green, rect3, width)
print(rect3)  # test

# shrink rect, move it and draw again
rect4 = rect.inflate(-70, -70)
rect5 = rect4.move(60, 60)
print(rect4, rect5)  # test
pg.draw.rect(win, red, rect5, width)

# update the display window to show the drawings
pg.display.flip()

# event loop and exit conditions
# (the window's titlebar x click to exit)
while True:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            raise SystemExit

You can animate a drawn object in PyGame this way ...

'''PG_rectangle_animate1.py
exploring Python game module pygame
free from: http://www.pygame.org

draw a rectangle on a white background and animate it
by erasing and moving the object
uses pygame class Rect and its method move()
'''

import pygame as pg

# pygame uses (r, g, b) color tuples
white = (255, 255, 255)
blue = (0, 0, 255)
red = (255, 0, 0)
green = (0, 255, 0)

# create a 400 x 300 pixel display window
win = pg.display.set_mode((400, 300))
# optional title bar caption
pg.display.set_caption('Pygame Rectangle Animation')
# default background is black, so make it white
win.fill(white)


# x1 and y1 are the upper left corner coordinates
# w and h are the width and height of rect
x1 = y1 = 15
w = 30
h = 20
# set up rect via pg class Rect(left, top, width, height)
rect = pg.Rect(x1, y1, w, h)
# width of 0 (default) fills the rectangle
# otherwise it is thickness of outline
width = 0
# draw a blue rectangle ...
# draw.rect(Surface, color, rect, width)
pg.draw.rect(win, blue, rect, width)

for delta in range(0, 480):
    # initially move toward the bottom
    # when bottom of win is near
    # move rectangle to the right
    if delta > 240:
        x = delta - 240
        y = 240
    else:
        x = 0
        y = delta
    # update screen
    pg.display.flip()
    # small time delay
    milliseconds = 25
    pg.time.delay(milliseconds)
    # this erases the old window with white
    # also erases the old rectangle
    win.fill(white)
    print(x, y)  # test
    # move rect to new location and draw        
    new_rect = rect.move(x, y)
    pg.draw.rect(win, blue, new_rect, width)

'''not very functional because of the for loop
# event loop and exit conditions
# (the window's titlebar x click to exit)
while True:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            raise SystemExit
'''

PyGame also has sprites which do a better job with animations.

Exploring the Tkinter ttk expansion module (included with Python27 and Python32):

'''ttk_progressbar2c.py
explore the Tkinter ttk expansion kit Progressbar()

tested with Python27 and Python32
'''

try:
    # Python27
    import Tkinter as tk
    import ttk
except ImportError:
    # Python3+
    import tkinter as tk
    from tkinter import ttk

class MyApp(tk.Tk):
    def __init__(self):
        # sets up the root as self
        tk.Tk.__init__(self)
        self.title("ttk Progressbar")
        self.button = ttk.Button(text="start", command=self.start)
        self.button.pack(pady=5)
        self.maxbytes = 50000
        self.pbar = ttk.Progressbar(self, orient="horizontal",
            max=self.maxbytes, length=300, mode="determinate")
        self.pbar.pack(padx=5, pady=5)

    def start(self):
        '''reset then simulate when start button is pressed'''
        self.bytes = 0
        self.pbar["value"] = 0
        self.read_bytes()

    def read_bytes(self):
        '''simulate reading chunks of 500 bytes and update progress bar'''
        self.bytes += 500
        self.pbar["value"] = self.bytes
        if self.bytes < self.maxbytes:
            # read another chunk of bytes after 100 ms
            self.after(100, self.read_bytes)
        # optional percent display
        percent = int(float(self.bytes)/self.maxbytes * 100)
        self.title("percent complete = %d" % percent)


app = MyApp()
app.mainloop()

If you want help with any of the Tkinter widgets, for instance Text, do this ...

# Python27 (with Python3 change Tkinter to tkinter)

from Tkinter import *

help("Tkinter.Text")

If you want to see the possible options for a Tkinter widget, for instance Text use key() ...

# Python27 (with Python3 change Tkinter to tkinter)

from Tkinter import *
import pprint

# no options given
text = Text()

# shows possible options for Text widget
pprint.pprint(text.keys())

'''output >>>
['autoseparators',
 'background',
 'bd',
 'bg',
 'blockcursor',
 'borderwidth',
 'cursor',
 'endline',
 'exportselection',
 'fg',
 'font',
 'foreground',
 'height',
 'highlightbackground',
 'highlightcolor',
 'highlightthickness',
 'inactiveselectbackground',
 'insertbackground',
 'insertborderwidth',
 'insertofftime',
 'insertontime',
 'insertwidth',
 'maxundo',
 'padx',
 'pady',
 'relief',
 'selectbackground',
 'selectborderwidth',
 'selectforeground',
 'setgrid',
 'spacing1',
 'spacing2',
 'spacing3',
 'startline',
 'state',
 'tabs',
 'tabstyle',
 'takefocus',
 'undo',
 'width',
 'wrap',
 'xscrollcommand',
 'yscrollcommand']
'''

A closer look at the Tkinter multiline Text widget ...

# explore the Tkinter multiline Text widget
# add a vertical scroll feature
# vegaseat

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

class TextScroll(object):
    def __init__(self, master):
        """creates a text display area with a vertical scrollbar"""
        scrollbar = tk.Scrollbar(root)
        # text entry field, width in chars, height in lines of text
        self.text = tk.Text(root, yscrollcommand=scrollbar.set,
            width=80, height=30)
        scrollbar.config(command=self.text.yview)
        scrollbar.pack(side='right', fill='y')
        self.text.pack(side='left', expand=0, fill='both')

    def add_text_end(self, data):
        '''
        add text to the end of present text
        you need to supply needed newline characters
        '''
        self.text.insert('insert', data)

    def add_text_at(self, data, line=1, col=0):
        '''
        adds text at specified line and column
        line starts with 1 and column with 0
        '''
        start = "%d.%d" % (line, col)
        self.text.insert(start, data)

    def get_text_at(self, line=1, col=0, size=1):
        '''
        get text at specified line, column and size of char
        line starts with 1 and column with 0
        '''
        start = "%d.%d" % (line, col)
        end_col = col + size
        end = "%d.%d" % (line, end_col)
        print(start, end)  # test
        return self.text.get(start, end)

root = tk.Tk()
root.title('scrollable text area')

ts = TextScroll(root)

str1 = """\
use 
ctrl+c to copy selected text, 
ctrl+x to cut selected text,
ctrl+v to paste, and 
ctrl+/ to select all    
"""

ts.add_text_end(str1)

# notice newline character '\n'
# also pad ahead with newlines to accommodate line 9
# a little odd but has to be done
str2 = "\nGive it a try!"
ts.add_text_end(str2)

# to add text to a specified location
# there has to be existing text 
# or you can fill the targeted text area 
# with lines of spaces
spaces = ' ' * 30
lines = 5
for line in range(lines):
    ts.add_text_end('\n' + spaces)

str3 = "Add this to line 9, column4"
ts.add_text_at(str3, 9, 4)

str4 = "Add this to line 10, column8"
ts.add_text_at(str4, 10, 8)

# get a text 17 characters in size at line 3 and column 10
# display in title bar
mytext = ts.get_text_at(3, 10, 17)
root.title(mytext)

root.mainloop()

Here is the code I am using to create a splash screen. But the problem is that I don't know how to set a good volume of the canvas and the image should elapse the entire canvas.
Currently, a part of the image is being clipped away, how do i get to know whatever size of the image do i need. Then how do I settle the splash screen in exact middle of the screen.
Changing the values of the constants width and height are being divided by sometimes clips the parts of the image and sometimes starts clipping part of the entire window away from the screen. What should I do?

# create a splash screen, 80% of display screen size, centered,
# displaying a GIF image with needed info, disappearing after 5 seconds
import Tkinter as tk
root = tk.Tk()
# show no frame
root.overrideredirect(True)
width = root.winfo_screenwidth()
height = root.winfo_screenheight()

#geometry(). Returns a string describing self's "geometry". The string has the following format:
#   "%dx%d%+d%+d" % (width, height, xoffset, yoffset)
#where all coordinates are given in pixels.
root.geometry('%dx%d+%d+%d' % (width*0.4, height*0.4, width*0.4, height*0.4))
# take a .jpg picture you like, add text with a program like PhotoFiltre
# (free from http://www.photofiltre.com) and save as a .gif image file
image_file = "s1.gif"
#assert os.path.exists(image_file)
# use Tkinter's PhotoImage for .gif files
image = tk.PhotoImage(file=image_file)
canvas = tk.Canvas(root, height=height*0.4, width=width*0.4, bg="black")
canvas.create_image(width*0.4/2, height*0.4/2, image=image)
canvas.pack()
# show the splash screen for 8000 milliseconds then destroy
root.after(8000, root.destroy)
root.mainloop()

Here is an example that gets the size of the image and centers the splash screen:

# a Tkinter splash screen 
# (uses a GIF image file, does not need PIL)
# tested with Python27

import Tkinter as tk

class SplashScreen(tk.Toplevel):
    def __init__(self, master, image=None, timeout=1000):
        """
        create a splash screen from a specified image file
        keep splash screen up for timeout milliseconds
        """
        tk.Toplevel.__init__(self, master, relief='raised', borderwidth=5)
        self.main = master

        # don't show main window
        self.main.withdraw()
        self.overrideredirect(1)

        # use Tkinter's PhotoImage for .gif files
        self.image = tk.PhotoImage(file=image)
        self.after_idle(self.centerOnScreen)

        self.update()
        self.after(timeout, self.destroySplash)

    def centerOnScreen(self):
        self.update_idletasks()
        # get the width and height of the image
        self.width, self.height = self.image.width(), self.image.height()

        xmax = self.winfo_screenwidth()
        ymax = self.winfo_screenheight()

        x0 = self.x0 = xmax/2 - self.width/2
        y0 = self.y0 = ymax/2 - self.height/2
        self.geometry("%dx%d+%d+%d" % (self.width, self.height, x0, y0))
        self.createSplash()

    def createSplash(self):
        # show the splash image
        self.canvas = tk.Canvas(self, height=self.height, width=self.width)
        self.canvas.create_image(0,0, anchor='nw', image=self.image)
        self.canvas.pack()

    def destroySplash(self):
        # bring back main window and destroy splash screen
        self.main.update()
        self.main.deiconify()
        self.withdraw()

# test it ...
if __name__ == "__main__":
    import os

    # main window
    root = tk.Tk()
    s = "This was a test of the gif image splash screen"
    lbl = tk.Label(root, text=s, bg='yellow')
    lbl.grid(row=0, column=0, padx=5, pady=5)

    # pick a splash screen GIF image file you have in the working folder
    # otherwise give full path
    image_file = "TWEEK600.gif"
    assert os.path.exists(image_file)
    s = SplashScreen(root, timeout=5000, image=image_file)

    root.mainloop()
commented: thank you +12

A closer look at positioning and sizing the Tkinter window:

# set position and size of a Tkinter window
# optionally center it on the screen

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def center_win():
    '''center the root window on the screen'''
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    width = root.winfo_width()
    height = root.winfo_height()
    x = (screen_width - width) // 2
    y = (screen_height - height) // 2
    print(screen_width, screen_height, width, height, x, y)  # test
    #root.geometry("%dx%d+%d+%d" % (width, height, x, y))
    root.geometry('{0}x{1}+{2}+{3}'.format(width, height, x, y))


#root = tk.Tk()
root = tk.Tk(className="My Title")  # sets title too
# or give it your title this way
#root.title("My Title")

# width and height
w = 300
h = 200
# x and y position
x = 100
y = 150
# use width x height + x_offset + y_offset (no spaces!)
# x_offset and y_offset are coordinates of upper left corner
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
# or starting with Python27 and higher you can use format()
#root.geometry('{0}x{1}+{2}+{3}'.format(w, h, x, y))

# or only set x, y position of root
#root.geometry("+%d+%d" % (x, y))

# or only set size of root
#root.geometry("%dx%d" % (w, h))

# make Tk window not resizable, also disables the maximize button
#root.resizable(width=FALSE, height=FALSE)
# or simply
#root.resizable(0, 0)

# or make root window full screen
#root.state('zoomed')

# give it a colorful frame
frame = tk.Frame(root, bg='green')
frame.pack(fill='both', expand='yes')
# and a button
center_button = tk.Button(frame, text='Center root window', command=center_win)
center_button.pack()

root.mainloop()
commented: thanks a lot +12

You can use a Tkinter label as a frame with a background image ...

# use a Tkinter label as a panel/frame with a background image
# (note that Tkinter reads only GIF and PGM/PPM images)
# put a button on the background image

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

root = tk.Tk()
root.title('background image')

# pick a .gif image file you have in the working directory
# or give full path to the image file
image = tk.PhotoImage(file="roses.gif")
# get the width and height of the image
w = image.width()
h = image.height()
# position coordinates of root 'upper left corner'
x = 200
y = 50
# size the root to fit the image
root.geometry("%dx%d+%d+%d" % (w, h, x, y))

# tk.Frame has no image argument
# so use a label as a panel/frame
panel = tk.Label(root, image=image)
panel.pack(side='top', fill='both', expand='yes')

# put a button widget on the panel
button = tk.Button(panel, text='button widget')
button.pack(side='top', pady=5)

# save the panel's image from 'garbage collection'
panel.image = image

# start the event loop
root.mainloop()
commented: timely +12

This shows you how to draw on the PySide/PyQT canvas and save your drawing ...

'''ps__drawcircles_save1.py
draw circles and save them as an image file
tested with pyside474 and Python27/Python32
'''

from PySide.QtCore import *
from PySide.QtGui import *

class DrawEllipse(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 300, 640, 480)

    def paintEvent(self, event):
        # create a blank (640x480, white background) image with 
        # a painting program like GIMP (http://www.gimp.org/)
        image = QImage('blank640x480.png')        
        paint = QPainter()
        # the paint canvas is the blank image
        # paints in memory only
        paint.begin(image)
        # optional
        paint.setRenderHint(QPainter.Antialiasing)
        # optionally make a blue drawing background
        paint.setBrush(Qt.blue)
        paint.drawRect(event.rect())
        # this will draw red outlined circles
        paint.setPen(Qt.red)

        # for a circle make the 2 radii the same
        radx = 100
        rady = 100
        # optionally fill circles yellow
        paint.setBrush(Qt.yellow)
        for n in range(125, 420, 20):
            # set center x,y coordinates
            center = QPoint(n*1.25, n-12)
            # also change the 2 radii
            radx -= 10
            rady -= 10
            paint.drawEllipse(center, radx, rady)

        paint.end()
        # now save the modified image, format needs to match blank format
        fname = "mycircles.png"
        image.save(fname)
        s = "File %s saved" % fname
        self.setWindowTitle(s)
        # load the saved image and show on the real paint canvas
        image2 = QPixmap(fname)
        paint.begin(self)
        paint.drawPixmap(0, 0, image2)
        paint.end()        


app = QApplication([])
circles = DrawEllipse()
circles.show()
app.exec_()
commented: clever +0
# use config() to show info of a Tkinter widget

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

root = tk.Tk()

btn = tk.Button(width=30, bg='red')
btn.pack()

# show background color of btn
print(btn.config('bg')[-1])  # red

root.mainloop()

The PyGTK GUI toolkit can make a list box, but it is not simple:

'''pgtk_listbox1.py
uses gtk.TreeView(), gtk.ListStore() and gtk.CellRendererText()
to create a single column listbox
'''

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

class MyListBox(object):
    '''
    create a single column listbox
    '''
    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def __init__(self, name_list):
        """create a single column list box and load it with data"""
        self.name_list = name_list
        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_size_request(200, 300)
        # allows for smooth exit on 'x' click
        self.window.connect("delete_event", self.delete_event)

        # create the list model and load with the name_list
        self.listmodel = self.make_list()

        # create the TreeView
        self.treeview = gtk.TreeView()

        cell = gtk.CellRendererText()
        # create the "Name" column
        self.tvcolumn = gtk.TreeViewColumn("Names", cell)
        # align data to the left
        cell.set_property('yalign', 1.0)
        self.tvcolumn.set_cell_data_func(cell, self.cell_property)
        # append the only column to the treeview
        self.treeview.append_column(self.tvcolumn)
        # make it a list
        self.treeview.set_model(self.listmodel)
        # create a scrolled window for the treeview
        self.scrolledwindow = gtk.ScrolledWindow()
        self.scrolledwindow.add(self.treeview)
        # add the scrolled window to the main window
        self.window.add(self.scrolledwindow)
        # now show the main window
        self.window.show_all()

    def make_list(self):
        """
        create and load the list model
        """
        self.window.set_title("My name list")
        listmodel = gtk.ListStore(object)
        for name in self.name_list:
            #print(name)  # test
            listmodel.append([name])
        return listmodel

    def cell_property(self, column, cell, model, iter):
        """set cells to text"""
        cell.set_property('text', model.get_value(iter, 0))
        return


# a list of names for testing
name_list = [
"Frank Ferkel",
"Erich Meitinger",
"Leon Larimee",
"Jens Klein",
"Bjorn Bork",
"Heidrun Lovelace",
"Klaus Abraham",
"Ulla Jorgens",
"Volger Jenkings",
"Alexander Arm",
"Helmut Schmidt",
"Freja Larse",
"Larry Orkan",
"Andreas Mauser",
"Harry Heimlich",
"Peter Schwartz"
]

mylist = MyListBox(name_list)
gtk.main()

Hope you are not a mouse. This shows you how to select multiple listbox items from a Tkinter listbox widget:

'''Tk_Listbox_multiselect1.py
create a scrollable listbox using Tkinter
load the listbox with tasty cheese data
and select your favorite cheese or cheeses with the mouse
press <Shift> and/or <Ctrl> to select multiple cheeses
'''

try:
    # for Python2
    import Tkinter as tk
except ImportError:
    # for Python3
    import tkinter as tk


def get_list(event):
    """
    function to read the listbox selection(s)
    and put the result in a label widget
    """
    # get multiselected line indices
    indices = listbox.curselection()
    print(indices)  # test
    # get the selected lines' text
    seltext = '\n'.join(listbox.get(ix) for ix in indices)
    # 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("150x300+100+70")

# create a label (width in characters)
s1 = "Click on a cheese"
s2 = "press <Shift> and/or"
s3 = "<Ctrl> for multiples"
sf = "%s\n%s\n%s" % (s1, s2, s3)
label = tk.Label(root, text= sf, width=25)
label.grid(row=0, column=0)

# create a listbox (height in characters/lines)
# give it a nice yellow background (bg) color
# press <Shift> and/or <Ctrl> to select multiple listelements
listbox = tk.Listbox(root, height=15, bg='yellow', selectmode='extended')
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()

Create a one time button:

# make a one time button with Tkinter

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def once_btn():
    """
    once the button has been clicked, it no longer responds
    """
    #
    # put your 'do something once' code here ...
    #
    btn_onetime.config(state='disabled')  # state='normal' enables again
    # optionally show the state of the button
    print(btn_onetime.config('state')[-1])

# create the root window
root = tk.Tk()
# create a button
btn_onetime = tk.Button(root, text="Press Button", command=once_btn)
# pack button into root window
btn_onetime.pack(fill='both', expand=1)

# start the event loop
root.mainloop()

A generic data entry and processing program written in IronPython ...

'''ip_DataEntry1.py
a colorful IronPython generic data entry form
tested with IronPython 2.7 and MS.NET Framework 4.0
'''

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")

#
# start of code mostly created with the SharpDevelop4 IDE Formbuilder
#
import System.Drawing
import System.Windows.Forms

from System.Drawing import *
from System.Windows.Forms import *

class MainForm(Form):
    def __init__(self):
        self.InitializeComponent()

    def InitializeComponent(self):
        self._groupBox1 = System.Windows.Forms.GroupBox()
        self._groupBox2 = System.Windows.Forms.GroupBox()
        self._button1 = System.Windows.Forms.Button()
        self._label1 = System.Windows.Forms.Label()
        self._label2 = System.Windows.Forms.Label()
        self._label3 = System.Windows.Forms.Label()
        self._textBox1 = System.Windows.Forms.TextBox()
        self._textBox2 = System.Windows.Forms.TextBox()
        self._textBox3 = System.Windows.Forms.TextBox()
        self._groupBox1.SuspendLayout()
        self._groupBox2.SuspendLayout()
        self.SuspendLayout()
        # 
        # groupBox1
        # 
        self._groupBox1.BackColor = System.Drawing.Color.YellowGreen
        self._groupBox1.Controls.Add(self._textBox2)
        self._groupBox1.Controls.Add(self._textBox1)
        self._groupBox1.Controls.Add(self._label2)
        self._groupBox1.Controls.Add(self._label1)
        self._groupBox1.Location = System.Drawing.Point(12, 12)
        self._groupBox1.Name = "groupBox1"
        self._groupBox1.Size = System.Drawing.Size(301, 133)
        self._groupBox1.TabIndex = 0
        self._groupBox1.TabStop = False
        self._groupBox1.Text = "Data Entry"
        # 
        # groupBox2
        # 
        self._groupBox2.BackColor = System.Drawing.Color.PowderBlue
        self._groupBox2.Controls.Add(self._textBox3)
        self._groupBox2.Controls.Add(self._label3)
        self._groupBox2.Location = System.Drawing.Point(12, 184)
        self._groupBox2.Name = "groupBox2"
        self._groupBox2.Size = System.Drawing.Size(301, 66)
        self._groupBox2.TabIndex = 1
        self._groupBox2.TabStop = False
        self._groupBox2.Text = "Result"
        # 
        # button1
        # 
        self._button1.BackColor = System.Drawing.Color.Bisque
        self._button1.Location = System.Drawing.Point(12, 155)
        self._button1.Name = "button1"
        self._button1.Size = System.Drawing.Size(301, 23)
        self._button1.TabIndex = 2
        self._button1.Text = "Press to process data"
        self._button1.UseVisualStyleBackColor = False
        self._button1.Click += self.Button1Click
        # 
        # label1
        # 
        self._label1.Location = System.Drawing.Point(6, 27)
        self._label1.Name = "label1"
        self._label1.Size = System.Drawing.Size(100, 23)
        self._label1.TabIndex = 0
        # change this text for your own use
        self._label1.Text = "Enter Name:"
        # 
        # label2
        # 
        self._label2.Location = System.Drawing.Point(6, 77)
        self._label2.Name = "label2"
        self._label2.Size = System.Drawing.Size(100, 23)
        self._label2.TabIndex = 1
        # change this text for your own use
        self._label2.Text = "Enter Age:"
        # 
        # label3
        # 
        self._label3.Location = System.Drawing.Point(6, 29)
        self._label3.Name = "label3"
        self._label3.Size = System.Drawing.Size(100, 23)
        self._label3.TabIndex = 0
        # change this text for your own use
        self._label3.Text = "Processed data:"
        # 
        # textBox1
        # 
        self._textBox1.Location = System.Drawing.Point(128, 27)
        self._textBox1.Name = "textBox1"
        self._textBox1.Size = System.Drawing.Size(100, 20)
        self._textBox1.TabIndex = 2
        # 
        # textBox2
        # 
        self._textBox2.Location = System.Drawing.Point(128, 77)
        self._textBox2.Name = "textBox2"
        self._textBox2.Size = System.Drawing.Size(100, 20)
        self._textBox2.TabIndex = 3
        # 
        # textBox3
        # 
        self._textBox3.Location = System.Drawing.Point(102, 26)
        self._textBox3.Name = "textBox3"
        self._textBox3.Size = System.Drawing.Size(185, 20)
        self._textBox3.TabIndex = 1
        # 
        # MainForm
        # 
        self.BackColor = System.Drawing.Color.Green
        self.ClientSize = System.Drawing.Size(325, 262)
        self.Controls.Add(self._button1)
        self.Controls.Add(self._groupBox2)
        self.Controls.Add(self._groupBox1)
        self.Name = "MainForm"
        self.Text = "Process Name and Age"
        self._groupBox1.ResumeLayout(False)
        self._groupBox1.PerformLayout()
        self._groupBox2.ResumeLayout(False)
        self._groupBox2.PerformLayout()
        self.ResumeLayout(False)


    def Button1Click(self, sender, e):
        """process data and show result"""
        # this code added by user
        # you can add your own processing code here
        sf = "Hello %s you are %s years old"
        s = sf % (self._textBox1.Text, self._textBox2.Text)
        self._textBox3.Text = s
#
# end of code mostly created with the SharpDevelop4 IDE Formbuilder
#

# final line added to make it run
Application.Run(MainForm())

Download IronPython from:
http://ironpython.codeplex.com/releases/view/81726
Download the SharpDevelop IDE from:
http://www.icsharpcode.net/opensource/sd/

Here is an example how to compile the previous code example to a Windows .exe program ...

'''ip_compile_DataEntry1.py
compile an ironpython sript file to an executable file
creates a Windows .exe file and an associated .dll file

it is best to put this file into a special directory
together with the ironpython script file you want to compile
then run it with 
ipy.exe ip_compile_DataEntry1.py
I simply used the ConTEXT IDE configured to run IronPython.

----------------------------------------------------
info about pyc: The Command-Line Python Compiler

Usage: ipy.exe pyc.py [options] file [file ...]

Options:
/out:output_file    Output file name (default is main_file.<extension>)
/target:dll     Compile only into dll.  Default
/target:exe     Generate console executable stub for startup in addition to dll.
/target:winexe  Generate windows executable stub for startup in addition to dll.
/? /h               This message

EXE/WinEXE specific options:
/main:main_file.py       Main file of the project (module to be executed first)
/platform:x86            Compile for x86 only
/platform:x64            Compile for x64 only

Example:
ipy.exe pyc.py /main:myprogram.py myform.py /target:winexe

creates myform.exe and associated myform.dll
---------------------------------------------------
needs IronPython 2.7 or higher
'''

import subprocess

# the IronPython script file you want to convert ...
ip_scriptfile = "ip_DataEntry1.py"

# location of IronPython and compile utility
ipython = "C:/IronPython27/ipy.exe"
utility = "C:/IronPython27/Tools/Scripts/pyc.py",
main = "/main:" + ip_scriptfile
target = "/target:winexe"
subprocess.call([ipython, utility, main, target])    

The above program creates two files you need to run ...
ip_DataEntry1.exe (executable stub, size = 3k)
ip_DataEntry1.dll (size = 32k)

wxPython is not totally dead, just hasn't ported to Python3 yet:

# exploring wxPython (http://www.wxpython.org/)
# get the position of the mouse when clicked or moved inside a frame
# Python 2.7.3

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title)
        self.SetBackgroundColour('yellow')
        # give it a pencil cursor
        self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))

        # bind different mouse events
        self.Bind(wx.EVT_LEFT_DOWN, self.onLeftDown)
        self.Bind(wx.EVT_MOTION, self.onMotion)

    def onLeftDown(self, event):
        """left mouse button is pressed"""
        # get the position tuple (x, y)
        pt = event.GetPosition()
        # show result in frame's titlebar
        self.SetTitle('LeftMouse click at = ' + str(pt))

    def onMotion(self, event):
        """mouse in motion"""
        pt = event.GetPosition()
        self.SetTitle('Mouse in motion at = ' + str(pt))


app = wx.App(0)
title = "Move or click mouse"
MyFrame(None, title).Show()
app.MainLoop()

The wxPython GUI toolkit offers nice and grisp code:

# exploring wxPython (http://www.wxpython.org/)
# use wxPython's wx.gizmos.LEDNumberCtrl for an LED clock
# Python 2.7.3 and wxPython 2.9

import wx
import wx.gizmos
import time

class LED_clock(wx.Frame):
    """
    create an LED clock showing the current time
    """
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title='LED Clock',
            size=(320, 100))
        self.led = wx.gizmos.LEDNumberCtrl(self, wx.ID_ANY,
            style=wx.gizmos.LED_ALIGN_CENTER)
        # default colours are green on black
        self.led.SetBackgroundColour("blue")
        self.led.SetForegroundColour("yellow")

        # set up a timer
        self.timer = wx.Timer(self, wx.ID_ANY)
        # update clock digits every second (1000ms)
        self.timer.Start(1000)
        self.Bind(wx.EVT_TIMER, self.onTimer)

    def onTimer(self, event):
        # get current time from computer
        current = time.localtime(time.time())
        # time string can have characters 0..9, -, period, or space
        ts = time.strftime("%H %M %S", current)
        self.led.SetValue(ts)


# test the LED_clock class ...
if __name__ == '__main__':
    app = wx.App(0)
    LED_clock(None).Show()
    app.MainLoop()

Use wxPython to nicely display a picture from the internet:

# exploring wxPython (http://www.wxpython.org/)
# display an image obtained from an internet web page
# Python 2.7.3 and wxPython 2.9

import wx
import urllib2
import cStringIO

class ImagePanel(wx.Panel):
    """ create a panel with a wx.StaticBitmap """
    def __init__(self, parent, bmp):
        wx.Panel.__init__(self, parent, wx.ID_ANY)
        self.SetBackgroundColour('brown')
        # show the static bitmap in the center of the panel
        wx.StaticBitmap(self, wx.ID_ANY, bmp, pos=(43, 30))
        # optional
        parent.SetTitle("have a nice DaniWeb day")


app = wx.App(0)

# in this case a picture downloaded to tinypic.com
image_url = "http://i48.tinypic.com/w6sjn6.jpg"

# open the image url and read bytes into a variable
opener = urllib2.build_opener()
image_bytes = opener.open(image_url).read()

# convert image bytes to data stream
data_stream = cStringIO.StringIO(image_bytes)

# convert data_stream to a bitmap
bmp = wx.BitmapFromImage(wx.ImageFromStream(data_stream))

# calculate width and height needed to set the frame
# plus a little extra for the border
width = bmp.GetWidth() + 100
height = bmp.GetHeight() + 100

# create window/frame instance
frame = wx.Frame(None, wx.ID_ANY, size=(width, height))
# create the panel instance
ImagePanel(frame, bmp)
# show the frame
frame.Show(True)

# start the GUI event loop
app.MainLoop()

See result:
http://i45.tinypic.com/1zxryvt.jpg

After a hint from Snippsat and Lardmeister I tested out wxPython Phoenix, a project still in development that modernizes wxPython and also makes it work for Python3:

'''wxp_html.HtmlWindow_101.py
exploring wxPython's
wx.html.HtmlWindow(parent, id, pos, size, style, name)
to show colourful text using relatively simple html code

for Python32 download the new wx phoenix version
(still in development, but works fairly well)
here the Windows version dated 11/12/2012
wxPython-Phoenix-r72945-win32-py3.2.tar.gz
from
http://wxpython.org/Phoenix/snapshot-builds/
then simply extract the wx folder to
C:\Python32\Lib\site-packages
'''

import wx
import wx.html

class MyFrame(wx.Frame):
    def __init__(self, parent, mytitle, mysize, html_code):
        wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle,
            size=mysize)

        htmlwin = wx.html.HtmlWindow(self, wx.ID_ANY, style=wx.NO_BORDER)
        htmlwin.SetPage(html_code)


# simple HTML code ...
# text between <B> and </B> is bold
# <BR> inserts a line break (or new line)
# text between <FONT color="blue"> and </FONT> is that color
# text between <H3> and </H3> is header size
# etc. etc. just experiment with the <> tags
html_code = """\
This shows you how to display text in color
<BR>
<FONT color="blue">like blue text</FONT>
<FONT color="red"> or red text</FONT>
<B> or want to see it bold ...</B>
<BR>
<H3>or large size</H3><H2> or larger size</H2>
<BR>
<FONT size="+4">or even larger size</FONT>
<BR>
<FONT color="brown" size="+4">larger size and color</FONT>
<BR><BR>
... and yes, you can do scientific things like this ...
<BR>
H<sub>2</sub>O
<BR>
x<sup>3</sup> + y<sup>2</sup> - 15 = 0
"""

app = wx.App(0)
mytitle =  "wx.html.HtmlWindow formatted text"
width = 450
height = 380
frame = MyFrame(None, mytitle, (width, height), html_code)
frame.Show(True)
frame.Center()
app.MainLoop()

Thanks Zoey! I decided to give project Phoenix a try with this wxPython stop watch code:

'''wxp_stopwatch101.py

a simple wxPython stopwatch that counts in increments of 0.1 seconds

for Python32 see:
http://wxpython.org/Phoenix/snapshot-builds/
download the latest snapshot-build for py3.2
then simply extract the wx folder to
C:\Python32\Lib\site-packages

tested with Python27/wx29 and Python32/wx(phoenix)
'''

import wx
import threading
import time

class MyPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, style=wx.RAISED_BORDER)
        # optionally give the panel a nice color
        self.SetBackgroundColour("dark green")

        # create the needed widgets
        self.text = wx.TextCtrl(self)
        # wx.Font(pointSize, family, style, weight, underline, faceName)
        self.text.SetFont(wx.Font(20, 74, 90, 92, False, "Comic Sans MS"))
        self.button_start = wx.Button(self, wx.ID_ANY, "Start")
        self.button_stop = wx.Button(self, wx.ID_ANY, "Stop")

        # lay out the widgets
        sizer = wx.GridBagSizer(vgap=5, hgap=5)
        # Add(widget, pos, span, flag, border)
        # pos=(row, column)  span=(rowspan, columnspan)
        sizer.Add(self.text, pos=(0, 1), span=(2, 5), flag=wx.ALL|wx.EXPAND, border=5)
        sizer.Add(self.button_start, pos=(2, 2), flag=wx.ALL, border=1)
        sizer.Add(self.button_stop, pos=(3, 2), flag=wx.ALL, border=1)
        self.SetSizer(sizer)

        # bind mouse events
        self.button_start.Bind(wx.EVT_LEFT_DOWN, self.button_start_click)
        self.button_stop.Bind(wx.EVT_LEFT_DOWN, self.button_stop_click)

    def button_start_click(self, event):
        self.counter = Counter(self.text)
        self.counter.start()

    def button_stop_click(self, event):
        count = self.counter.finish()


class Counter(threading.Thread):
    '''
    create a thread object that will do the counting in the background
    '''
    def __init__(self, display_widget):
        # init the thread
        threading.Thread.__init__(self)
        # controls the while loop in the run command
        self.alive = False
        # the display widget for the count
        self.display = display_widget

    def run(self):
        '''
        this will run in a separate thread
        '''
        self.alive = True
        self.value = 0.0
        while self.alive:
            # count every 0.1 seconds
            time.sleep(0.1)
            self.value += 0.1
            #print(self.value)  # test
            self.display.SetValue("%0.1f" % self.value)

    def peek(self):
        '''
        peek at the current value (optional)
        '''
        return self.value

    def finish(self):
        '''
        close the thread (stop the while loop in method run)
        and return the final value
        '''
        self.alive = False
        return self.value


app = wx.App(0)
# give the frame a titlebar caption and a size
mytitle = "My Stop Watch"
width = 230
height = 180
# create the wx.Frame class instance
frame = wx.Frame(None, title=mytitle, size=(width, height))
# create the MyPanel class instance
MyPanel(frame)
frame.Show()
app.MainLoop()

Wow, project Phoenix is in progress and is sometimes updated several times a day at
http://wxpython.org/Phoenix/snapshot-builds/

The PySide GUI toolkit is available for all versions of Python. Here is a little test with Python33:

'''ps_test_QMessageBox2.py

a simple template to test PySide widgets like 
QMessageBox and QMainWindow (has statusbar)

PySide is the official LGPL-licensed version of PyQT

binary installers are available for:
Windows
Linux
Mac OS X
at http://qt-project.org/wiki/PySideDownloads

tested with Python33 and  PySide 1.1.2 (based on pyQT474 or higher) 
'''

from PySide.QtCore import *
from PySide.QtGui import *

# replace [] with sys.argv for commandline operation
app = QApplication([])

# ----- start your widget test code ----

# need QMainWindow for statusbar
win = QMainWindow()

# QMessageBox.warning(parent, title, text, button0Text)
reply = QMessageBox.warning(win, 'Read this!',
            "Drinking and Driving won't mix well!",
            QMessageBox.Ok)

win.statusBar().showMessage('Thanks for reading this warning!')

win.show()

# ---- end of widget test code -----

app.exec_()

Well, why not?
I am hopping on the wxPython project Phoenix bandwagon with this example ...

'''wxp_StaticBitmap_image_b64_1.py

for smaller images it is best to embed the image as base64 encoded 
string and then convert this string to a bitmap

tested with Python 2.7.3 and Python 3.2.3 and wx/wx-phoenix by vegaseat
'''

import wx
import io
import base64
import sys


class ImagePanel(wx.Panel):
    """ create a panel with a wx.StaticBitmap """
    def __init__(self, parent, bmp):
        wx.Panel.__init__(self, parent, wx.ID_ANY)
        # show the static bitmap
        wx.StaticBitmap(self, wx.ID_ANY, bmp, pos=(50, 40))


# a typical base64 encoded image string
# see:
# http://www.daniweb.com/software-development/python/code/440446/python2python3-base64-encoded-image
rainbow_jpg_b64='''\
/9j/4AAQSkZJRgABAQEAyADIAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAoACgDASIA
AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+VL4J
/Aj4eeN/hNo+uan4a0mXWDo1pLNdNZQF7hvKh3TTOUP78f8ALWQk+aD1888+lfBf9lf4ceMvFF5p
d54Y0q4jt7wwpHJY28q7dkZx/qzwDz0681vfst/8kU0n/sCWn/pNDX0/+x/DFJ8RNW8xd/8AxNB9
7d/cTH06/wBM1/sn9Eb6OXhx4n/Rrx3FWeZHl9XPcuwuMl9fq4SlUrVVHGyp03Ko4cynCKUE1LVb
p2P6H/aG5/gfCD6O/AHFfC+QZTgs3x/AuU4vF4zB4HC4XE18T/ZWGnPEVKtKjGVStNyc6lWT5pyv
KTbk2fTnhX/glZ8DtU8Pw6hL8PPD8jyfxNpNmzen/Pv6cH2Ne5+Bf+COfwA1vQtQvrj4Z+G5JbeG
R1ZtHseqOh6/Z/6j9K/Wn4Z6bY/8IPZ/6LGPuddw/wCWa/T/ACOOOn2F8JdL0+P4f+JpFtY1kTT7
plbLfK29P85Nf8k/7TLxQ408GfF+XD3BvEOa5VgVi6tONHAYzEYakksTRhFOFKpBWtK2nTzZ/hX+
zk+mDx34wfSXwfBnF1JZnk08fmVOWExs44ihy0alKMIyp1YTi7KTsrW00Suz+H39v/8AYw+D37P3
w/8AFV54b8GaFY61BpN8YLiHTbWOSyZYZQsyhI/kuMY8mQ/6nAx+/A8or7I/4LJf8iV40/7Buof+
iJqK/p36HvEeecV+FNLOM+zTGZnmGIx7dTE42tPFVbfVqElCM6znKMIvaKdr3drtn/Q59M/IMi4e
4m8PMNkWT5dk+HxPAtDGV6OXYTD4SFbE1cwxHPXrKhSgqtVxjCHtJpz5IxjeysfnB+y3/wAkU0n/
ALAlp/6TQ19Sfsdf8lD1b/sJ/wDsiV8t/st/8kU0n/sCWn/pNDX0/wDsezRx/ETVtzqv/E16N3wi
Z6de3X+Vf9W/7PyUY/RK4h5pRing8Yk5O128wnZJvTvu1sfiH7WSMp/RS8M1GLk/+Ie5VpFNv/kU
YTokf1C/DH/kRrP6r/6LWvsT4Uf8k68Vf9gy6/8ARkdfGXwwvrP/AIQez/0iE/Mv8S/3E/z+fbNf
YXwlvrNvh/4ojWeFpDp10qr5i7mben5fX+Vf8NX7Y28/HxuKckswrXcU5JL67hm22lay9dvPQ/5m
P2R9GtD6YWAc6VSK/tTNneUJJf7xR0d4pLa+/wCtv5Qf+CyX/IleNP8AsG6h/wCiJqKP+CyX/Ile
NP8AsG6h/wCiJqK/sT6DX/JlcH/2Hf8AurQP+uz6c/8AyVnhr/2bzCf+p+JPx7+Cfx2+HXgj4TaP
oWq+JtIi1c6NaJNaNewB7aTyoh5Uyl8pOSP3qHmIg5GcgemfBP8Aam+GfgrxReanf+J9It45rzzl
kkv7dVZNiJ08zts+mc0UV/rd4cfSM8TeBvDpcEcO4/AYXInRr05U5YWtOvNVa3tJynUji6cJScnu
6VrJLlPxrx44rxHirwDw7wfxbleTYjJsoyDAZThYYbC4mlXeGw2Co0ISq1K2MxEJ1pwgnUnGnCEp
NtU4qyX6z+E/+CqvwH0nw/b6fJ8RfDaSx8bW1izV0yuP+eg7nHrnjqa908B/8Fj/ANnnQdB1DT7j
4m+GIZLmGSMK2tWS9WT/AKeD16+45oor/Kj6RfgnwV4zcUvP+No5piMxdWU3PB4rD0KfNOcKj9yv
g8U7c0U7c3kfxb4A+Cfhv4QeIlHjLgzh6hh87p1q9aNTGP29HnqzhKV6dGOGm1eKt+8uu5+Tn/BQ
X9s34NftBfD/AMVWvhfxroF7rU2k3629rb6naSNfN5MvyQoj/vJ/+eMf/Lf3uP8AWlFFfp/gnwLk
nh7wrU4fyCeO/s6ni/bU442vSrVISlThBwjOjQw8fZpU4uMXBuLbs0uVR/tLx98Q898Q8z4VzDPK
WXUK+V5DLKcOssoV8NTnhqOLlWpyrRr4rFOVZOrKLnCVOLhGPucycn//2Q==
'''

app = wx.App(redirect=False)

try:
    # Python2 wx
    jpg_bytes = base64.b64decode(rainbow_jpg_b64)
    data_stream = io.BytesIO(jpg_bytes)
    bmp = wx.BitmapFromImage(wx.ImageFromStream(data_stream))
except TypeError:
    # Python3 wx-phoenix
    jpg_bytes = base64.b64decode(rainbow_jpg_b64.encode())
    data_stream = io.BytesIO(jpg_bytes)
    bmp = wx.Bitmap(wx.Image(data_stream))

# create window/frame
frame = wx.Frame(None, wx.ID_ANY, size = (400, 300))
# create the panel instance
ImagePanel(frame, bmp)
# show the frame
frame.Show()
# start the GUI event loop
app.MainLoop()

One complication is that you now you have to make sure that the code works with Python2 and Python3.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.