1

A short piece of pygame code to show you a red square that follows the mouse click position ...

# exploring pygame mouse action
# let the red square follow the mouse click position
# tested with Python 2.6.5 and pygame 1.9.1  by vegaseat

import pygame as pg

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

screen = pg.display.set_mode((500, 500))
pg.display.set_caption("click the mouse on the window ...")

# create a little red square
red_square = pg.Surface((30, 30))
red_square.fill(red)

# starting position
xy_position = (100, 100)

# set up the event loop
running = True
while running:
    event = pg.event.poll()
    keyinput = pg.key.get_pressed()
    # exit on corner 'x' click or escape key press
    if keyinput[pg.K_ESCAPE]:
        raise SystemExit
    elif event.type == pg.QUIT:
        running = False
    elif event.type == pg.MOUSEBUTTONDOWN:
        #print(event.pos)  # test
        xy_position = event.pos

    # this erases the old sreen
    screen.fill(white)
    # put the image on the screen at given position
    screen.blit(red_square, xy_position)
    # update screen
    pg.display.flip()
1

Another pygame mouse event code that checks if the mouse has been clicked inside or outside a given rectangle ...

# exploring module pygame
# draw a red rectangle on a white screen
# check if the mouse is clicked within the red rectangle
# tested with Python 3.1.2 and pygame 1.9.1  by vegaseat

import pygame as pg

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

# window/screen width and height
screen_w = 450
screen_h = 450
screen = pg.display.set_mode((screen_w, screen_h))
# default background is black so fill it white
screen.fill(white)
pg.display.set_caption("click the mouse on the red rectangle ...")

# a rect object is set with (x1, y1, w, h)
# where (x1, y1) are the upper left corner coordinates
# w and h are the width and height of rect
rect = (130, 120, 180, 170)
x1, y1, w, h = rect
# calculate lower right corner coordinates (x2, y2) needed later
x2 = x1 + w
y2 = y1 + h
# pygame.draw.rect(Surface, color, Rect, width=0)
# if width is not given, then rectangle is filled
myrect = pg.draw.rect(screen, red, rect)

# update display
pg.display.flip()

# starting position
x, y = 0, 0

# event loop ...
running = True
while running:
    for event in pg.event.get():
        # quit when window corner x is clicked
        if event.type == pg.QUIT:
            running = False
        elif event.type == pg.MOUSEBUTTONDOWN:
            #print(event.pos)  # test
            x, y = event.pos

    # check if x and y fall within the bounderies of the rectangle
    if myrect.collidepoint(x, y):
        pg.display.set_caption("mouse clicked within the red rectangle")
    else:
        pg.display.set_caption("mouse clicked outside the red rectangle")

The last few lines replaced the strict Python solution of ...

# check if x and y fall within the bounderies of the rectangle
    if x1 <= x <= x2 and y1 <= y <= y2:
        pg.display.set_caption("mouse clicked within the red rectangle")
    else:
        pg.display.set_caption("mouse clicked outside the red rectangle")

Edited by vegaseat: updated using pygame method

1

Pygame has some nice image processing available, here is an example ...

# experiments with module pygame
# free from: http://www.pygame.org/
# load, rotate, zoom and display an image
# tested with Python 3.1.2 and pygame 1.9.1 by vegaseat

import pygame as pg

# initialize pygame
pg.init()

# create a 640x480 black screen (black is the default)
screen = pg.display.set_mode((640, 480))

# pick an image you have (.bmp  .jpg  .png  .gif) in the 
# working folder, or use the full pathname
image_file = "Audi.jpg"

# load the image from a given file
image = pg.image.load(image_file).convert()

# this will rotate the image angle degrees counter clockwise
# and also zoom using the scale factor
angle = 25.5
scale = 1.5
image = pg.transform.rotozoom(image, angle, scale)
# optional window title
s = "%s rotated %s degrees and zoomed at %s" % \
    (image_file, angle, scale)
pg.display.set_caption(s)

# draw modified image, position the image ulc at x=5, y=-60
# negative y goes up
screen.blit(image, (5, -60))

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

# run the event loop until
# the user clicks on the window corner x to exit
while True:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            raise SystemExit

Attached is the Audi.jpg image. IMHO the cutest car ever made. Run the program with the image and see what happens.

Edited by vegaseat: audi

Attachments Audi.jpg 33.04 KB
1

Here is a simple way to create a transparent image on your screen ...

# explore Tkinter transparency
# show image without root title or root border
# you have to add a way to exit, like mouse double click

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

def exit(event=None):
    root.destroy()

root = tk.Tk()
# only set x, y position of root
x = 200
y = 100
root.geometry("+%d+%d" % (x, y))

# use opacity alpha values from 0.0 to 1.0
# lower alpha is most transparent
# opacity/tranparency applies to image too
root.wm_attributes('-alpha', 0.7)  

# remove border from root window
root.overrideredirect(1)

# you can get sample image LAKE2.gif from
# http://www.daniweb.com/forums/post866067.html#post866067
photo = tk.PhotoImage(file="LAKE2.gif")

tk.Label(root, image=photo).pack()

# double click mouse on picture to exit
root.bind('<Double-1>', exit)

root.mainloop()
1

The Tkinter spin box is a nice input widget for numeric values. Let's take a closer look ...

