1.11M Members

Python GUI Programming

 
1
 

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

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/

 
2
 

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)

 
1
 

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

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

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

 
2
 

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

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/

 
2
 

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

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.

 
0
 

The Phoenx project at least makes an attempt to create a half way good documentation for wxPython.

 
1
 

Another look at the Tkinter GUI toolkit and its grid layout manager:

''' tk_grid_test101.py
explore the Tkinter grid layout
don't mix pack() and grid() within same frame container widget
place() and grid() can be used in the same frame

'''

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

root = tk.Tk()
w = h = 200
root.geometry("%dx%d" % (w, h))
root.title("buttons in frames")

frame1 = tk.Frame(root, bg='yellow')
frame1.pack(side='top', fill='both', expand='yes')

frame2 = tk.Frame(root, bg='green')
frame2.pack(side='top', fill='both', expand='yes')

# these buttons are in frame1
btn1 = tk.Button(frame1, text=" button1 ")
btn2 = tk.Button(frame1, text=" button2 ")
btn3 = tk.Button(frame1, text=" button3 ")
btn4 = tk.Button(frame1, text=" button4 ")
# these buttons are in frame2
btn5 = tk.Button(frame2, text=" button5 ")
btn6 = tk.Button(frame2, text=" button6 ")

# lay out buttons ...
# these buttons are in frame1
btn1.grid(row=0, column=0, pady=5)
btn2.grid(row=1, column=0)
btn3.grid(row=1, column=1, padx=5)
btn4.grid(row=1, column=2)
# these buttons are in frame2
btn5.grid(row=0, column=0, pady=5)
btn6.grid(row=1, column=0)

root.mainloop()

Thanks vegaseat for this hint!
Display --> http://prntscr.com/l8g34

 
1
 

Shows you how to assign a text font to the various Tkinter text oriented widgets:

''' tk_font_explore1.py
different ways to assign a text font to certain Tkinter widgets
snee
'''

try:
    # Python2
    import Tkinter as tk
    import tkFont as tkf
except ImportError:
    # Python3
    import tkinter as tk
    import tkinter.font as tkf

root = tk.Tk()
# set size of root
w = 350
h = 300
root.geometry("%dx%d" % (w, h))
root.title('setting Tkinter text fonts')

helv12 = tkf.Font(family="Helvetica", size=12, weight="bold")
helv16 = tkf.Font(family="Helvetica", size=16, weight="bold")

# FYI
# the instance of Font() can yield information
# get pixel width of a text in a given font, handy info
print(helv16.measure('label_2'))  # 71
print(helv16.cget('family'))      # Helvetica
print(helv16.actual())
''' result ...
{'family': 'Arial', 'weight': 'bold', 'slant': 'roman', 
'overstrike': 0, 'underline': 0, 'size': 16}
'''

frame = tk.Frame(root, bg='yellow')
frame.pack(side='top', fill='both', expand='yes')

label_1 = tk.Label(frame, text='label_1', font=helv12)
label_1.pack(pady=5)

label_2 = tk.Label(frame, text='label_2', font=helv16)
label_2.pack(pady=5)

# change helv16 (need to use a copy of the instance)
helv16a = helv16.copy()
helv16a.config(weight='normal', underline=1, slant='italic')
label_3 = tk.Label(frame, text='label_3', font=helv16a)
label_3.pack(pady=5)

# another way to set fonts using just a tuple
cosa24 = ('Comic Sans MS', 24, 'bold')
label_4 = tk.Label(frame, text='label_4', font=cosa24)
label_4.pack(pady=5)

# tuple examples of common fonts (some might be just on Windows)
#myfont = ('times', 20, 'bold')
#myfont = ('times', 12, 'normal')
#myfont = ('courier', 20, 'bold')
#myfont = ('helvetica', 20, 'bold italic')
#myfont = ('verdana', 20, 'bold italic')

# you can also use font designation this way
label_5 = tk.Label(frame, text='label_5', font='courier 32 bold')
label_5.pack(pady=5)

root.mainloop()
 
2
 

A look at the Tkinter data Entry widget and the use of tk.StringVar() to handle the data ...

''' tk_StringVar_Entry1.py
use tk.StringVar() to handle Entry widget values
'''

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

def get_value():
    label['text'] = value.get()

def set_value():
    value.set("Hello DaniWeb")

def clear_value():
    value.set("")

root = tk.Tk()

value = tk.StringVar()

tk.Label(root, text='Enter something below: ').pack()
entry = tk.Entry(root, textvariable=value, bg='yellow')
entry.pack()
# put cursor in entry
entry.focus()

b1 = tk.Button(root, text="Show Entry Value", command=get_value)
b1.pack(pady=3)

b2 = tk.Button(root, text="Set Entry Value", command=set_value)
b2.pack(pady=3)

b3 = tk.Button(root, text="Clear Entry Value", command=clear_value)
b3.pack(pady=3)

