[Tkinter-discuss] Newbie question - displaying data
Lion Kimbro
lionkimbro at gmail.com
Mon Oct 19 19:09:24 CEST 2009
This sounds like a great use for **the canvas widget.**
1. Draw layout with canvas lines and rectangles.
2. Draw text representing sensor readings onto canvas.
3. Refresh display by reconfiguring text, once a second.
The great thing about canvas is that -- once you've got
text placed on it, you can just alter the text via the
canvas.itemconfigure method.
Here's a rendering of your program:
------------------------------------------------------------------------
from tkinter import *
class BasicCanvasFrame1(Canvas):
"""Basic canvas frame.
(Strictly, NOT a Frame -- but we're using it sort of like one.)
For convenience, there is a size parameter offering typical sizes:
320x200 "CGA"
640x480 "VGA"
1024x768 "XGA"
1280x1024 "SVGA"
"FULL" -- full screen mode
For organizing's sake, the BasicCanvasFrame suggests a function,
"draw," for drawing onto it with.
Also, there are some common event registrations, so that you do not
need to register them yourself:
* mouse clicks,
* mouse motion,
* key presses
"""
def __init__(self, title="Untitled Frame",
size="VGA", width=None, height=None,
enable_per_second=False,
master=None,
external_delegate=None):
self.external_delegate = external_delegate
# 1. Initialize Frame
size = size.upper()
if size != "FULL":
if width is None:
width = {"CGA": 320, "VGA": 640,
"XGA": 1024, "SVGA": 1280}[size]
if height is None:
height = {"CGA": 200, "VGA": 480,
"XGA": 768, "SVGA": 1024}[size]
Canvas.__init__(self, master, width=width, height=height)
self.master.title(title)
else:
Canvas.__init__(self, master)
(width, height) = tk_fullscreen(self)
self.configure(width=width, height=height)
self.pack(anchor=N+W, fill='both', expand='yes')
# Fix origin displayer, per:
#
http://tkinter.unpythonic.net/wiki/Widgets/Canvas?highlight=(canvas)
self.xview_moveto(0)
self.yview_moveto(0)
# 2. Bind
self.bind("<Button-1>", self.left_click)
self.bind("<Button-3>", self.right_click)
#self.bind("<Any-KeyPress>", self.keypress)
self.bind_all('<Key>', self.keypress)
self.bind_all('<Key-Alt_L>', self.keypress)
self.bind_all('<Key-Alt_R>', self.keypress)
# self.bind_all('<Key->', self.keypress)
self.bind("<Motion>", self.motion)
# 3. Draw
self.wait_visibility()
self.draw()
if external_delegate is not None:
external_delegate.draw(self)
# 4. Turn on per-second events, if requested
if enable_per_second:
self.after(1000, self._per_second)
def _per_second(self):
self.per_second()
self.after(1000, self._per_second)
def draw(self):
pass
def left_click(self, evt):
pass
def right_click(self, evt):
pass
def keypress(self, evt):
"""Key pressed.
evt.keysym -- super-friendly key symbol
evt.char -- For textual characters, this is the char.
evt.keycode -- For recognizing things like...
"""
pass
def motion(self, evt):
pass
def per_second(self):
pass
class MickSulleysTemperatureSensor(BasicCanvasFrame1):
def __init__(self, **args):
BasicCanvasFrame1.__init__(
self,
title="Mike Sulley's Temperature Sensor",
width=130*3,
height=75*3,
enable_per_second=True)
def draw(self):
self.create_rectangle(45*3,35*3,85*3,55*3, outline="blue")
for (x1,y1,x2,y2) in [(15*3,15*3, 55*3,15*3),
(55*3,15*3, 55*3,35*3),
(15*3,45*3, 45*3,45*3),
(85*3,45*3,105*3,45*3)]:
self.create_line(x1,y1,x2,y2)
self.temperature_item = {}
for (x,y,name) in [( 15*3,15*3, "A"),
( 55*3,35*3, "B"),
( 15*3,45*3, "C"),
( 45*3,45*3, "D"),
( 85*3,45*3, "E"),
(105*3,45*3, "F")]:
text_item = self.create_text(x+5,y+2, text="<"+name+">",
anchor=NW)
self.temperature_item[name] = text_item
def get_temperature(self, sensor_name):
"""Put your code in here."""
import random
return random.randint(72,95)
def per_second(self):
for (sensor_name, text_item) in self.temperature_item.items():
cur_temperature = self.get_temperature(sensor_name)
self.itemconfigure(text_item,
text="%s: %d" % (sensor_name,
cur_temperature))
MickSulleysTemperatureSensor().mainloop()
------------------------------------------------------------------------
(This is longer than is strictly necessary; I'm reusing
BasicCanvasFrame1 from my notes to make this quickly.)
The main points of interest are:
* MickSulleysTemperatureSensor.draw:
(the drawing code)
* MickSulleysTemperatureSensor.per_second:
(the itemconfigure line)
* BasicCanvasFrame1.__init__:
(Canvas initialization, packing code, Canvas.after
initialization)
* BasicCanvasFrame1._per_second:
(Canvas.after continuity)
Feel free to adapt and reuse the code here.
(If you experiment with Canvas, I might suggest using
BasicCanvasFrame1 yourself -- it has made my own
experimentation a lot easier.)
Sincerely,
Lion Kimbro
On Mon, Oct 19, 2009 at 8:29 AM, MickSulley <mick at sulley.info> wrote:
>
> Hi,
>
> I am new to TKinter and struggling somewhat.
>
> I have a Python program that reads a number of temperatures from sensors in
> tanks and pipework, that is working fine. I now want to display those
> temperatures, ideally a simple diagram of the pipework with boxes
> displaying
> the values. I don't need any user input, it just runs forever once started
>
> My initial thought was to use a text widget for the whole page and update
> the areas that show the values.
>
> Is that the best way to do it? Can anyone give me some pointers on
> constructing the program?
>
> Thanks
>
> Mick
> --
> View this message in context:
> http://www.nabble.com/Newbie-question---displaying-data-tp25960335p25960335.html
> Sent from the Python - tkinter-discuss mailing list archive at Nabble.com.
>
> _______________________________________________
> Tkinter-discuss mailing list
> Tkinter-discuss at python.org
> http://mail.python.org/mailman/listinfo/tkinter-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20091019/95db6d84/attachment.htm>
More information about the Tkinter-discuss
mailing list