# explore the Tkinter spin box
# similar to: http://effbot.org/tkinterbook/spinbox.htm
# tested with Python 3.1.2 and Tkinter 8.5  vegaseat

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

def click_sb1():
    """get value via textvariable"""
    s = "sb1 value = %s" % v.get()
    root.title(s)

def click_sb2():
    """get value directly"""
    s = "sb2 value = %s" % sb2.get()
    root.title(s)
 

root = tk.Tk()
root['bg'] = 'green'

v = tk.StringVar()

# goes from 0 to 10 in steps of 1 (default)
sb1 = tk.Spinbox(root, from_=0, to=10, textvariable=v, 
    command=click_sb1, width=40)
sb1.pack(padx=10, pady=5)

# goes from 0 to 10 in steps of 0.5
sb2 = tk.Spinbox(root, from_=0, to=10, increment=0.5,
    command=click_sb2)
sb2.pack(padx=10, pady=5)

# goes incremental 1 2 4 8 16
sb3 = tk.Spinbox(root, values=(1, 2, 4, 8, 16))
sb3.pack(padx=10, pady=5)

# goes incemental as specified by range()
# here from 10 to 100 in steps of 5
# list() needed for Python3
steps = list(range(10, 101, 5))
sb4 = tk.Spinbox(root, values=steps)
sb4.pack(padx=10, pady=5)

root.mainloop()
3

Since the Tkinter GUI toolkit is included with just about all Python versions, you can use it for a convenient anykey() function in your console applications. The anykey() function will wait until any key on the keyboard is pressed (no need to press the Enter key too) ...

# use Tkinter for a console anykey function
# for Python3 use import tkinter as tk
# tested with Python 2.6.5  vegaseat

import Tkinter as tk

def anykey(prompt="Press any key to continue ... "):
    """
    waits until any key on the keyboard is pressed
    (use only in console programs)
    """
    def key(event):
        # quits all Tkinter programs, so watch out
        root.quit()
        return
    root = tk.Tk()
    print(prompt)
    root.bind_all('<Key>', key)
    # Tkinter window will not show
    root.withdraw()
    root.mainloop()

# run some console code
for x in range(100, 200, 10):
    print(x)

# now call anykey
anykey()

# do some more console stuff
for c in "hello":
    print(c)

anykey()

# do more code or allow exit

The next option would be to use a mouse click to continue a console program. Here we can't withdraw the root, but make it full screen and transparent instead. This way it won't show ...

# use Tkinter for a console mouse click function
# for Python3 use import tkinter as tk
# tested with Python 2.6.5  vegaseat

import Tkinter as tk

def mouseclick(prompt="Click the left mouse button to continue ... "):
    """
    waits until the left mouse button has been clicked
    (use only in console programs)
    """
    def mouse(event):
        # quits all Tkinter programs, so watch out
        root.quit()
        return
    root = tk.Tk()
    print(prompt)
    root.bind_all('<Button-1>', mouse)
    # make Tkinter almost fully transparent so it will not show
    root.wm_attributes('-alpha', 0.01)
    # make root window full screen, so mouse can be clicked anywhere
    root.state('zoomed')
    root.mainloop()

# run some console code
for x in range(200, 100, -10):
    print(x)

# now call mouseclick
mouseclick()

# do some more console stuff
for word in "mice are nice".split():
    print(word)

mouseclick()

# do more code or allow exit

Edited by vegaseat: mouseclick

Votes + Comments
Interesting
nice !
1

Exploring a Tkinter list box ...

# load a Tkinter listbox with data
# color alternate lines
# and select a listbox item with the mouse

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