# show get_value() results
label = tk.Label(root, text='<>'*5, fg='red')
label.pack(pady=3)

root.mainloop()
 
2
 

Access the source code of Tkinter widgets ...

''' tk_button_inspect101.py
since Tkinter is written in Python you can access the source code
of a specified class with Python module inspect
'''

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


root = tk.Tk()

t_btn = tk.Button(text="Hello World", width=25, bg='green')
t_btn.pack(padx=5, pady=5)

# get the Tkinter class Button source code ...
print(inspect.getsource(tk.Button))

root.mainloop()

'''
class Button(Widget):
    """Button widget."""
    def __init__(self, master=None, cnf={}, **kw):
        """Construct a button widget with the parent MASTER.

        STANDARD OPTIONS

            activebackground, activeforeground, anchor,
            background, bitmap, borderwidth, cursor,
            disabledforeground, font, foreground
            highlightbackground, highlightcolor,
            highlightthickness, image, justify,
            padx, pady, relief, repeatdelay,
            repeatinterval, takefocus, text,
            textvariable, underline, wraplength

        WIDGET-SPECIFIC OPTIONS

            command, compound, default, height,
            overrelief, state, width
        """
        Widget.__init__(self, master, 'button', cnf, kw)

    def tkButtonEnter(self, *dummy):
        self.tk.call('tkButtonEnter', self._w)

    def tkButtonLeave(self, *dummy):
        self.tk.call('tkButtonLeave', self._w)

    def tkButtonDown(self, *dummy):
        self.tk.call('tkButtonDown', self._w)

    def tkButtonUp(self, *dummy):
        self.tk.call('tkButtonUp', self._w)

    def tkButtonInvoke(self, *dummy):
        self.tk.call('tkButtonInvoke', self._w)

    def flash(self):
        """Flash the button.

        This is accomplished by redisplaying
        the button several times, alternating between active and
        normal colors. At the end of the flash the button is left
        in the same normal/active state as when the command was
        invoked. This command is ignored if the button's state is
        disabled.
        """
        self.tk.call(self._w, 'flash')

    def invoke(self):
        """Invoke the command associated with the button.

        The return value is the return value from the command,
        or an empty string if there is no command associated with
        the button. This command is ignored if the button's state
        is disabled.
        """
        return self.tk.call(self._w, 'invoke')

'''
 
0
 

Get a listbox filled with a given directory's filenames, select a filename ...

''' ps_Listbox_filenames1.py
load a PySide listbox with filenames in a given directory
show the selected (clicked) filename in a label

PySide is the license free version of PyQT
for Python33 you can use the Windows self-extracting installer
PySide-1.1.2.win32-py3.3.exe
(PyQT483 equivalent) from:
http://qt-project.org/wiki/PySide
or:
http://www.lfd.uci.edu/~gohlke/pythonlibs/

'''

from PySide.QtCore import *
from PySide.QtGui import *
import os
import glob

class MyForm(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(100, 150, 240, 380)

        self.label_dir = QLabel("Enter/Edit Directory:")
        # pick a directory you have as default
        #self.edit_dir = QLineEdit("C:/Temp/Zcrypt/Art123")
        self.edit_dir = QLineEdit("C:/Zz4/Sz1")

        self.button_load = QPushButton("Load Filenames")
        # bind the button click to a function reference
        # newer connect style used with PyQT 4.5 and higher
        self.button_load.clicked.connect(self.on_click)

        self.listbox = QListWidget()
        # new connect style, needs PyQt 4.5+
        self.listbox.clicked.connect(self.on_select)

        self.label_result = QLabel()        

        # layout the 2 widgets
        vbox = QVBoxLayout()
        vbox.addWidget(self.label_dir)
        vbox.addWidget(self.edit_dir)
        vbox.addWidget(self.button_load)
        vbox.addWidget(self.listbox)
        vbox.addWidget(self.label_result)
        self.setLayout(vbox)

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

    def on_click(self):
        directory = self.edit_dir.text()
        try:
            # make it the working directory
            os.chdir(directory)
        except FileNotFoundError:
            self.label_result.setText("No such directory")
            self.listbox.clear()
            return
        #print(os.getcwd())  # test
        # create a list of all .jpg files in a given directory
        self.list_fnames = []
        #mask = "*.jpg"  # .jpg files only
        mask = "*.*"    # all files
        for path in glob.glob(mask):
            dirname, filename = os.path.split(path)
            #print(filename)  # test
            self.list_fnames.append(filename)
        #print(list_jpg)  # test
        self.listbox.addItems(self.list_fnames)
        sf = "{} items loaded".format(len(self.list_fnames))
        self.setWindowTitle(sf)
        pass


# replace [] with sys.argv for commandline args
app =  QApplication([])
form = MyForm()
form.show()
app.exec_()
 
0
 

Using two Tkinter windows ...

''' tk_toplevel_window_hides_root1.py
hide the root window temporarily with a top level window
'''

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

def create_top():
    top = tk.Toplevel(root, bg='red')
    top.title("top")
    # use width x height + x_offset + y_offset (no spaces!)
    # set top the same as root so it will hide it below
    top.geometry("%dx%d+%d+%d" % (200, 150, 100, 50))    
    tk.Button(top, text='Destroy Top Window', command=top.destroy).pack()

root = tk.Tk()
root['bg'] = 'yellow'
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (200, 150, 100, 50))
root.title("root")

