The Phoenx project at least makes an attempt to create a half way good documentation for wxPython.
ZZucker 342 Practically a Master Poster
sneekula 969 Nearly a Posting Maven
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
sneekula 969 Nearly a Posting Maven
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()
Edited by sneekula
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
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()
Edited by vegaseat
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
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')
'''
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
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_()
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
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()
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
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)
Lardmeister 461 Posting Virtuoso
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
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
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)
Edited by vegaseat because: added author
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Version information ...
''' pwx_version.py
get the version info of the wxPython GUI
for Python33 download the wxPython Phoenix version (4nov2013)
wxPython_Phoenix-3.0.0.0-r75123-win32-py3.3.tar.gz
from
http://wxpython.org/Phoenix/snapshot-builds/
then simply extracted the wx folder to
C:\Python33\Lib\site-packages
'''
import wx
import sys
# Python version
print(sys.version)
# wx version
print(wx.version())
app = wx.App()
# create the basic window, let's call it win
# (there is no parent, -1 is the default ID)
win = wx.Frame(None, -1, size=(360, 80))
win.SetBackgroundColour('white')
sf = " {}".format(wx.version())
# create a label, default is auto-size
label = wx.StaticText(win, -1, sf)
font = wx.Font(16, wx.SCRIPT, wx.NORMAL, wx.LIGHT)
label.SetFont(font)
# show the window
win.Show(True)
# start the GUI event loop
app.MainLoop()
''' results (Python27 or Python33) ...
2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)]
2.9.1.1 (msw-unicode)
3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
3.0.0.0-r75123 msw (phoenix)
'''
vinodvinu -3 Light Poster
Who created a hell like language python?. The creator want us to memorise all codes for making GUI and enter it manually. Horrible !!!. Everybody says that python is a simple language and it will increase productivity of a programmer. But how?. A programmer should type for all his widjets like buttons and labels and textboxes. This is a shame. Why don't somebody try to make a drag & drop GUI making IDE like VB ?. I admire that there is a QtDesigner, but no use. Only god knows how to write python code in Qt designer files.(.ui files)
Editor's note:
Don't clutter up the sticky with questions. Ask your question in the regular forum.
Edited by vegaseat because: clutter
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Here is a typical PySide/PyQt designer project. First the XML file generated by the Designer program (saved as ps_listview_match2.ui) ...
<?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>
Now the Python code that uses the XML file ...
''' 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 from:
http://qt-project.org/wiki/PySide_Binaries_Windows
The Windows self installer is called:
PySide-1.2.1.win32-py2.7.exe (for Python27)
PySide-1.2.1.win32-py3.3.exe (for Python33)
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_()
diezel9 0 Newbie Poster
thank you
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Drawing shapes with Tkinter ...
''' tk_canvas_shapes101.py
use the Tkinter GUI toolkit that comes with Python
to draw some shapes
for more shapes check canvas methods at ...
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/canvas.html
http://effbot.org/tkinterbook/canvas.htm
'''
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
# create the main window
root = tk.Tk()
root.title("Drawing shapes on a Tkinter canvas")
# create the drawing canvas with white background
canvas = tk.Canvas(root, width=550, height=450, bg='white')
canvas.pack()
# upper left and lower right corner coordinates of rectangle
rect = (50, 110, 250, 310)
# draw the outline of the rectangle
canvas.create_rectangle(rect)
# now draw the oval to fit inside the above rectangle
# an oval is drawn within a rectangle
# a square will give a circle
canvas.create_oval(rect, fill='yellow')
# draw a triangle using polygon
# (endpoint of polygon is same as starting point)
x1 = 300
y1 = 110
x2 = 300
y2 = 310
x3 = 500
y3 = 310
canvas.create_polygon(x1, y1, x2, y2, x3, y3, fill="blue")
# draw a rectangle to fit around the triangle
canvas.create_rectangle(x1, y1, x3, y3)
# start the GUI event loop
root.mainloop()
ZZucker 342 Practically a Master Poster
Sometimes comes in handy:
''' ps_qt_version101.py
show the version number for PYSide and the QT version it used
'''
import PySide
import PySide.QtCore
# prints PySide version
print(PySide.__version__)
# gets a tuple with each version component
print(PySide.__version_info__)
print('-'*30)
# prints the Qt version used to compile PySide
print(PySide.QtCore.__version__)
# gets a tuple with each version components of Qt used to compile PySide
print(PySide.QtCore.__version_info__)
''' possible result ...
1.1.1
(1, 1, 1, 'final', 1)
------------------------------
4.7.4
(4, 7, 4)
'''
sneekula 969 Nearly a Posting Maven
Explore the Tkinter GUI toolkit to draw a circle:
# draw a circle with given center (x,y) and radius
# tkinter normally needs a specified square
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
def get_center(x1, y1, x2, y2):
'''
for a rectangle with ulc=(x1,y1) and lrc=(x2,y2)
calculate the center (x,y)
'''
x = x1 + (x2 - x1)//2
y = y1 + (y2 - y1)//2
return x, y
def get_square(x, y, radius):
'''
given the center=(x,y) and radius
calculate the square for the circle to fit into
return x1, y1, x2, y2 of square's ulc=(x1,y1) and lrc=(x2,y2)
'''
x1 = x - radius
y1 = y - radius
x2 = x + radius
y2 = y + radius
return x1, y1, x2, y2
# create the basic window, let's call it 'root'
root = tk.Tk()
# create a canvas to draw on
cv = tk.Canvas(root, width=300, height=300, bg='white')
cv.grid()
# draw a circle with given center (x,y) and radius
x, y = 150, 120
radius = 65
# to draw a circle you need to get the ul and lr corner coordinates
# of a square that the circle will fit inside of
rect = get_square(x, y, radius)
# draw the cicle that fits into the rect/square
# default fill is canvas bg
#cv.create_oval(rect)
circle1 = cv.create_oval(rect, fill='red')
# optionally show the recangle the circle fits into
cv.create_rectangle(rect)
# testing ...
print(get_square(x, y, radius)) # (10, 10, 90, 90)
print(get_center(*rect)) # (50, 50)
# ul and lr box corners of square around circle
print(cv.coords(circle1)) # [10.0, 10.0, 90.0, 90.0]
# start the event loop
root.mainloop()
Tkinter normally takes a square to draw a circle inside, but I added helper functions to draw a circle with a given radius and a center position.
Edited by sneekula
sneekula 969 Nearly a Posting Maven
Explore the Tkinter GUI toolkit to draw a circle and move it with the arrow keys:
# use a Tkinter canvas to draw a circle, move it with the arrow keys
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
class MyApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("move circle with arrow keys")
# create a canvas to draw on
self.cv = tk.Canvas(self, width=400, height=400, bg='white')
self.cv.grid()
# create a square box with upper left corner (x,y)
self.x = 120
self.y = 120
size = 150
box = (self.x, self.y, self.x + size, self.y + size)
# create a circle that fits the bounding box
self.circle = self.cv.create_oval(box, fill='red')
# bind arrow keys to movement
self.bind('<Up>', self.move_up)
self.bind('<Down>', self.move_down)
self.bind('<Left>', self.move_left)
self.bind('<Right>', self.move_right)
def move_up(self, event):
# move_increment is 5 pixels
y = -5
# move circle by increments x, y
self.cv.move(self.circle, 0, y)
def move_down(self, event):
y = 5
self.cv.move(self.circle, 0, y)
def move_left(self, event):
x = -5
self.cv.move(self.circle, x, 0)
def move_right(self, event):
x = 5
self.cv.move(self.circle, x, 0)
app = MyApp()
app.mainloop()
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Sometimes you want to know the version of the Tkinter GUI toolkit in your Python installation ...
''' tk_version.py
get the version number of Tkinter and its underlying TCL
'''
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
print("Tkinter version = {}".format(tk.TkVersion))
print("Its TCL version = {}".format(tk.TclVersion))
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Constants used in pygame code ...
''' pg_constants101.py
look at a list of pygame event constants
'''
import pygame.constants
help(pygame.constants)
''' result ...
Help on module pygame.constants in pygame:
NAME
pygame.constants - Constants defined by SDL and needed in Pygame.
DATA
ACTIVEEVENT = 1
ANYFORMAT = 268435456
ASYNCBLIT = 4
AUDIO_S16 = 32784
AUDIO_S16LSB = 32784
AUDIO_S16MSB = 36880
AUDIO_S16SYS = 32784
AUDIO_S8 = 32776
AUDIO_U16 = 16
AUDIO_U16LSB = 16
AUDIO_U16MSB = 4112
AUDIO_U16SYS = 16
AUDIO_U8 = 8
BIG_ENDIAN = 4321
BLEND_ADD = 1
BLEND_MAX = 5
BLEND_MIN = 4
BLEND_MULT = 3
BLEND_PREMULTIPLIED = 17
BLEND_RGBA_ADD = 6
BLEND_RGBA_MAX = 16
BLEND_RGBA_MIN = 9
BLEND_RGBA_MULT = 8
BLEND_RGBA_SUB = 7
BLEND_RGB_ADD = 1
BLEND_RGB_MAX = 5
BLEND_RGB_MIN = 4
BLEND_RGB_MULT = 3
BLEND_RGB_SUB = 2
BLEND_SUB = 2
BUTTON_X1 = 6
BUTTON_X2 = 7
DOUBLEBUF = 1073741824
FULLSCREEN = -2147483648
GL_ACCELERATED_VISUAL = 15
GL_ACCUM_ALPHA_SIZE = 11
GL_ACCUM_BLUE_SIZE = 10
GL_ACCUM_GREEN_SIZE = 9
GL_ACCUM_RED_SIZE = 8
GL_ALPHA_SIZE = 3
GL_BLUE_SIZE = 2
GL_BUFFER_SIZE = 4
GL_DEPTH_SIZE = 6
GL_DOUBLEBUFFER = 5
GL_GREEN_SIZE = 1
GL_MULTISAMPLEBUFFERS = 13
GL_MULTISAMPLESAMPLES = 14
GL_RED_SIZE = 0
GL_STENCIL_SIZE = 7
GL_STEREO = 12
GL_SWAP_CONTROL = 16
HAT_CENTERED = 0
HAT_DOWN = 4
HAT_LEFT = 8
HAT_LEFTDOWN = 12
HAT_LEFTUP = 9
HAT_RIGHT = 2
HAT_RIGHTDOWN = 6
HAT_RIGHTUP = 3
HAT_UP = 1
HWACCEL = 256
HWPALETTE = 536870912
HWSURFACE = 1
IYUV_OVERLAY = 1448433993
JOYAXISMOTION = 7
JOYBALLMOTION = 8
JOYBUTTONDOWN = 10
JOYBUTTONUP = 11
JOYHATMOTION = 9
KEYDOWN = 2
KEYUP = 3
KMOD_ALT = 768
KMOD_CAPS = 8192
KMOD_CTRL = 192
KMOD_LALT = 256
KMOD_LCTRL = 64
KMOD_LMETA = 1024
KMOD_LSHIFT = 1
KMOD_META = 3072
KMOD_MODE = 16384
KMOD_NONE = 0
KMOD_NUM = 4096
KMOD_RALT = 512
KMOD_RCTRL = 128
KMOD_RMETA = 2048
KMOD_RSHIFT = 2
KMOD_SHIFT = 3
K_0 = 48
K_1 = 49
K_2 = 50
K_3 = 51
K_4 = 52
K_5 = 53
K_6 = 54
K_7 = 55
K_8 = 56
K_9 = 57
K_AMPERSAND = 38
K_ASTERISK = 42
K_AT = 64
K_BACKQUOTE = 96
K_BACKSLASH = 92
K_BACKSPACE = 8
K_BREAK = 318
K_CAPSLOCK = 301
K_CARET = 94
K_CLEAR = 12
K_COLON = 58
K_COMMA = 44
K_DELETE = 127
K_DOLLAR = 36
K_DOWN = 274
K_END = 279
K_EQUALS = 61
K_ESCAPE = 27
K_EURO = 321
K_EXCLAIM = 33
K_F1 = 282
K_F10 = 291
K_F11 = 292
K_F12 = 293
K_F13 = 294
K_F14 = 295
K_F15 = 296
K_F2 = 283
K_F3 = 284
K_F4 = 285
K_F5 = 286
K_F6 = 287
K_F7 = 288
K_F8 = 289
K_F9 = 290
K_FIRST = 0
K_GREATER = 62
K_HASH = 35
K_HELP = 315
K_HOME = 278
K_INSERT = 277
K_KP0 = 256
K_KP1 = 257
K_KP2 = 258
K_KP3 = 259
K_KP4 = 260
K_KP5 = 261
K_KP6 = 262
K_KP7 = 263
K_KP8 = 264
K_KP9 = 265
K_KP_DIVIDE = 267
K_KP_ENTER = 271
K_KP_EQUALS = 272
K_KP_MINUS = 269
K_KP_MULTIPLY = 268
K_KP_PERIOD = 266
K_KP_PLUS = 270
K_LALT = 308
K_LAST = 323
K_LCTRL = 306
K_LEFT = 276
K_LEFTBRACKET = 91
K_LEFTPAREN = 40
K_LESS = 60
K_LMETA = 310
K_LSHIFT = 304
K_LSUPER = 311
K_MENU = 319
K_MINUS = 45
K_MODE = 313
K_NUMLOCK = 300
K_PAGEDOWN = 281
K_PAGEUP = 280
K_PAUSE = 19
K_PERIOD = 46
K_PLUS = 43
K_POWER = 320
K_PRINT = 316
K_QUESTION = 63
K_QUOTE = 39
K_QUOTEDBL = 34
K_RALT = 307
K_RCTRL = 305
K_RETURN = 13
K_RIGHT = 275
K_RIGHTBRACKET = 93
K_RIGHTPAREN = 41
K_RMETA = 309
K_RSHIFT = 303
K_RSUPER = 312
K_SCROLLOCK = 302
K_SEMICOLON = 59
K_SLASH = 47
K_SPACE = 32
K_SYSREQ = 317
K_TAB = 9
K_UNDERSCORE = 95
K_UNKNOWN = 0
K_UP = 273
K_a = 97
K_b = 98
K_c = 99
K_d = 100
K_e = 101
K_f = 102
K_g = 103
K_h = 104
K_i = 105
K_j = 106
K_k = 107
K_l = 108
K_m = 109
K_n = 110
K_o = 111
K_p = 112
K_q = 113
K_r = 114
K_s = 115
K_t = 116
K_u = 117
K_v = 118
K_w = 119
K_x = 120
K_y = 121
K_z = 122
LIL_ENDIAN = 1234
MOUSEBUTTONDOWN = 5
MOUSEBUTTONUP = 6
MOUSEMOTION = 4
NOEVENT = 0
NOFRAME = 32
NUMEVENTS = 32
OPENGL = 2
OPENGLBLIT = 10
PREALLOC = 16777216
QUIT = 12
RESIZABLE = 16
RLEACCEL = 16384
RLEACCELOK = 8192
SCRAP_BMP = 'image/bmp'
SCRAP_CLIPBOARD = 0
SCRAP_PBM = 'image/pbm'
SCRAP_PPM = 'image/ppm'
SCRAP_SELECTION = 1
SCRAP_TEXT = 'text/plain'
SRCALPHA = 65536
SRCCOLORKEY = 4096
SWSURFACE = 0
SYSWMEVENT = 13
TIMER_RESOLUTION = 10
USEREVENT = 24
USEREVENT_DROPFILE = 4096
UYVY_OVERLAY = 1498831189
VIDEOEXPOSE = 17
VIDEORESIZE = 16
YUY2_OVERLAY = 844715353
YV12_OVERLAY = 842094169
YVYU_OVERLAY = 1431918169
FILE
c:\pyzo2014a\lib\site-packages\pygame\constants.pyd
'''
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Dress up your Tkinter programs with a background image ...
''' tk_Image_label_button1.py
put a background picture and a button on a Tkinter label
'''
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
def on_button():
root.title("Button has been pressed!")
root = tk.Tk()
# pick a .gif image file you have in the working folder
# (or give full path) Linux fname is case sensitive
fname = "LAKE.GIF"
image_tk = tk.PhotoImage(file=fname)
w = image_tk.width()
h = image_tk.height()
info = "size of {} = {}".format(fname, (w, h))
print(info) # test
root.title(info)
root.geometry("%dx%d+310+210" % (w, h))
label = tk.Label(root, image=image_tk)
label.pack(side='top', fill='x', expand='yes')
label.pack_propagate(0)
# put the button on the label with the picture
btn = tk.Button(label, text="press me", command=on_button)
btn.pack(pady=10)
root.mainloop()
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
One way to show a picture with PySide (public PyQT) ...
''' ps_designer_dialog_picture101.py
use the Designer program that comes with the PySide installation,
for instance in C:\Python33\Lib\site-packages\PySide\Designer.exe
1) create a dialog widget
2) put a label on it with a pixmap picture from a file
3) save as mydialog2.ui
the .py, .ui and the picture file should be in the working directory
the .ui file is an xml file you can edit with some care
for instance you can change the name of the picture file
'''
from PySide.QtGui import QApplication
from PySide.QtUiTools import QUiLoader
import sys
def main():
application = QApplication([])
loader = QUiLoader()
dialog = loader.load('mydialog2.ui')
dialog.show()
sys.exit(application.exec_())
if __name__ == '__main__':
main()
Here is the xml file mydialog2.ui created with the PySide Designer program ...
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>30</x>
<y>240</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>22</y>
<width>341</width>
<height>201</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>myline.png</pixmap>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
A simple test for a widget ...
''' ps_test_QLabel_image_scroll.py
test PySide widgets
label with an image on it
QScrollArea class provides a scrolling view onto another widget
for more info see ...
http://srinikom.github.io/pyside-docs/PySide/QtGui/QScrollArea.html
'''
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 = "../image/PorscheBoxster.jpg"
imageLabel = QLabel()
image = QImage(image_file)
imageLabel.setPixmap(QPixmap.fromImage(image))
scrollArea = QScrollArea()
scrollArea.setBackgroundRole(QPalette.Dark)
scrollArea.setWidget(imageLabel)
#scrollArea.ensureVisible(300, 500)
#scrollArea.ensureWidgetVisible(imageLabel, xmargin=150, ymargin=150)
scrollArea.show()
# ---- end of widget test code -----
app.exec_()
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
Sort a listbox in Tkinter ...
'''tk_Listbox_sort1.py
load a Tkinter listbox with data
then sort the data
dns
'''
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
def sort_listbox(event):
# convert the tuple to a list for sorting
data = list(listbox.get(0, 'end'))
print(data) # test
# delete contents of present listbox
listbox.delete(0, 'end')
# load listbox with sorted data
for item in sorted(data):
listbox.insert('end', item)
sort_btn['text'] = "List has been sorted"
# the main window
root = tk.Tk()
root.title("")
# create a button to click for sorting
sort_btn = tk.Button(text="Click to sort listbox")
sort_btn.pack(pady=5)
sort_btn.bind("<Button-1>", sort_listbox)
# create a listbox (height in characters)
listbox = tk.Listbox(root, height=17, bg='yellow')
listbox.pack()
friend_list = [
'Steve', 'Tom', 'Mark', 'Adam', 'Alison', 'Ethel',
'Barb', 'Tiny', 'Tim', 'Pete', 'Sue', 'Zack']
# load the listbox
for item in friend_list:
listbox.insert('end', item)
root.mainloop()
dddomodossola 6 Newbie Poster
Here is an example of my GUI library. It shows an overview of the widgets available, and demostrates the callback usage.
I have already opened a thread about this, but I think that here is a good place also.
Differently from the other examples, this library is fully python coded and provide webserver that allows remote access by means of a browser.
import gui #at https://github.com/dddomodossola/gui
from gui import *
class MyApp(App):
def __init__(self, *args):
super(MyApp, self).__init__(*args)
def main(self):
mainContainer = gui.Widget(600, 530, True, 10)
subContainerLeft = gui.Widget(300, 370, False, 10)
self.img = gui.Image(100, 100, 'logo.png')
self.table = gui.Table(300, 200)
row = gui.TableRow()
item = gui.TableTitle()
item.append(str(id(item)), 'ID')
row.append(str(id(item)), item)
item = gui.TableTitle()
item.append(str(id(item)), 'First Name')
row.append(str(id(item)), item)
item = gui.TableTitle()
item.append(str(id(item)), 'Last Name')
row.append(str(id(item)), item)
self.table.append(str(id(row)), row)
self.add_table_row(self.table, '101', 'Danny', 'Young')
self.add_table_row(self.table, '102', 'Christine', 'Holand')
self.add_table_row(self.table, '103', 'Lars', 'Gordon')
self.add_table_row(self.table, '104', 'Roberto', 'Robitaille')
self.add_table_row(self.table, '105', 'Maria', 'Papadopoulos')
# the arguments are width - height - layoutOrientationOrizontal
subContainerRight = gui.Widget(240, 390, False, 10)
self.lbl = gui.Label(200, 30, 'This is a LABEL!')
self.bt = gui.Button(200, 30, 'Press me!')
# setting the listener for the onclick event of the button
self.bt.set_on_click_listener(self, 'on_button_pressed')
self.txt = gui.TextInput(200, 30)
self.txt.set_text('This is a TEXTAREA')
self.txt.set_on_change_listener(self, 'on_text_area_change')
self.spin = gui.SpinBox(200, 30)
self.spin.set_on_change_listener(self, 'on_spin_change')
self.btInputDiag = gui.Button(200, 30, 'Open InputDialog')
self.btInputDiag.set_on_click_listener(self, 'open_input_dialog')
self.listView = gui.ListView(300, 120)
li0 = gui.ListItem(279, 20, 'Danny Young')
li0.set_on_click_listener(self, 'list_item0_selected')
li1 = gui.ListItem(279, 20, 'Christine Holand')
li1.set_on_click_listener(self, 'list_item1_selected')
li2 = gui.ListItem(279, 20, 'Lars Gordon')
li2.set_on_click_listener(self, 'list_item2_selected')
li3 = gui.ListItem(279, 20, 'Roberto Robitaille')
li3.set_on_click_listener(self, 'list_item3_selected')
self.listView.append('0', li0)
self.listView.append('1', li1)
self.listView.append('2', li2)
self.listView.append('3', li3)
self.dropDown = gui.DropDown(200, 20)
c0 = gui.DropDownItem(200, 20, 'DropDownItem 0')
c1 = gui.DropDownItem(200, 20, 'DropDownItem 1')
self.dropDown.append('0', c0)
self.dropDown.append('1', c1)
self.dropDown.set_on_change_listener(self, 'drop_down_changed')
self.slider = gui.Slider(200, 20, 10, 0, 100, 5)
self.slider.set_on_change_listener(self, 'slider_changed')
self.colorPicker = gui.ColorPicker(200, 20, '#ffbb00')
self.colorPicker.set_on_change_listener(self, 'color_picker_changed')
self.date = gui.Date(200, 20, '2015-04-13')
self.date.set_on_change_listener(self, 'date_changed')
# appending a widget to another, the first argument is a string key
subContainerRight.append('1', self.lbl)
subContainerRight.append('2', self.bt)
subContainerRight.append('3', self.txt)
subContainerRight.append('4', self.spin)
subContainerRight.append('5', self.btInputDiag)
subContainerRight.append('6', self.dropDown)
subContainerRight.append('7', self.slider)
subContainerRight.append('8', self.colorPicker)
subContainerRight.append('9', self.date)
subContainerLeft.append('0', self.img)
subContainerLeft.append('1', self.table)
subContainerLeft.append('2', self.listView)
mainContainer.append('0', subContainerLeft)
mainContainer.append('1', subContainerRight)
# returning the root widget
return mainContainer
def add_table_row(self, table, field1, field2, field3):
row = gui.TableRow()
item = gui.TableItem()
item.append(str(id(item)), field1)
row.append(str(id(item)), item)
item = gui.TableItem()
item.append(str(id(item)), field2)
row.append(str(id(item)), item)
item = gui.TableItem()
item.append(str(id(item)), field3)
row.append(str(id(item)), item)
table.append(str(id(row)), row)
# listener function
def on_button_pressed(self):
self.lbl.set_text('Button pressed!')
self.bt.set_text('Hi!')
def on_text_area_change(self, newValue):
self.lbl.set_text('Text Area value changed!')
def on_spin_change(self, newValue):
self.lbl.set_text('SpinBox changed, new value: ' + str(newValue))
def open_input_dialog(self):
self.inputDialog = gui.InputDialog('Input Dialog', 'Your name?')
self.inputDialog.set_on_confirm_value_listener(
self, 'on_input_dialog_confirm')
# here is returned the Input Dialog widget, and it will be shown
self.inputDialog.show(self)
def on_input_dialog_confirm(self, value):
self.lbl.set_text('Hello ' + value)
def list_item0_selected(self):
self.lbl.set_text('Danny selected')
def list_item1_selected(self):
self.lbl.set_text('Christine selected')
def list_item2_selected(self):
self.lbl.set_text('Lars selected')
def list_item3_selected(self):
self.lbl.set_text('Roberto selected')
def drop_down_changed(self, value):
self.lbl.set_text('New Combo value: ' + value)
def slider_changed(self, value):
self.lbl.set_text('New slider value: ' + str(value))
def color_picker_changed(self, value):
self.lbl.set_text('New color value: ' + value)
def date_changed(self, value):
self.lbl.set_text('New date value: ' + value)
# starts the webserver
start(MyApp)
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
''' tk_entry_textvariable2.py
set the content of an Entry widget via textvariable
use tk.StringVar() and set
'''
try:
# for Python2
import Tkinter as tk
except ImportError:
# for Python3
import tkinter as tk
root = tk.Tk()
# use this to set an initial value in Entry()
# to set value use v.set(value_string)
# to retrieve value use v.get()
v = tk.StringVar()
enter = tk.Entry(root, textvariable=v, bg='yellow', width=80)
enter.pack()
# set entry text
doh = "enter info"
v.set(doh)
# alternative ...
v2 = tk.StringVar(value="new info")
enter2 = tk.Entry(root, textvariable=v2, bg='green', width=80)
enter2.pack()
root.mainloop()
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.