def get_list(event=None):
    """
    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

# the main window
root = tk.Tk()

# create a label (width in characters)
label = tk.Label(root, width=15)
label.pack()

# create a listbox (height in characters)
listbox = tk.Listbox(root, height=15)
listbox.pack()

friend_list = [
'Stew', 'Tom', 'Jens', 'Adam', 'Al', 'Ethel',
'Barb', 'Tiny', 'Tim', 'Pete', 'Sue', 'Zack',
'Frank', 'Gustav', 'Ted', 'Morgan', 'Karen']

# load the listbox
for index, item in enumerate(friend_list):
    listbox.insert('end', item)
    # optionally color alternate lines
    if index % 2:
        listbox.itemconfig(index, bg='light blue')
    
# left mouse click on a list item to display selection
listbox.bind('<ButtonRelease-1>', get_list)
# use mouse wheel to scroll listbox items, focus first
listbox.focus()

root.mainloop()
1

Using the Tkinter GUI toolkit to create five pointed stars ...

# explore Tkinter's
# canvas.create_polygon(xy_list, fill)
# to create five pointed stars

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

# create the root window and set title too
root = tk.Tk(className="five pointed stars")

w = 400
h = 400
x = 50
y = 100
# set x, y position of root
root.geometry("+%d+%d" % (x, y))

# pairs of x,y coordinates for the 10 corners of a five pointed star
star = [10,40,40,40,50,10,60,40,90,40,65,60,75,90,50,70,25,90,35,60]

# create the drawing canvas
canvas = tk.Canvas(root, width=w, height=h, bg='white')
canvas.pack()

canvas.create_polygon(star, fill='red')

# shift the star x,y by 70
star1 = [k+70 for k in star]
canvas.create_polygon(star1, fill='blue')

# shift the star x,y by 140
star2 = [k+140 for k in star]
canvas.create_polygon(star2, fill='maroon')

# double the size and shift the star x,y by 180
star3 = [k*2+180 for k in star]
canvas.create_polygon(star3, fill='green')

root.mainloop()
1

A simple template to experiment with PyQT widgets ...

# a simple template to test PyQT widgets
# PyQT free from:
# http://www.riverbankcomputing.co.uk/software/pyqt/download
# used Windows installer PyQt-Py3.1-gpl-4.7.2-1.exe
# tested with PyQT4.7 and Python3.1

from PyQt4.QtCore import *
from PyQt4.QtGui import *

app = QApplication([])
# create the window and set the title
win = QWidget()
# setGeometry(x_pos, y_pos, width, height)
# 1, 1 --> widget will expand to fit lable size
win.setGeometry(100, 150, 1, 1)


html_code = """\
<h1><i>Hello </i>
<font color=red>PyQT!</font><h1>
"""
# create the label and insert html code as text
label = QLabel(html_code)

# use the grid layout manager
grid = QGridLayout()
# addWidget(widget, row, column, rowSpan=1, columnSpan=1)
grid.addWidget(label, 0, 0)
win.setLayout(grid)


win.show()
app.exec_()

You can even go simpler ...

# a very simple template to test PyQT widgets

from PyQt4.QtCore import *
from PyQt4.QtGui import *

app = QApplication([])


html_code = """\
<h1><i>Hello </i>
<font color=red>PyQT!</font><h1>
"""
# create the label and insert html code as text
label = QLabel(html_code)
label.show()


app.exec_()
1

One way to get some sound into your Tkinter GUI toolkit code ...

# play a wave sound file with Tkinter using the module pygame
# pygame is free from: http://www.pygame.org/
# tested with Python26, Python31 and pygame1.9.1  vegaseat

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

def pg_play_sound(sound_file):
    """
    uses the pygame mixer
    will load the whole sound into memory before playback
    """
    sound = pg.mixer.Sound(sound_file)
    clock = pg.time.Clock()
    sound.play()
    # how often to check active playback
    frame_rate = 30
    while pg.mixer.get_busy():
        clock.tick(frame_rate)

def play_sound():
    pg_play_sound(sound_file)


# initiate the mixer with these values for good sound
FREQ = 18000   # play with this for best sound
BITSIZE = -16  # here unsigned 16 bit
CHANNELS = 2   # 1 is mono, 2 is stereo
BUFFER = 1024  # audio buffer size, number of samples
pg.mixer.init(FREQ, BITSIZE, CHANNELS, BUFFER)
# or use just default values (sounds a bit more tinny)
#pg.mixer.init()

root = tk.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("250x50+50+30")
root['bg'] = 'green'

# pick a .wav sound file you have in the working directory
# or give the full path
sound_file = "Chimes.wav"
root.title(sound_file)
s = "Play " + sound_file
b1 = tk.Button(root, text=s, command=play_sound)
b1.pack(padx=30, pady=5)

root.mainloop()
1

Every now and then there is a demand for this sort of information ...

# create some Tkinter canvas shapes
# show their names when clicked

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

def clicked(event):
    """display the clicked widgets's name"""
    root.title( shape_dict[cv.find_withtag('current')[0]] )

def create_shapes():
    """function keeps local dictionary vars() clean"""
    line1 = cv.create_line(0, 10, 200, 10, fill='red', width=5, tags='click')
    line2 = cv.create_line(0, 30, 200, 30, fill='blue', width=5, tags='click')
    line3 = cv.create_line(0, 50, 200, 50, fill='green', width=5, tags='click')
    rect1 = cv.create_rectangle(50, 70, 150, 85, fill='magenta', tags='click')
    oval1 = cv.create_oval(10, 70, 40, 85, fill='red', tags='click')
    print(oval1, cv.type(oval1))  # test --> (5, 'oval')
    # reverse local dictionary vars()
    # keys are now numbered in order of creation, values are the names
    return dict((v, k) for (k, v) in vars().items())
    

root = tk.Tk()

cv = tk.Canvas(root, width=200, height=100, bg='white')
cv.pack()

shape_dict = create_shapes()
# test
print(shape_dict)

# left mouse click = '<1>'
cv.tag_bind('click', '<1>', clicked)

root.mainloop()

Edited by vegaseat: test

2

I use PyGTK on Linux. I'm no expert with it as i mainly use GTK+ through it's C interface but I did write a simple wrapper file that initializes the main window as I dislike having to write the same code over and over again that might be useful to someone else.

from gtk import *
import pygtk; pygtk.require('2.0')

class GtkApp_Toplevel:
    """
    This class creates a standard toplevel GtkWindow
    widget with default handlers connected to delete_event
    and destroy signals, respectively. To use, simply derive
    new classes from this base and extend your new classes
    constructor by calling back to the __init__ here. Example:

    class MyGUI(GtkApp_Toplevel):
        def __init__(this):
            GtkApp_Toplevel.__init__(this)
            ...custom extension code...

    if __name__ == "__main__":
        Obj = MyGUI().main()

    Attributes defined: this.window
    """
    def delete_event(this, widget, event, data = None):
        """
        By returning False, we ask that GTK+ emit the destroy signal.
        Override this function in a derived class to change this behavior.
        """
        return False

    def destroy(this, widget, data = None):
        main_quit()

    def main(this):
        """
        Control of our application ends here. GTK+ will sleep in its main
        event loop waiting for events to occur. e.g. mouse clicks
        """
        main()

    def __init__(this):
        this.window = Window(WINDOW_TOPLEVEL)
        this.window.connect("delete_event", this.delete_event)
        this.window.connect("destroy", this.destroy)

