Tkinter Text widget getting too slow
Michael Peuser
mpeuser at web.de
Fri Sep 5 15:50:16 EDT 2003
More information about the Python-list mailing list
Fri Sep 5 15:50:16 EDT 2003
- Previous message (by thread): Tkinter Text widget getting too slow
- Next message (by thread): Tkinter Text widget getting too slow
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
"Christos TZOTZIOY Georgiou" <tzot at sil-tec.gr> schrieb im Newsbeitrag news:eoselvguf3hvie3s95kjndhtuno0jiu09s at 4ax.com... > On Thu, 4 Sep 2003 03:15:16 +0900, rumours say that "Changjune Kim" > <juneaftn at REMOVETHIShanmail.net> might have written: > > >(I'm interested to see his "extremely fast" text widget, too) > > Notice that Michael Peuser described an "extremely fast" "binary > editor"; I assume a dual view (hex / chars) one. This is not a text > widget --you don't have to account for line feeds and variable width > characters :) Well I have somthing a little bit over 100 lines; I removed the editor part but that is straight forward. No scaling to size up to 1 GB. ----------------------------------- # wckhwex by Michael Peuser May-2003 # Using some ideas from F. Lundh (WCK) # This is Open Source. I will be happy if it could help somebody. versionString="wckhex 0.3 by mpeuser.de" from __future__ import division from Tkinter import * from WCK import Widget, EventMixin from tkFileDialog import askopenfile import mmap class HexView(EventMixin, Widget): """Displays HUGE binary file using memory mapped files """ aCols=10 # address field bCols=2.5*16+1 # binary field cCols=16+1 # ascii field ui_takefocus=1 ui_doublebuffer=0 def __init__(self,root, buffer=None): self.buffer=buffer self.defLines=(len(buffer)+15)//16 self.firstLine=0 # numer of first line in window self.oldFirst=-1 # .. compared to last time self.visLines=1 # visible lines in window self.pix=None # pixmap will be created on resize self.ui_init(root) self.vscroll=Scrolls(self,orient=VERTICAL) self.vscroll.pack(side=RIGHT,fill=Y) self.pack(side=TOP,fill=BOTH,expand=1) self.font=self.ui_font(0,"Courier 10") (self.cWidth, self.lHeight) = self.font.measure("X") def ui_handle_resize(self, width, height): self.height=height self.width= max(width, (self.aCols+1+self.bCols+1+self.cCols)*self.cWidth) # pixel self.visLines=self.height//self.lHeight self.pix=self.ui_pixmap(self.width, self.height) self.vscroll.doScroll() # compute new thumb self.drawPix() def ui_handle_clear(*whatever): pass # no need for clear as is pixmap long enough def ui_handle_repair(self, draw, x0, y0, x1, y1): #if self.pix: draw.paste(self.pix) def onclick(self, ev): self.focus_set() if ev.num==1: pass #XXX implement editor here if ev.num==3: pop=Menu(self,tearoff=0); pop.add_command(label=versionString,state=DISABLED) pop.post(ev.x+self.winfo_rootx(),ev.y+self.winfo_rooty()) def onkey(self, event): todo ={'Down': ("scroll",1,"lines"), 'Up': ('scroll',-1,'lines'), 'Next': ("scroll",1,"pages"), 'Prior':('scroll',-1,'pages')} x=todo.get(event.keysym) print x if x: self.vscroll.doScroll(*x) def bgText(self,x,y,w,h,text,theBrush): "Displays centered text with background color" self.pix.rectangle((x+1,y+1,x+w-2,y+h-2),theBrush) (tw,th)=self.pix.textsize(text,self.font) self.pix.text((x+(w-tw)/2,y+(h-th)/2),text,self.font) def drawPix(self,unchangedSize=0): "Central dawing routine" c=self.pix repair=None whiteBrush=self.ui_brush(0xffffff) yellowBrush=self.ui_brush(0xffff99) grayPen=self.ui_pen(0x999999,2) ww,wh = self.ui_size() h=self.lHeight posX = 0 # speed up scrolling by image blitting, but unclean parametrisation of paste if unchangedSize: ## check if blitting useful linesTBS = self.oldFirst-self.firstLine ## TBS = to be scrolled if 0 < linesTBS < self.visLines/2: ## down, repair top c.paste(c,(0, h*linesTBS)) theRange=range(1,linesTBS+1) c.rectangle((0,h,ww,(linesTBS+1)*h),whiteBrush) c.rectangle((0,h,self.aCols*self.cWidth,(linesTBS+1)*h), yellowBrush) elif 0 < -linesTBS < self.visLines/2: ## up, repair bottom c.paste(c,(0, h*linesTBS)) delta=self.visLines+linesTBS theRange=range(delta-1,self.visLines) c.rectangle((0, delta*h, ww, wh),whiteBrush) c.rectangle((0,delta*h, self.aCols*self.cWidth, wh), yellowBrush) else: unchangedSize=0 # blitting would not make much improvement... self.oldFirst=self.firstLine # remember first line for next time # end of blitting optimization if not unchangedSize: # all new c.rectangle((0,0,ww,wh),whiteBrush) theRange=range(1, self.visLines) c.rectangle((0,h,self.aCols*self.cWidth,wh), yellowBrush) for w, text in \ ((self.aCols,"address"),(self.bCols,"hex"),(self.cCols,"ascii")): w *= self.cWidth if repair!='T': self.bgText(posX, 0, w, h, text, yellowBrush) c.line((posX - 1, 0, posX - 1, wh -1), grayPen) posX+=w # addresses and data posY = self.lHeight for y in theRange: posX = 0 heightY = self.lHeight address=(y-1+self.firstLine)*16 vals = self.buffer[address:address+16] c.text((posX,y*self.lHeight), "%3x.%05x " % divmod(address, 1024*1024), self.font) posX += self.aCols*self.cWidth for vala in range(address,address+16): if vala %8==0: posX+=self.cWidth//2 # some in between space if vala<len(buffer): c.text((posX, y*heightY),"%02x"%ord(buffer[vala]),self.font) posX += 2.5*self.cWidth c.text((posX+10,y*heightY),buffer[address:address+16],self.font) self.ui_damage() self.focus_set() class Scrolls(Scrollbar): "wrapper around Tk scrolbars" def __init__(self,frame,orient=None,**kw): Scrollbar.__init__(self,frame,orient=orient,command=self.doScroll) self.visible=1 # start packed self.theMaster=frame def doScroll(self,a=None,b=None,c=None): m=self.theMaster oldfirst=m.firstLine if a=="scroll": if c=='pages': b=int(b)*m.visLines-1 m.firstLine = oldfirst+int(b) elif a=="moveto": m.firstLine=int(float(b)*(m.defLines+1)) if m.firstLine+m.visLines>m.defLines: # the end m.firstLine=m.defLines-m.visLines+1 if m.firstLine<0: m.firstLine=0 size = m.visLines/m.defLines # 0...1 start= m.firstLine/m.defLines # 0...1 if self.visible: self.set(start,start+size) if oldfirst != m.firstLine: m.drawPix(unchangedSize=1) if __name__ == "__main__": root=Tk() root.iconify() fbb=askopenfile("r+"); assert fbb, "No file" buffer=mmap.mmap(fbb.fileno(),0) s=HexView(root, buffer=buffer) root.title("%s (%6.3f MB)" %(fbb.name, len(buffer)/1024/1024)) root.geometry("720x550+10+10") root.deiconify() root.mainloop() fbb.close() # the End
- Previous message (by thread): Tkinter Text widget getting too slow
- Next message (by thread): Tkinter Text widget getting too slow
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list