Tkinter: how to refresh a canvas without duplicates?

Stewart Midwinter stewart at midtoad.homelinux.org
Sat Feb 28 03:49:25 EST 2004


On Sat, 28 Feb 2004 01:13:36 -0700
Stewart Midwinter <stewart at midtoad.homelinux.org> spake thusly:

> I've got a Tkinter app that draws three histograms.  ...
> 
> I want to redraw the rectangles every time I press the Again button.  This
> works for me, but I get an extra set of rectangles each time I press the Again
> button. How to get rid of this effect?

Ok, answering my own question here, and placing another one.  I realised that my
three histograms are being drawn inside three frames which are children of the
dialog interior. So, there's no easy way to eliminate this interior between
button presses.  I created another frame container, and put all of the stuff I
want to re-draw inside that container.  Then I can destroy that container, and
redraw it.  Works great!

Now the only problem is the Cancel button. It should eliminate my dialog, which
it does if pressed right away.  But if I press the Apply button 3 times, to
redraw the histograms 3 times, I have to press the Cancel button 4 times before
the dialog disappears.  Why is this?

here's my revised code:

---

title = 'Pmw.Dialog demonstration'

# Import Pmw from this directory tree.
import sys
sys.path[:0] = ['../../..']

from Tkinter import *
import Pmw
import random

global canwidth, canheight, sectors, barcolors
sectors = 'SECT_1','SECT_2','SECT_3'
barcolors = 'green','yellow','red','violet'
canwidth = 200
canheight = 20


class Summary:
    def __init__(self, parent):
	# Create the dialog.
	self.dialog = Pmw.Dialog(parent,
	    buttons = ('OK', 'Apply', 'Cancel', 'Help'),
	    defaultbutton = 'OK',
	    title = 'My dialog',
	    command = self.execute)
	self.dialog.withdraw()

	# Add some contents to the dialog.
	w = Label(self.dialog.interior(),
	    text = 'Sector Summary',
	    background = 'black',
	    foreground = 'white',
	    pady = 20)
	w.pack(expand = 1, fill = 'both', padx = 2, pady = 2)
	

    def drawRec(self):
        global row,can, frm
        frm = Frame(self.dialog.interior())
	for sector in sectors:
		row = Frame(frm)
		lab = Label(row, width=10,text=sector)
		can = Canvas(row,
			width=canwidth,
			height=canheight
			)
	
                h=canheight
                m=canwidth-20 # alarm level (100%) is less than available space
for rectangle                d=canwidth/2
                p=random.randrange(-1,2,2) # create random + or - imbalance
                f=random.randrange(-110,110,1)/100.0 # create random fractional
height of bar                w=f*m
                startx=d+f*d
                starty=0
                endx=d
                endy=h
                if (f<-1.0):
                    rcolor='violet'
                elif (-1.0<=f<0.85):
                    rcolor='green'
                elif (0.85<f<=1.0):
                    rcolor='yellow'
                elif (f>1.0):
                    rcolor='red'
                else:
                    rcolor='grey'
               
can.create_rectangle(startx,starty,endx,endy,width=1,fill=rcolor)               
frm.pack(side=TOP, fill=X)                row.pack(side=TOP, fill=X)
                lab.pack(side=LEFT)
                can.pack(side=LEFT, expand=0, padx = 1, pady = 1) #grow
horizontal        self.dialog.activate(globalMode = 'nograb')

    def redrawRec(self):
        self.dialog.deactivate()
        #for i in range(3):
        #sector in sectors:
        frm.destroy()
        self.drawRec()
        self.dialog.activate()
        
    def execute(self, result):
	print 'You clicked on', result
	if result not in ('Apply', 'Help'):
	    self.dialog.deactivate(result)
	    self.dialog.destroy
	if (result =='Apply'):
            self.redrawRec()
            
######################################################################

# Create demo in root window for testing.
if __name__ == '__main__':
    root = Tk()
    #Pmw.initialise(root)
    #root.title(title)

    widget = Summary(root)
    goButton = Button(root, text = 'Again', command = lambda:
widget.redrawRec())    goButton.pack(side = 'bottom')
    exitButton = Button(root, text = 'Exit', command = root.destroy)
    exitButton.pack(side = 'bottom')
    widget.drawRec()
    root.mainloop()

---




More information about the Python-list mailing list