It makes things easier for me anyway because the entire program is initialized and set up the way I want with a single call to this base class constructor which allows me to immediately start setting attributes of the window instead of dealing with the universal tasks of window creation and signal setting.

2

It is better to keep to Python convention for first parameter name self instead of this.

2

Create a Tkinter image button that easily toggles between two images ...

# create Tkinter image objects and display them ...
# create all image objects in __main__ to be persistent
# Note: if you create the image object and tie it to a
# function scope variable, then when the function is done
# the image will be garbage collected

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

def toggle_image(event):
    """toggle between the two button images"""
    print(button['image'], type(button['image']))  # test
    if button['image'] == 'pyimage2':
        button['image'] = image1
    else:
        button['image'] = image2

root = tk.Tk()
root.title("Click the image button")

# pick images you have in the working directory
# or give full path
image1 = tk.PhotoImage(file='Btn_next.gif')
image2 = tk.PhotoImage(file='Btn_prev.gif')

# create a button to display the image
button = tk.Button(root, image=image1, relief='raised', bd=10)
button.grid(row=1, column=1, padx=100, pady=10)
# bind left mouse click
button.bind('<Button-1>', toggle_image)  

root.mainloop()

Edited by vegaseat: w

Attachments Btn_next.gif 3.67 KB Btn_prev.gif 3.7 KB
1

For the casual developer of software working with PyQT had always a certain worry about licensing associated with it. That has now been eliminated with the PySide LGPL version of PyQT.

The GNU Lesser General Public License (LGPL) is a free software license published by the Free Software Foundation (FSF).

Here is an example of PySide code (looks much like PyQT code) ...

# PySide is the official LGPL-licensed version of PyQT
# I downloaded and used the Windows self-extracting installer
# PySide-1.0.0qt472.win32-py2.7.exe
# from: http://developer.qt.nokia.com/wiki/PySide_Binaries_Windows
# tested with pyside472 and Python27
 
from PySide.QtCore import *
from PySide.QtGui import *
 
class MyFrame(QWidget):
    def __init__(self, parent=None):
        # create the frame/window (this will be instance self)
        QWidget.__init__(self, parent)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 150, 300, 50)
        self.setWindowTitle('button connected to a label')

        # create a button
        self.button = QPushButton("Click me")
        # when clicked connect button to method action()
        self.button.clicked.connect(self.action)

        # create 2 Qt labels
        self.label1 = QLabel()
        self.label2 = QLabel()

        # use grid layout to position the 3 widgets
        grid = QGridLayout()
        # addWidget(QWidget, row, column, rowSpan=1, columnSpan=1)
        grid.addWidget(self.button, 0, 0)
        grid.addWidget(self.label1, 1, 0)
        grid.addWidget(self.label2, 2, 0)

        self.setLayout(grid)
        
    def action(self):
        s = "You clicked the button!"
        self.label1.setText(s)
        # for optional color use HTML code
        html = "<font color=red>You clicked the button!</font>"
        self.label2.setText(html)
        # optional wave sound
        # sound file (.wav files only) should be in working folder
        # or give full file path 
        QSound.play("boing.wav")
 
# create the Qt Application
app = QApplication([])

frame = MyFrame()
frame.show()

# run the main Qt event loop
app.exec_()

Edited by vegaseat: sound

1

The Tix (Tk Interface Extension) module provides an additional rich set of widgets. to the Tkinter GUI toolkit. Here is one example for you ...

# Tix_ScrolledListBox2.py
# Tkinter extension module tix comes with Python27 and Python31+
# explore the tix.ScrolledListBox
# vertical or horizontal scroll bars appear as needed (automatic)
# for more info check ...
# http://docs.python.org/library/tix.html  
# http://doc.astro-wise.org/Tix.html
# actually Tix imports Tkinter so you can call it all tix

try:
    import Tix as tix  # Python27
except ImportError:
    import tkinter.tix as tix  # Python31 and higher

def get_list(event=None):
    """
    function to read the listbox selection
    and put the result in a text/edit widget
    """
    # get selected line index
    index = slbox.listbox.curselection()[0]
    # get the line's text
    # optionally add newline char to end
    seltext = slbox.listbox.get(index) + '\n'
    # put the selected text in the edit field
    edit.insert('end', seltext)
    edit.focus

root = tix.Tk()
root.title('tix.ScrolledListBox (click on a name)')

# create a text/edit widget (width/height in characters)
edit = tix.Text(root, width=35, height=15)
edit.pack(side='left')

# create scrolled listbox
slbox = tix.ScrolledListBox(root, scrollbar='auto')
# background color of listbox part
slbox.listbox.configure(bg='yellow')
slbox.pack(fill='both', expand=1)

friend_list = [
'Steve', 'Tom', 'Mark', 'Adam', 'Alison', 'Ethel',
'Barb', 'Tiny', 'Tim', 'Pete', 'Sue', 'Zack', 'Fred',
'Lars', 'Detlev', 'Akiko', 'Heidrun', 'Udo',
'supercalifragilisticexpialidocious']

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

root.mainloop()
2

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)

This is the best set of tutorials on GUI programming in Python that i have ever seen--whether free/paid or web/print.

2

Introducing color to your PyQt widget ...

# testing the PyQT GUI toolkit
# use setStyleSheet(format_string)
# to set the background color of the specified widget
# also use the newer style of signal/slot connect
# tested with PyQT483 and Python27/Python32  vegaseat

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("change background color")

        # create a widget to display the color in
        self.display = QWidget(self)
        self.display.setGeometry(0, 0, 50, 50)
        # takes colors in "#RRGGBB" format
        # initial color is white
        self.display.setStyleSheet("QWidget { background-color: #FFFFFF }") 

        btn_red = QPushButton("red")
        # bind the button click to a function reference
        # newer style ...
        btn_red.clicked.connect(self.change_color)

        btn_green = QPushButton("green")
        # bind the button click to a function reference
        # newer style ...
        btn_green.clicked.connect(self.change_color)        

        btn_blue = QPushButton("blue")
        # bind the button click to a function reference
        # newer style ...
        btn_blue.clicked.connect(self.change_color)        

        # use a grid layout for the widgets
        grid = QGridLayout()
        # addWidget(widget, row, column, rowSpan=1, columnSpan=1)
        # widget display spans 3 rows
        grid.addWidget(self.display, 0, 1, 3, 1)
        grid.addWidget(btn_red, 0, 0)
        grid.addWidget(btn_green, 1, 0)
        grid.addWidget(btn_blue, 2, 0)

        self.setLayout(grid)

    def change_color(self):
        button = self.sender()
        # button texts are the dictionary keys
        color_key = str(button.text())
        # takes colors in '#RRGGBB' format
        colors = {'red': '#FF0000', 'green': '#00FF00', 'blue':  '#0000FF'}
        sf = "QWidget { background-color: %s }" % colors[color_key]
        self.display.setStyleSheet(sf)    


app =  QApplication([])
form = MyForm()
form.show()
app.exec_()

Edited by vegaseat: Python27 needs str()

2

Folks are using Tkinter's expansion modules. A nice example of the tix.ComboBox came up in the forum. Here is a modified version of this example ...

# explore the tix.ComboBox()
# the Tix (Tk Interface Extension) module comes with the
# Python27 and Python31+ installation

try:
    import Tix as tix  # Python27
except ImportError:
    import tkinter.tix as tix  # Python31 and higher

def selected(event=None):
    color = combo.entry.get()
    root.title("value is %s" % color)
    root['bg'] = color


root = tix.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (330, 80, 200, 150))
root.title("tix.ComboBox()")

# apply a label and make the combo entry editable
combo = tix.ComboBox(root, label='Color:', editable=1)
combo.pack(side='left', padx=10, pady=10)

# load the combobox listbox
color_list = ['red', 'green', 'blue', 'yellow', 'white', 'magenta']
for item in color_list:
    combo.insert('end', item)

# set the initial color
# make combobox editable to do this
combo.entry.insert(0, 'red')
# start with the color in the entry
selected()

# left mouse click on a list item to display selection
combo.slistbox.listbox.bind('<ButtonRelease-1>', selected)

root.mainloop()

Actually, the label within the combo box is rather neat.

Edited by vegaseat: label

Votes + Comments
tix is interesting
1

Here we use the module pygame, but do not create a GUI frame ...

# play MP3 music files using Python module pygame
# pygame is free from: http://www.pygame.org
# or latest updates from:
# http://www.lfd.uci.edu/~gohlke/pythonlibs/
# tested with Windows7, Python3.2 and PyGame1.9.2 by vegaseat
# (does not create a GUI frame in this case)

import pygame as pg

def play_music(music_file, volume=0.8):
    """
    stream music with mixer.music module in blocking manner
    this will stream the sound from disk while playing
    """
    # set up the mixer
    freq = 44100     # audio CD quality
    bitsize = -16    # unsigned 16 bit
    channels = 2     # 1 is mono, 2 is stereo
    buffer = 2048    # number of samples (experiment for good sound)
    pg.mixer.init(freq, bitsize, channels, buffer)

    # set volume from 0 to 1.0
    pg.mixer.music.set_volume(volume)
    clock = pg.time.Clock()
    try:
        pg.mixer.music.load(music_file)
        print( "Playing file %s" % music_file )
    except pg.error:
        print("File %s not found! (%s)" % \
            (music_file, pg.get_error()))
        return
    pg.mixer.music.play()
    while pg.mixer.music.get_busy():
        # check if playback has finished
        clock.tick(30)
        # msecs since init, potential use for progress bar
        print(pg.time.get_ticks())

# pick MP3 music files you have in the working folder
# otherwise use the full file path
#music_file = "Hot80s.mp3"   # 0.5MB
music_file = "Beat_it.mp3"  # 6.1MB demo

# highest volume is 1.0
volume = 1.0
play_music(music_file, volume)

Have fun with this code!

1

A scrollable list box is handy if you want to display a text with many lines ...

# load a Tkinter listbox with the lyrics of '99 bottles of beer'
# tested with Python27 and Python32  by  vegaseat

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