tk.Button(root, text='Create Top Window', command=create_top).pack()

root.mainloop()

Another approach is lower and lift ...

''' tk_lower_lift_windows.py
lower and lift Tkinter windows
'''

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

# create the root window
root = tk.Tk()
root['bg'] = 'yellow'
root.title("root")
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (200, 150, 100, 30))

# create a top level window
top = tk.Toplevel(root, bg='red')
top.title("top")
# use width x height + x_offset + y_offset (no spaces!)
top.geometry("%dx%d+%d+%d" % (200, 150, 170, 80))    

# widgets for root window
tk.Button(root, text='lower root window below top window', 
          command=partial(root.lower, top)).pack()
tk.Button(root, text='lift root window above top window', 
          command=partial(root.lift, top)).pack()

# widgets for top window
tk.Button(top, text='lower top window below root window', 
          command=partial(top.lower, root)).pack()
tk.Button(top, text='lift top window above root window', 
          command=partial(top.lift, root)).pack()

root.mainloop()
 
0
 

A little IronPython code ...

''' ip_mouseclick_location1.py
download and install 
IronPython-2.7.4.msi 
or latest version from:
http://ironpython.codeplex.com/

Form designed with SharpDevelop 4.2.1

tested with IronPython 2.7.4
'''

import clr

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

import System.Drawing
import System.Windows.Forms

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

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

    def InitializeComponent(self):
        self.SuspendLayout()
        # 
        # Form1
        # 
        self.BackColor = System.Drawing.Color.Yellow
        self.ClientSize = System.Drawing.Size(350, 250)
        self.CenterToScreen()
        self.Name = "Form1"
        self.Text = "MyForm"
        self.MouseClick += self.Form1MouseClick
        self.ResumeLayout(False)


    def Form1MouseClick(self, sender, e):
        ''' position is within form borders '''
        sf = "mouse clicked at x={} y={}".format(e.X, e.Y)
        self.Text = sf


form = Form1()
Application.Run(form)
 
0
 

Using PyGame for drawing shapes:

# exploring module pygame
# draw rectangles on a black screen

import pygame as pg

# some colors
# pygame uses (r, g, b) tuples for color
black = 0, 0, 0
blue = 0, 0, 255
green = 0, 255, 0
light_blue = 173, 216, 230
olive = 128, 128, 0
orange = 255, 165, 0
magenta = 255, 0, 255
red = 255, 0, 0
yellow = 255, 255, 0
white = 255, 255, 255

# window/screen width and height
screen_w = 400
screen_h = 300
# default background is black
screen = pg.display.set_mode((screen_w, screen_h))
pg.display.set_caption("Draw rectangles")

# set up the rectangle specs
# 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 = (30, 20, 130, 120)
# optional width of the rectangles's border
width = 2
# pygame.draw.rect(Surface, color, Rect, width=0)
pg.draw.rect(screen, white, rect, width)

# draw another rectangle
rect2 = (80, 40, 130, 120)
pg.draw.rect(screen, red, rect2, width)

# draw a filled rectangle
rect3 = (220, 140, 130, 120)
# if width = 0 (or not given) the shape is filled with color
width = 0
pg.draw.rect(screen, yellow, rect3, width)

# update display
pg.display.flip()

# event loop ...
while True:
    for event in pg.event.get():
        # quit when window corner x is clicked
        if event.type == pg.QUIT:
            pg.quit()
            raise SystemExit
 
0
 

I found this C# code snippet from our friend ddanbe and couldn't help to translate it to IronPython.

Here is the C# code ...

// small_form101.cs
// C# form with a label
// can be compiled with:
// SnippetCompiler.exe
// from:
// http://www.sliver.com/dotnet/SnippetCompiler/

using System.Windows.Forms;

class Class1
{
    static void Main()
    {
        Label label = new Label();
        label.Text = "Hello world!";
        Form form = new Form();
        form.Controls.Add(label);
        Application.Run(form);
    }
}

Here is the corresponding IronPython code ...

''' ip_small_form101.py
form with a label
using IronPython from
http://www.codeplex.com/ironpython
'''

import clr
clr.AddReference('System.Windows.Forms')

import System.Windows.Forms as swf

class Class1(swf.Form):
    def __init__(self):
        label = swf.Label()
        label.Text = "Hello world!"
        self.Controls.Add(label)

form = Class1()
swf.Application.Run(form)
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: