Python GUI Programming

 
1
 

Hey Henri, very nice widget tester for Pyside (for PyQt change imports). I just wanted to know if the list box would add a scroll-bar automatically for a long list. It does ...

# test PySide widgets
# load a list box

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

app = QApplication([])

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

# Fnames.txt is a file of names, one each line
with open("Fnames.txt", "r") as fin:
    # remove trailing newline characters
    name_list = [name.strip() for name in fin]

# automatically adds vertical scrollbar for this long list
listbox = QListWidget()
listbox.addItems(name_list)

listbox.show()

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

app.exec_()
Attachments FNames.txt (5.59 KB)
Abby
Abigail
Adela
Adele
Adelheide
Adrian
Adrianna
Adrienne
Agatha
Agnes
Akiko
Akina
Alana
Alea
Alena
Alessandra
Alexa
Alexandra
Alexia
Alexis
Alicia
Alice
Alissa
Alison
Alley
Allie
Allison
Allyssa
Alva
Amanda
Amber
Amie
Amy
Anabel
Anastasia
Andrea
Aneke
Anke
Annette
Anita
Anja
Angela
Ann
Anna
Anne
Annette
Annie
Aphrodite
April
Arden
Aria
Arial
Arianna
Ariel
Arlinda
Ashley
Astrid
Athena
Audra
Audrey
Auria
Autumn
Ava
Avis
Azizi
Azuma
Babett
Barb
Barbara
Barbie
Baylee
Bea
Beate
Beatrice
Becky
Belinda
Bella
Bernadette
Beth
Betia
Betty
Bia
Bianca
Billiejo
Birgit
Blair
Blake
Bobbie
Bonnie
Brenda
Briana
Bridgett
Britt
Brittany
Brittney
Brooke
Caitlin
Callie
Callista
Camille
Candice
Candy
Cara
Carla
Carmela
Carmen
Carmine
Carolina
Carly
Carol
Caroline
Carolyn
Carra
Carrie
Carissa
Carson
Casey
Cassandra
Cassie
Cathy
Celia
Celina
Celeste
Cindy
Chantelle
Charlene
Charlotte
Chasey
Chelsea
Chastity
Cher
Cherie
Cheryl
Cheyen
Cheyenne
Chihiro
Chloe
Chrissy
Christa
Christina
Christine
Claire
Clarice
Clarissa
Claudia
Cleo
Colleen
Collette
Connie
Coreen
Corinna
Corky
Corrie
Corrine
Cory
Crystal
Cyndi
Cynthia
Daisy
Dagmar
Dale
Dana
Daniela
Danielle
Dallas
Daphne
Darcy
Darla
Dawn
Debbie
Debora
Debra
Dee
Deena
Deidra
Deidre
Deleen
Delila
Demi
Demitra
Denise
Desiree
Devine
Devon
Diana
Dianne
Dixie
Dolly
Donita
Donna
Doris
Dorothy
Dotty
Drew
Druna
Eden
Edina
Edith
Edna
Eileen
Elaine
Elana
Elena
Ellen
Elli
Ellina
Elke
Eloise
Elona
Emma
Emillia
Emily
Erin
Erika
Esmeralda
Ester
Euphemia
Eva
Eve
Evelyn
Evgenia
Evgina
Faith
Fawn
Faye
Febe
Felicia
Fila
Fran
Francesca
Frankie
Frannie
Frieda
Gabriella
Gabrielle
Gaby
Gail
Gale
Geneve
Georgia
Gerda
Gilda
Gillian
Gin
Gina
Ginger
Gisela
Gita
Gitte
Gloria
Grace
Gretel
Gwen
Haley
Halle
Hanna
Hannah
Hattie
Haley
Hayley
Hazel
Heather
Heidi
Heidrun
Heika
Heike
Helen
Helena
Helga
Hilda
Hilde
Hildegard
Hisako
Holly
Ilse
Indigo
Inga
Inge
Ingeborg
Ingrid
Irena
Irene
Irmgard
Isabel
Isolde
Ivana
Iveta
Ivy
Jackie
Jacqueline
Jade
Jamie
Jana
Jane
Janessa
Janice
Janie
Janine
Janis
Janet
Jannay
Jasmine
Jayda
Jean
Jennifer
Jenna
Jenny
Jerry
Jess
Jessica
Jessie
Jessy
Jette
Jezebel
Jill
Jimmiann
Joanne
Jocelyn
Joelle
Johanna
Jodie
Jody
Joli
Joni
Jonnie
Jordan
Josie
Joy
Joyce
Juana
Judy
Julia
Julie
Kalin
Kalissa
Kanami
Kandace
Karen
Karie
Karin
Karina
Karita
Karla
Karni
Kassia
Kassy
Katama
Kate
Katelyn
Kathrin
Kathy
Katia
Katja
Katie
Kay
Keiko
Kelly
Kelsey
Kerry
Keyla
Kia
Kim
Kimberly
Kintra
Kira
Kirsten
Kitty
Krista
Kristen
Kristina
Ksenia
Kyndal
Lace
Laika
Lana
Lara
Laura
Laverne
Layla
Lea
Leah
Lee
Leigh
Lena
Lenka
Lenna
Lenoshka
Lesa
Leslie
Libby
Liddy
Liese
Liesel
Lila
Lillian
Lilly
Lina
Linda
Lindsey
Linet
Lisa
Lissie
Liv
Liz
Liza
Lola
Lolita
Lonnie
Lorain
Lora
Lore
Loretta
Lori
Lorey
Lorna
Louise
Lucie
Lucinda
Lucy
Ludmila
Lulu
Lydia
Lyndsey
Lyndell
Lynette
Lynn
Mable
Macie
Madeleine
Madeline
Maddie
Madge
Madlyn
Mae
Maggy
Maia
Malka
Malory
Mandy
Manu
Mara
Marcee
Marcella
Marcia
Marcy
Mareik
Marika
Mariko
Margot
Margret
Maria
Mariane
Marie
Marijam
Marika
Marilyn
Marian
Marianne
Marina
Maris
Mariska
Marissa
Marla
Marlena
Marlene
Marlise
Marsha
Marta
Martha
Martina
Marly
Mary
Maryann
Masha
Mason
Matilda
Mattie
Maui
Maura
Megan
Melanie
Melany
Melilla
Melissa
Melody
Mena
Mercedes
Meredith
Meris
Mesina
Mette
Miana
Micah
Michelle
Mickey
Mickie
Mila
Millie
Mindy
Mira
Miranda
Mirja
Mirka
Misha
Mishka
Missy
Misty
Mita
Melanie
Melinda
Molly
Monica
Monika
Monique
Morgan
Myra
Myril
Nadia
Nadya
Nancy
Naomi
Natalia
Nataly
Natanya
Nantasha
Neriah
Nicole
Nicki
Nikkita
Nina
Nisha
Nishi
Noleen
Nora
Odell
Olga
Olive
Olivia
Opal
Paige
Paisley
Paloma
Pam
Pamela
Paola
Patricia
Patt
Pattie
Parsy
Paula
Pauline
Peggy
Pennie
Persia
Petra
Petrinka
Phoebe
Phyllis
Pia
Poppy
Priscilla
Raine
Ramona
Rana
Randy
Rachel
Raquel
Rayna
Reba
Rebecca
Regan
Regina
Rena
Renate
Renee
Rhonda
Ricki
Ricky
Rina
Rita
Rennie
Rhonda
Robby
Roberta
Robin
Rochelle
Romina
Rory
Rosalie
Rose
Rosie
Roxie
Ruby
Ruth
Sabine
Sabrina
Sadie
Sage
Sahar
Sally
Samantha
Sameerah
Sandra
Sandy
Sarah
Sasha
Savanna
Sayaka
Scarlett
Sedta
Selia
Selina
Selma
Seneca
Serena
Serina
Shalini
Shana
Shane
Shannon
Shareen
Sharia
Sharon
Sharry
Shay
Shelby
Shelly
Sheila
Sheralee
Shereen
Sherrie
Sherry
Sheryl
Shirley
Shizuka
Shoshonna
Sidney
Sierra
Silke
Silvia
Silvie
Simone
Sina
Sittia
Skyler
Sofia
Sonja
Sophia
Sophie
Stacey
Stacy
Star
Stella
Stephanie
Stephie
Stevie
Sue
Summer
Sunny
Surrey
Susan
Susanna
Susie
Suzette
Svenja
Sybille
Sydney
Sylvia
Sylvie
Svetlana
Tabatha
Tabitha
Tabby
Tamara
Tammy
Tanya
Tara
Tatum
Tatyana
Taylor
Teresa
Teri
Terry
Tess
Tessa
Tessie
Thelma
Theresa
Tiffany
Tina
Tineke
Tonie
Toni
Tonya
Tori
Tracy
Trina
Trine
Trish
Trisha
Trissa
Trixie
Tyler
Ulla
Ulrike
Unne
Ursel
Ursula
Uschi
Ute
Val
Valerie
Vanessa
Velvet
Venice
Venus
Vera
Verena
Verginia
Veronica
Veruschka
Vicki
Vicky
Victoria
Viola
Violet
Vivian
Vlada
Wanda
Wendy
Whitney
Wilda
Wilma
Xena
Xenia
Xuan
Yahni
Yana
Yolanda
Yoriko
Youko
Yulia
Yvette
Zaila
Zara
Zelda
Zena
Zia
Zina
Zoe
Zoey
 