# the main window
root = tk.Tk()
root.title("99 BoB lyrics")

# create a listbox (height, width in characters)
listbox = tk.Listbox(root, height=30, width=32, bg='yellow')
listbox.grid(row=0, column=0)

# create a vertical scrollbar to the right of the listbox
yscroll = tk.Scrollbar(command=listbox.yview, orient='vertical')
yscroll.grid(row=0, column=1, sticky='ns')
listbox.configure(yscrollcommand=yscroll.set)

# create the lyrics and load the listbox
bottle = "%s bottle"
beer = "s of beer on the wall!"
take = "Take one down, pass it around,"
for k in range(99, 0, -1):
    # an exercise in slicing
    s1 = bottle % k + beer[k==1:]
    s2 = (bottle % k + beer[k==1:])[:-13] + "!"
    s3 = bottle % (k-1 or "No")
    s4 = beer[k==2:-1] + "!"
    listbox.insert('end', s1)
    listbox.insert('end', s2)
    listbox.insert('end', take)
    listbox.insert('end', s3+s4)
    listbox.insert('end', " ")

root.mainloop()

Enjoy!

Edited by vegaseat: 99bob

2

The PySide GUI toolkit has PyQt under the hood and is public. Here is an example I played with on my Windows machine:

# ps_colordialog1.py
# exploring PySide's QColorDialog widget
# go to http://www.pyside.org/
# and download the proper binary installer from their downloads
# for Windows and Python27 I used:
# PySide-1.0.1qt472.win32-py2.7(2).exe

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

class ColorDialog(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setGeometry(300, 300, 250, 180)
        self.setWindowTitle('ColorDialog')
        # use initial color black (r, g, b) = (0, 0, 0)
        # color.name() would be string #RRGGBB = #000000
        color = QColor(0, 0, 0)

        self.button = QPushButton('Dialog', self)
        self.button.setFocusPolicy(Qt.NoFocus)
        # position the button absolute (x, y)
        self.button.move(20, 20)
        # bind the button click
        self.button.clicked.connect(self.showDialog)
        self.setFocus()

        self.widget = QLabel(self)
        # use style sheet to set background color
        # color.name() is a string in #RRGGBB format
        self.style_str = "QLabel {background-color: %s}"
        self.widget.setStyleSheet(self.style_str % color.name())
        self.widget.setGeometry(130, 22, 100, 100)

    def showDialog(self):
        """
        get the color from QColorDialog and
        use it to set a widget's background color
        """
        color = QColorDialog.getColor()
        print(color.name())  # optional test
        self.widget.setStyleSheet(self.style_str % color.name())


app = QApplication([])
cd = ColorDialog()
cd.show()
app.exec_()

I leaned on vegaseat's pyqt example at:
http://www.daniweb.com/software-development/python/threads/191210/1525722#post1525722

Edited by HiHe: vega ref

Votes + Comments
good info
nice example
2

Ironpython 2.7 (Python27 based) is out and is greatly improved (IMHO). Let's revisit the '99 Bottles of Beer' song lyrics written in ironpython code ...

# ip_ListBox_99BoB.py
# add '99 bottles of beer' lyrics to a .NET list box
# simplified code using some defaults
# tested with IronPython 2.7 by  vegaseat

import clr

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

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

class BeerSong(Form):
    def __init__(self):
        # width, height of form
        self.ClientSize = System.Drawing.Size(220, 326)
        self.Text = '99 BoB lyrics'
        # create the listbox and fill the form (self) with it
        box = ListBox()
        # light yellow
        box.BackColor = System.Drawing.Color.FromArgb(255, 255, 224)
        box.Dock = DockStyle.Fill
        self.Controls.Add(box)

        # move the lyrics into ArrayList then transfer to the box
        array = ArrayList()
        bottle = "%s bottle"
        beer = "s of beer on the wall!"
        take = "Take one down, pass it around,"
        for k in range(99, 0, -1):
            # an exercise in slicing
            s1 = bottle % k + beer[k==1:]
            s2 = (bottle % k + beer[k==1:])[:-13] + "!"
            s3 = bottle % (k-1 or "No")
            s4 = beer[k==2:-1] + "!"
            array.Add(s1)
            array.Add(s2)
            array.Add(take)
            array.Add(s3+s4)
            array.Add(" ")
        box.DataSource = array


Application.Run(BeerSong())

The nice thing about ironpython is that you can create a Windows executable with ease. Here is a short code to do just that with the above script file ...

# compile_ip1.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
#
# needs IronPython 2.7

import subprocess

# the ironpython script file you want to compile ...
ip_scriptfile = "ip_ListBox_99BoB.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])

I got the following files:
ip_ListBox_99BoB.exe (3kb)
ip_ListBox_99BoB.dll (13kb)

IronPython 2.7 needs the MS .NET Framework version 4.0
You can download the setup exe free from Microsoft

2

If you are not in Microsoft bandwagon, I noticed interesting point in the web site:

Mac OS & Linux desktop & server apps

IronPython runs on Mono, a cross platform, open source .NET framework, enables IronPython to be used on Linux, Mac OS, and BSD systems.
Latest Mono version

Votes + Comments
you did not test it out
1

A little more IronPython. Here I have used the SharpDevelop4 IDE and its Frame-builder to create the bulk of the IronPython code. A few extra lines of code have been added to make the program run without the use of the SharpDevelop environment ...

# a colorful IronPython 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")

# created with the SharDevelop4 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
        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
        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
        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
        sf = "Hello %s you are %s years old"
        s = sf % (self._textBox1.Text, self._textBox2.Text)
        self._textBox3.Text = s

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

It would be easy to process some more complex data, rather than the sample name age stuff.

The free SharpDevelop4 IDE and its Frame-builder work similar to the famous MS Studio product and is a charm to use.

Again, if you saved the above code as ip_DataEntry1.py, you can compile it to a Windows executable .exe stup and a .dll with this short program ...

# compile_ip1.py
# 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 file you want to compile
#
# needs IronPython 2.7

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])

