[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