2
 

Some more explorations with Jython ...

""" view an image with Jython using the Java swing GUI toolkit get the image from a webpage URL or any image file tested with jython2.5.2 by vegaseat """ from pawt import swing from java import net def view_image(image): frame = swing.JFrame("Jython Image Viewer") # allows frame corner x to exit properly frame.defaultCloseOperation = swing.JFrame.EXIT_ON_CLOSE frame.visible = True frame.setSize(500, 688) # show the image in a label frame.getContentPane().add(swing.JLabel(swing.ImageIcon(image))) frame.show() # get a URL based image from the internet # the url was very long so I split it in half part1 = "http://uploads.neatorama.com/wp-content/"
part2 = "uploads/2011/05/cogtrain-500x688.jpg"
url = part1 + part2
# now that is sweet ...
image = net.URL(url)
view_image(image)
 
1
 

I coded the above Jython Image Viewer program with Python27 and PyQt, a little bit more complex ...

""" view an image with Python using the PyQt GUI toolkit get the image from a webpage URL or any image file note: urllib2 has changed in Python3 tested with Python27 and PyQt48 """ from PyQt4.QtCore import * from PyQt4.QtGui import * # Python2 import urllib2 app = QApplication([]) # create the window/frame win = QWidget() win.setGeometry(100, 50, 500, 688) win.setWindowTitle("PyQt Image Viewer") # get a URL based image from the internet # the url was very long so I split it in half part1 = "http://uploads.neatorama.com/wp-content/"
part2 = "uploads/2011/05/cogtrain-500x688.jpg"
url = part1 + part2
picture = urllib2.build_opener().open(url).read()