It gives files
ip_DataEntry1.exe
and
ip_DataEntry1.dll
having a fairly small size of 3kb and 32kb on my Windows7 machine.

Edited by vegaseat: compile

Attachments ip_DateEntry1.jpg 19.98 KB
0

The Python module pygame is a GUI for games. In this case we use OOP. Let's look at some simple drawing code:

# exploring the Python module pygame
# pygame free from: http://www.pygame.org/
# or: http://www.lfd.uci.edu/~gohlke/pythonlibs/
# use pygame sprites group to fill a screen with colorful shapes

import pygame as pg
import random

class Square(pg.sprite.Sprite):
    """
    create a square sprite with a random position and given color
    also needs screen (via pg.display.set_mode)
    """
    def __init__(self, screen, color):
        pg.sprite.Sprite.__init__(self)  # this will be self
        # the square
        self.image = pg.Surface((50, 50))
        self.image.fill(color)
        # random position
        self.rect = self.image.get_rect()
        self.rect.centerx = random.randrange(0, screen.get_width())
        self.rect.centery = random.randrange(0, screen.get_height())


def test():
    """testing the class Square"""
    pg.init()
    # create the pg window, give it a caption and bg color
    screen = pg.display.set_mode((640, 480))
    pg.display.set_caption(" colorful squares all over")
    background = pg.Surface(screen.get_size())
    background.fill(pg.color.Color('white'))
    screen.blit(background, (0, 0))

    # create a list of colored square sprite objects
    squares = []
    # go through the pg.color.THECOLORS dictionary of color names
    for color_name in sorted(pg.color.THECOLORS):
        print(color_name)  # test
        squares.append(Square(screen, pg.color.Color(color_name)))
    # pack all your sprites into a group container
    all_sprites = pg.sprite.Group(squares)

    # the pg event loop ...
    while True:
        for event in pg.event.get():
            # quit when window corner x is clicked
            if event.type == pg.QUIT:
                raise SystemExit
        # draw and show the group of sprites
        all_sprites.draw(screen)
        pg.display.flip()

# allows class Square to be a module
if __name__ == "__main__":
    test()
1

The Python module pygame is a GUI for games, animated or otherwise. Here is some simple animated drawing code:

# exploring the Python module pygame
# pygame free from: http://www.pygame.org/
# or: http://www.lfd.uci.edu/~gohlke/pythonlibs/
# bubble circles up the screen

import pygame as pg
import random

def draw(screen, background, width, height):
    # create a few random values
    x = random.randint(10, width)
    y = random.randint(100, height)
    radius = random.randint(20, 50)
    # random (r, g, b) color, avoid black (0, 0, 0)
    r = random.randint(20, 255)
    g = random.randint(20, 255)
    b = random.randint(20, 255)
    # bubble up until circle center (x, y) reaches top
    while y > 0:
        background.fill(pg.color.Color('black'))
        # draw.circle(Surface, color, pos, radius, width)
        # width of 0 (default) fills the circle
        pg.draw.circle(background, (r, g, b), (x, y), radius, 3)
        y -= 1
        # put the circle on the screen
        screen.blit(background, (0, 0))
        # update the screen
        pg.display.flip()

def main():
    pg.init()
    # create the pg window, give it a caption and bg color
    width = 680
    height = 460
    screen = pg.display.set_mode((width, height))
    pg.display.set_caption(' random bubbles')
    background = pg.Surface(screen.get_size())
    background.fill(pg.color.Color('black'))
    clock = pg.time.Clock()
    # the pg event loop ...
    while True:
        # quit when window corner x is clicked
        # there is a small delay
        for event in pg.event.get():
            if event.type == pg.QUIT:
                raise SystemExit
        draw(screen, background, width, height)
        # use a frame rate of 30 to avoid flickering
        clock.tick(30)

if __name__ == "__main__":
    main()

Edited by sneekula: n/a

Votes + Comments
nice example
2

Module cx_Freeze right now is the only 'package to Windows executable compiler' for programs written with Python32. I tried my luck successfully with a PyQT GUI code using this setup program:

"""
pqt_setup.exe

Using cx_Freeze with Python32 to package a PyQT GUI toolkit
program to an executable file (.exe in Windows OS).

Put this setup program and your PyQT program file into the same
directory.  Change the filename in this setup program and also edit
name, version and description in setup() if you so desire.

It is important to use command argument 'build'
Run the build process by running the command:
python pqt_setup.py build

A directory 'build' is created with a subdirectory 'exe.win32-3.2'
containing all the files needed for distribution including the
.exe file named after the PyQT program file.

The total distribution has a size of about 20.8 MB

I used:
http://cx-freeze.sourceforge.net/
cx_Freeze-4.2.3.win32-py3.2.msi
"""