# save the image as a file
fname = "cogtrain-500x688.jpg"
fout = open(fname, "wb")
fout.write(picture)
fout.close()

# load the picture back in a form PyQt can process
image = QPixmap(fname)

# use a label to display the image in
label = QLabel(win)
label.setPixmap(image)

win.show()

app.exec_()
 
3
 

To allow for comparisons, here is the URL image viewer using Tkinter and PIL ...

""" view an image with Python using the Tkinter GUI toolkit get the image from a webpage URL note: urllib2 has changed in Python3 tested with Python 2.7 and PIL 1.1.7 """ import Tkinter as tk from PIL import ImageTk # Python2 import urllib2 root = tk.Tk() root.title("Tkinter URL Image Viewer") # get a URL based image from the internet # the url was very long so I split it in half part1 = "http://uploads.neatorama.com/wp-content/"
part2 = "uploads/2011/05/cogtrain-500x688.jpg"
url = part1 + part2
picture = urllib2.build_opener().open(url).read()

# use PIL to convert to a format Tkinter can handle
image_tk = ImageTk.PhotoImage(data=picture)

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

root.mainloop()
Comments
great code, thank you
 
2
 

The popular plotting module matplotlib works very well within Tkinter ...

"""
embedding module matplotlib in a Tkinter GUI application
tested with Python 2.7 and matplotlib 1.0.1
"""

import matplotlib
matplotlib.use('TkAgg')

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import math
import Tkinter as tk

root = tk.Tk()
root.wm_title("Embedding matplotlib in Tkinter")


fig = Figure(figsize=(6, 5), dpi=100)
myplot = fig.add_subplot(111)

# brew up a simple sample plot
# create a list of floating point numbers
# this will be the x-axis data
float_list = [x/100.0 for x in range(300)]
# now create a list of sine values
# this will be the y-axis data
sine_list = [math.sin(2*math.pi*y) for y in float_list]
# optional labels
myplot.set_xlabel('x')
myplot.set_ylabel('y = sin(x)')
# then plot the two list's data in red
myplot.plot(float_list, sine_list, 'r')


# create a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().pack(side='top', fill='both', expand=1)

toolbar = NavigationToolbar2TkAgg( canvas, root )
toolbar.update()
canvas._tkcanvas.pack(side='top', fill='both', expand=1)

root.mainloop()
Comments
thanks
Attachments tk_matplot1.jpg 39.44 KB
 
2
 

Since we are talking about plotting, often overlooked is VPython, that has quite a nice plotting feature. It is fairly simple to use, here is an example ...

""" vp_plot_bars1.py use VPython to draw a bar chart module visual (aka VPython) comes in Windows, Linux and Mac flavors Windows download website: http://vpython.org/contents/download_windows.html
pick the download for your version of Python
I used installer VPython-Win-Py2.7-5.41.exe
"""

import visual.graph as vg

# set up the plot display
# if xmax, xmin, ymax, ymin are not specified, 
# then the default is auto scale
myplot = vg.gdisplay(x=80, y=50, width=680, height=350,
    title = 'widgets sold each day',
    xtitle='day', 
    ytitle='widgets sold',
    foreground=vg.color.black,
    background=vg.color.white)

draw_bars = vg.gvbars(delta=0.5, color=vg.color.red)

# list of data to be graphed
data = [30, 45, 80, 150, 220, 180, 110, 75, 50, 35, 20, 15, 10, 10]

for day, units in enumerate(data):
    draw_bars.plot(pos=(day+1, units))
 
2
 

You can use the Tkinter Entry() widget to enter a valid function_of_x string, evaluate it with eval(), and then plot it with VPython. Here is an example ...

"""tk_vp_plotting.py
using Tkinter to get the function of x input for a VPython plot
(console raw_input() does not work with VPython)
you can plot several functions, hence the random curve colors 
tested with Python27  by  vegaseat
"""

import Tkinter as tk
import visual.graph as vg
import random
from math import *

class MyApp(tk.Tk):
    def __init__(self, prompt):
        # the root will be self
        tk.Tk.__init__(self)
        self.title("Tkinter plotting with VPython")
        # set tk window x, y position below visual window
        self.geometry("+15+420")
        self.prompt = prompt
        self.v = tk.StringVar()
        # set some initial functionx string
        self.v.set("cos(x)")
        self.createWidgets()
        
    def visual_plot(self):
        # optionally make curve color random
        color_list = [vg.color.cyan, vg.color.yellow, vg.color.green]
        curve_color = random.choice(color_list)
        curve = vg.gcurve(color=curve_color)
        for x, fx in self.plot_data:
            curve.plot(pos=(x, fx))
    
    def get_data(self, functionx):
        plot_data = []
        # create a range of x values from 0 to 9 in steps of 0.1
        # this might have to be changed via user entry
        for x in vg.arange(0, 9.1, 0.1):
            # evaluate string function of x
            fx = eval(functionx)
            #print(x, fx)  # test
            plot_data.append((x, fx))
        return plot_data
    
    def createWidgets(self):
        self.label = tk.Label(self, text=self.prompt)
        self.label.grid(row=0, column=0, padx=10, pady=1)
        self.enter = tk.Entry(self, textvariable=self.v, bg='yellow')
        self.enter.grid(row=1, column=0, padx=10, pady=1)
        self.button = tk.Button(self, text="plot the function of x",
            command=self.action)
        self.button.grid(row=2, column=0, padx=10, pady=1)

    def action(self):
        # function of x string from entry widget
        functionx = self.v.get()
        self.plot_data = self.get_data(functionx)
        self.visual_plot()
        #self['bg'] = 'green'  # test


prompt = """\
Please input a valid mathematical function of x
like 
sin(2*x) * exp(0.5*x)
or
sqrt(x) + pi"""

app = MyApp(prompt)
app.mainloop()
Comments
without threading too
 
1
 

PyQt, or in this case PySide, allows you to look at a given web page via PySide.QtWebKit.QWebView() ...

# PySide is the official LGPL-licensed version of PyQT # You can download and use the Windows self-extracting installer # PySide-1.0.0qt472.win32-py2.7.exe # from: http://developer.qt.nokia.com/wiki/PySide_Binaries_Windows # modified example from: # http://www.pyside.org/docs/pyside/PySide/QtWebKit/ # tested with pyside472 and Python27 from PySide.QtCore import * from PySide.QtGui import * from PySide.QtWebKit import * # create a Qt application app = QApplication([]) # create a PySide.QtWebKit.QWebView() to display a web page # (your computer needs to be connected to the internet) view = QWebView() url = "http://qt.nokia.com/"
view.load(QUrl(url))
view.show()

# run the application event loop
app.exec_()
 
2
 

What about an example of using the webbrowser as the frontend? I use some pen-testing suites that use html as the GUI.

Here is an example, kind of ugly since it is just to demonstrate what you can do.
Also, I am no web developer so the html was mostly pulled from w3schools.com.

Example:

import socket, webbrowser #setup our socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #set socket to reuse address, if you don't you will eventually get #socket errors with repetitive access s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) #bind socket to localhost and port 44444 s.bind(('',44444)) #I am not a web developer and most of this was from #w3schools.com page = """ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <body> <h1>GUI via web page</h1> <p>Some examples of using html for a GUI</p> <ol> <li>Element 1</li> <li>Element 2</li> <li>So on..</li> <li>And so on.</li> </ol> <form name="input" action="html_form_action.asp" method="get"> First name: <input type="text" name="firstname" /><br /> Last name: <input type="text" name="lastname" /><br /> Password: <input type="password" name="pwd" /><br /> <input type="radio" name="sex" value="male" /> Male<br /> <input type="radio" name="sex" value="female" /> Female<br /> <input type="checkbox" name="vehicle" value="Bike" /> I have a bike<br /> <input type="checkbox" name="vehicle" value="Car" /> I have a car<br /> Username: <input type="text" name="user" /><br /> <input type="submit" value="Submit" /> </form> </body> </html>""" car_page = """ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <body> <h1> Car </h1> <p> I have a car too, it is a Scion tC! </p> </body> </html> """ bike_page = """ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <body> <h1> Bike </h1> <p> I don't have a bike.... </p> </body> </html> """ loggedin_page = """ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <body> <h1> Logged in </h1> <p> You are now logged in, welcome. </p> </body> </html> """ started = 0 while 1: #listen for connection s.listen(1) #check an see if this is the first time running #if so, open the default browser to our server #not needed, added for convince if started == 0: webbrowser.open_new("http://localhost:44444")
        started = 1
    else:
        #accept connection and create objects to handle it
        conn, addr = s.accept()
        #get data from browser
        data = conn.recv(10000)
        print data
        #check and see if the browser POSTed data to us
        if "html_form_action.asp?" in data:
            #look for stuff from forms and send appropreate page
            if "Bike" in data:
                conn.send(bike_page)
            elif "Car" in data:
                conn.send(car_page)
            else:
                conn.send(loggedin_page)
        else:
            conn.send(page)
        #close connection so we can get more data if sent
        conn.close()
 
1
 

PySide is out for Python32, here is a little test program ...

# explore multiple QFrame() in a QGridLayout()
# also change the color of the frames
# tested with PySide 474 and Python32

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_frame()
    
    def make_frame(self):
        self.frame1 = QFrame(self)
        self.frame1.setLineWidth(3)
        self.frame1.setFrameStyle(QFrame.Box|QFrame.Sunken)
        
        self.frame2 = QFrame(self)
        self.frame2.setLineWidth(3)
        self.frame2.setFrameStyle(QFrame.Box|QFrame.Sunken)        

        self.frame3 = QFrame(self)
        self.frame3.setLineWidth(3)
        self.frame3.setFrameStyle(QFrame.Box|QFrame.Sunken)
        
        grid = QGridLayout()
        grid.setSpacing(10)
        # addWidget(QWidget, row, column, rowSpan, columnSpan)
        # span 2 rows and 1 column each
        grid.addWidget(self.frame1, 1, 1, 2, 1)
        grid.addWidget(self.frame2, 1, 2, 2, 1)
        # span 1 row and 2 columns
        # note that you occupy row 3 now
        grid.addWidget(self.frame3, 3, 1, 1, 2)
       
        self.setLayout(grid)
        
        # put a button on frame1
        self.button = QPushButton("Change colors", self.frame1)
        self.button.resize(150, 30)  # alternate size
        self.button.move(20, 20)
        # bind the button click
        self.button.clicked.connect(self.changeFrameColor)
        
    def changeFrameColor(self):
        # color is a string in #RRGGBB format
        red = "#ff0000"
        blue = "#0000ff"
        yellow = "#ffff00"        
        style_str = "QFrame {background-color: %s}"            
        # use style sheet to set background colors of frames
        self.frame1.setStyleSheet(style_str % yellow)
        self.frame2.setStyleSheet(style_str % red)
        self.frame3.setStyleSheet(style_str % blue)        

# create the Qt Application
app = QApplication([])

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

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

A test code for a PySide button with an image and text next to it:

# test PySide widgets
# button with image and text

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

app = QApplication([])

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

# the image file can be a .jpg, .png, ,gif, .bmp image file
# if not in the working directory, give the full path
image_file = "down.gif"
image = QPixmap(image_file)

text = "my down arrow"
# put an image and a text on the button
button = QPushButton(image, text)
button.show()

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

app.exec_()
Attachments down.gif 0.59 KB
 
0
 

This shows you how simple it is to use PySide to display an image:

# test PySide widgets
# label with an image on it

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

app = QApplication([])

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

# the image file can be a .jpg, .png, ,gif, .bmp image file
# if not in the working directory, give the full path
image_file = "PorscheBoxster.jpg"
image = QPixmap(image_file)

label = QLabel()
label.setPixmap(image)
label.show()

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

app.exec_()
Attachments PorscheBoxster.jpg 30.26 KB
 
0
 

Just playing around with PySide and the QT Designer. The example is a popular program that matches words with words on a list as you type. Rewritten using the Designer's XML .ui file and a Python ui-loader program:

''' run_ps_listview_match2.py example using PySide's QListView and QAbstractListModel to match a partially typed word to words in a list the visible GUI part was generated with PySide's Designer the Designer's XML file was saved as "ps_listview_match2.ui" it contains a QWidget form with a QLabel, a QLineEdit and a QListView stacked into a QVBoxLayout() this program is a simple loader for the .ui XML file and also does the connection of the widget's signals PySide is the official LGPL-licensed version of PyQT I downloaded the 32 bit version for Python 2.7 from: http://qt-project.org/wiki/PySide_Binaries_Windows
The Windows self installer is called:
PySide-1.1.0qt474.win32-py2.7.exe
this also installs the Designer program
'''


from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtUiTools import QUiLoader

class MyWindow():
    def __init__(self, words, *args):
        # create the ui loader
        loader = QUiLoader()
        # and load the form's ui file created by Designer
        self.widget = loader.load("ps_listview_match2.ui")
        self.widget.show()

        # create the label, edit and list objects
        # (for correct names check the .ui file)
        self.label = self.widget.findChild(QLabel, 'label')
        self.edit = self.widget.findChild(QLineEdit, 'lineEdit')
        self.lview = self.widget.findChild(QListView, 'listView')

        # create model objects
        # words is a list of words
        self.lmodel = MyListModel(self.widget, words)
        self.lview.setModel(self.lmodel)

        self.words = words

        # act on the key pressed in edit
        self.widget.connect(self.edit,
            SIGNAL("textChanged(QString)"),
            self.update)

    def update(self):
        """
        updates the list of possible completions each time key
        is pressed, use lower() to make things case insensitive
        """
        p = str(self.edit.text()).lower()
        new_list = [w for w in self.words if w.lower().find(p)==0]
        self.lmodel.setAllData(new_list)


class MyListModel(QAbstractListModel):
    def __init__(self, parent, words, *args):
        QAbstractListModel.__init__(self, parent, *args)
        # words is a list of words
        self.words = words

    def rowCount(self, parent=QModelIndex()):
        return len(self.words)

    def data(self, index, role):
        if index.isValid() and role == Qt.DisplayRole:
            return self.words[index.row()]
        else:
            return None

    def setAllData(self, new_list):
        """replace old list with new list"""
        self.words = new_list
        self.reset()


# just a test list of words
state_list = [
'Mississippi', 'Oklahoma', 'Delaware', 'Minnesota',
'Arkansas', 'New Mexico', 'Indiana', 'Louisiana',
'Texas', 'Wisconsin', 'Kansas', 'Connecticut',
'California', 'West Virginia', 'Georgia', 'North Dakota',
'Pennsylvania', 'Alaska', 'Missouri', 'South Dakota',
'Colorado', 'New Jersey', 'Washington', 'New York',
'Nevada', 'Maryland', 'Idaho', 'Wyoming', 'Maine',
'Arizona', 'Iowa', 'Michigan', 'Utah', 'Illinois',
'Virginia', 'Oregon', 'Montana', 'New Hampshire',
'Massachusetts', 'South Carolina', 'Vermont', 'Florida',
'Hawaii', 'Kentucky', 'Rhode Island', 'Nebraska',
'Ohio', 'Alabama', 'North Carolina', 'Tennessee'
]

app = QApplication([])
win = MyWindow(state_list)
# run the application event loop
app.exec_()

For those of you who are curious, here is the XML code file "ps_listview_match2.ui" the Designer generated:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Match words with a list</string>
  </property>
  <widget class="QWidget" name="verticalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>9</x>
     <y>9</y>
     <width>361</width>
     <height>281</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QLabel" name="label">
      <property name="text">
       <string>Start typing to match words in list:</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QLineEdit" name="lineEdit"/>
    </item>
    <item>
     <widget class="QListView" name="listView"/>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>
 
1
 

Select multiple items from a Tkinter list box:

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

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


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

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

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

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

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

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

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

root.mainloop()
 
1
 

Thanks for sharing, only how listbox(3) chooses third if the lines are numbered 0 based as per comment?

 
1
 