import sys

from cx_Freeze import setup, Executable

# change the filename to your program file
filename = "pqt_BarChart1.py"

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    name = "BarChart",
    version = "1.0",
    description = "cx_Freeze PyQt4 script",
    executables = [Executable(filename, base=base)])
Votes + Comments
great code
3

Thanks for the cx_Freeze setup example. The version for Python32 has seen much improvement. The older Python31 version used to make you jump through hoops with tkinter GUI programs, now it's easy. Here is a mildly improved version of Lardmeister's code using a tkinter code example, simply run it once you have supplied the file name ...

"""
tk_setup2.exe

Using cx_Freeze with Python32 to package a Tkinter GUI toolkit
program to an executable file (.exe in Windows OS).  Module
cx_Freeze also is available for Unix systems.

Put this setup program and your Tkinter program file into the same
directory.  Change the filename in this setup program and also edit
name, version and description in setup() if you so desire.

A directory 'build' is created with a subdirectory 'exe.win32-3.2'
containing all the files needed for distribution including the
.exe file named after the Tkinter program file.

The total distribution has a size of about 13.5 MB

The Python32 version works much better now with tkinter code.

I used:
http://cx-freeze.sourceforge.net/
cx_Freeze-4.2.3.win32-py3.2.msi
"""

import sys
from cx_Freeze import setup, Executable

sys.argv.append("build")  # replaces commandline arg 'build'

# change the filename to your program file
filename = "tk_calculator2.py"

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(
    name = "Calculator2",
    version = "1.0",
    description = "cx_Freeze Tkinter script",
    executables = [Executable(filename, base=base)])
Votes + Comments
just what I needed
2

The Python module pymunk is a wrapper for the 2D-Physics module Chipmunk, together with module pygame you can easily make animated physics programs ...

# Python module pygame works well with
# module pymunk (Python wrapper for 2d physics library Chipmunk)
# from:
# http://code.google.com/p/pymunk/
# in this case I downloaded Windows installer
# pymunk-1.0.0.win32.exe
# this falling ball example modified from the site ...
# http://code.google.com/p/pymunk/wiki/SlideAndPinJointsExample
# tested with Python27 and Python32 by vegaseat
#
# to make pymunk work with Python32
# change line 60 of site-packages/pymunk/package __init__.py
# from
# chipmunk_version = cp.cpVersionString.value + "r428"
# to
# chipmunk_version = cp.cpVersionString.value + "r428".encode("utf8")

import sys
import random
import pygame as pg
import pymunk as pm
import math

def to_pygame(p):
    """Small hack to convert pymunk to pygame coordinates"""
    return int(p.x), int(-p.y+600)

def add_ball(space):
    mass = 1
    radius = 14
    inertia = pm.moment_for_circle(mass, 0, radius) # 1
    body = pm.Body(mass, inertia) # 2
    x = random.randint(120,380)
    body.position = x, 550 # 3
    shape = pm.Circle(body, radius) # 4
    space.add(body, shape) # 5
    return shape    

def draw_ball(screen, ball):
    p = int(ball.body.position.x), 600-int(ball.body.position.y)
    blue = (0, 0, 255)
    pg.draw.circle(screen, blue, p, int(ball.radius), 2)    

def add_static_L(space):
    """an L shaped shelf"""
    body = pm.Body(pm.inf, pm.inf)  # 1
    body.position = (300,300)    
    l1 = pm.Segment(body, (-150, 0), (255.0, 0.0), 5.0)  # 2
    l2 = pm.Segment(body, (-150.0, 0), (-150.0, 50.0), 5.0)
    space.add_static(l1, l2) # 3
    return l1,l2

def draw_lines(screen, lines):
    """draw an L shaped shelf"""
    for line in lines:
        body = line.body
        pv1 = body.position + line.a.rotated(body.angle) # 1
        pv2 = body.position + line.b.rotated(body.angle)
        p1 = to_pygame(pv1) # 2
        p2 = to_pygame(pv2)
        red = (255, 0, 0)
        pg.draw.lines(screen, red, False, [p1,p2])

def main():
    pg.init()
    # (color tuple (r, g, b)
    white = (255, 255, 255)  
    screen = pg.display.set_mode((700, 600))
    pg.display.set_caption("Balls falling on an L shaped shelf")
    clock = pg.time.Clock()
    running = True
    
    pm.init_pymunk()
    space = pm.Space()
    space.gravity = (0.0, -900.0)
    
    lines = add_static_L(space)
    balls = []
    
    ticks_to_next_ball = 10
    # to exit user clicks on windows corner x or uses ecape key
    while running:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False
            elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
                running = False
        
        ticks_to_next_ball -= 1
        if ticks_to_next_ball <= 0:
            ticks_to_next_ball = 25
            ball_shape = add_ball(space)
            balls.append(ball_shape)

        screen.fill(white)
        
        for ball in balls:
            draw_ball(screen, ball)
        
        draw_lines(screen, lines)
        
        space.step(1/50.0)
        
        pg.display.flip()
        clock.tick(50)
        
if __name__ == '__main__':
    sys.exit(main())

Edited by vegaseat: pymunk for Python32 note

Votes + Comments
neat physics
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.