You can use PyQT or PySide to do a similar thing:

# explore the PyQT or PySide QListWidget

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

class MyWindow(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)

        # create a test list of characters 'a' to 'z'
        test_list = [chr(p) for p in range(0x0061,  0x007b)]
        # create the listbox and position and size it
        self.listbox = QListWidget(self)
        self.listbox.setGeometry(20, 10, 200, 200)
        # load the listbox with the test list
        # automatically adds vertical scrollbar if list is long
        self.listbox.addItems(test_list)
        # now show the listbox
        self.listbox.show()
        # new connect style, needs PyQt 4.5+
        self.listbox.clicked.connect(self.on_select)

    def on_select(self):
        """an item in the listbox has been clicked/selected"""
        selected_item = self.listbox.currentItem().text()
        self.setWindowTitle(selected_item)


# create the Qt Application
app = QApplication([])

title = "select listbox item"
width = 240
height = 220
window = MyWindow(title, width, height)
window.show()

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

Tkinter is still refreshingly simple to use:

# display GMT time with Tkinter

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

def update_gmt():
    gmt_string.set(time.strftime("%H:%M:%S", time.gmtime()))
    # update every second recursively
    app.after(1000, update_gmt)

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

app = tk.Tk()
app.title("GMT")

gmt_string = tk.StringVar()

main()

app.mainloop()
 
1
 

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.

 
0
 

A little more involved, and shows how to draw lines on an image with the mouse pointer. The picture is in an earlier post if you want to use it.

'''ps_image_drawlines1.py draw lines across an image PySide is the official LGPL-licensed version of PyQT downloaded and used the Windows self-extracting installer PySide-1.1.0qt474.win32-py2.7.exe from: http://developer.qt.nokia.com/wiki/PySide_Binaries_Windows
tested with pyside474 and Python27
'''

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

class MyQGraphicsView(QGraphicsView):
    def __init__(self,scene, parent=None):
        super(MyQGraphicsView, self).__init__(scene, parent=parent)
        self.parent = parent
        self.scene  = scene
        self.startPunkt = None
        self.endPunkt = None

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
          self.endPunkt = event.pos()
          self.paintme()

    def mousePressEvent(self, event):
        if (event.buttons() & Qt.LeftButton):
          self.startPunkt = event.pos()

    def paintme(self):
        if self.endPunkt and self.startPunkt:
            pen = QPen()
            # set pen color
            pen.setColor(Qt.yellow)
            self.startPunkt = self.mapToScene(QPoint(self.startPunkt.x(),
                self.startPunkt.y()))
            self.endPunkt = self.mapToScene(QPoint(self.endPunkt.x(),
                self.endPunkt.y()))
            self.scene.addLine(self.startPunkt.x(),self.startPunkt.y(),
                self.endPunkt.x(),self.endPunkt.y(),pen)
            self.startPunkt = None
            self.endPunkt = None


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle('draw lines on an image (click/drag pointer)')
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 100, 800, 500)
        self.setup_ui()
        self.show()

    def setup_ui(self):
        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, 800, 500)

        loaded_image = QImage()
        # pick an image file you have in the working folder or give full path
        image_file = "PorscheBoxster.jpg"
        load_error = "%s not found!" % image_file
        if not loaded_image.load(image_file):
            self.setWindowTitle(load_error)
        self.image = loaded_image
        self.scene.addPixmap(QPixmap.fromImage(self.image))

        self.view = MyQGraphicsView(self.scene, self)
        self.setCentralWidget(self.view)

    def paintEvent(self, event):
        self.view.paintme()


app = QApplication([])
win = MainWindow()
app.exec_()
 
1
 

A little pygame code to show you how to create the effect of soap bubbles floating:

'''pg_Bubbles1.py make bubble circles float up the screen 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 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 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)
    pg.quit()

if __name__ == "__main__":
    main()
Isn't it about time forums rewarded their contributors?

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

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

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