1. 程式人生 > 實用技巧 >python的引用graphics模組報錯解決方案

python的引用graphics模組報錯解決方案

一、安裝python之後,呼叫graphics模組可能會出現如用報錯,這說明就需要安裝或複製檔案graphics.py到安裝目錄下。

>>> from graphics import *
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    from graphics import *
ModuleNotFoundError: No module named 'graphics'

報錯原因:沒有graphics模組,需要到官網上下載graphics.py檔案,放到Python/Lib/site-packages目錄下,如下圖所示:

下載不了的,可以將如下程式碼儲存至graphics.py,放到以上的目錄中

  1 # graphics.py
  2 """Simple object oriented graphics library  
  3 The library is designed to make it very easy for novice programmers to
  4 experiment with computer graphics in an object oriented fashion. It is
  5 written by John Zelle for use with the book "Python Programming: An
6 Introduction to Computer Science" (Franklin, Beedle & Associates). 7 LICENSE: This is open-source software released under the terms of the 8 GPL (http://www.gnu.org/licenses/gpl.html). 9 PLATFORMS: The package is a wrapper around Tkinter and should run on 10 any platform where Tkinter is available.
11 INSTALLATION: Put this file somewhere where Python can see it. 12 OVERVIEW: There are two kinds of objects in the library. The GraphWin 13 class implements a window where drawing can be done and various 14 GraphicsObjects are provided that can be drawn into a GraphWin. As a 15 simple example, here is a complete program to draw a circle of radius 16 10 centered in a 100x100 window: 17 -------------------------------------------------------------------- 18 from graphics import * 19 def main(): 20 win = GraphWin("My Circle", 100, 100) 21 c = Circle(Point(50,50), 10) 22 c.draw(win) 23 win.getMouse() # Pause to view result 24 win.close() # Close window when done 25 main() 26 -------------------------------------------------------------------- 27 GraphWin objects support coordinate transformation through the 28 setCoords method and pointer-based input through getMouse. 29 The library provides the following graphical objects: 30 Point 31 Line 32 Circle 33 Oval 34 Rectangle 35 Polygon 36 Text 37 Entry (for text-based input) 38 Image 39 Various attributes of graphical objects can be set such as 40 outline-color, fill-color and line-width. Graphical objects also 41 support moving and hiding for animation effects. 42 The library also provides a very simple class for pixel-based image 43 manipulation, Pixmap. A pixmap can be loaded from a file and displayed 44 using an Image object. Both getPixel and setPixel methods are provided 45 for manipulating the image. 46 DOCUMENTATION: For complete documentation, see Chapter 4 of "Python 47 Programming: An Introduction to Computer Science" by John Zelle, 48 published by Franklin, Beedle & Associates. Also see 49 http://mcsp.wartburg.edu/zelle/python for a quick reference""" 50 # Version 4.1 12/29/2009 51 # * Merged Pixmap and Image class. Old Pixmap removed, use Image. 52 # Version 4.0.1 10/08/2009 53 # * Modified the autoflush on GraphWin to default to True 54 # * Autoflush check on close, setBackground 55 # * Fixed getMouse to flush pending clicks at entry 56 # Version 4.0 08/2009 57 # * Reverted to non-threaded version. The advantages (robustness, 58 # efficiency, ability to use with other Tk code, etc.) outweigh 59 # the disadvantage that interactive use with IDLE is slightly more 60 # cumbersome. 61 # * Modified to run in either Python 2.x or 3.x (same file). 62 # * Added Image.getPixmap() 63 # * Added update() -- stand alone function to cause any pending 64 # graphics changes to display. 65 # 66 # Version 3.4 10/16/07 67 # Fixed GraphicsError to avoid "exploded" error messages. 68 # Version 3.3 8/8/06 69 # Added checkMouse method to GraphWin 70 # Version 3.2.3 71 # Fixed error in Polygon init spotted by Andrew Harrington 72 # Fixed improper threading in Image constructor 73 # Version 3.2.2 5/30/05 74 # Cleaned up handling of exceptions in Tk thread. The graphics package 75 # now raises an exception if attempt is made to communicate with 76 # a dead Tk thread. 77 # Version 3.2.1 5/22/05 78 # Added shutdown function for tk thread to eliminate race-condition 79 # error "chatter" when main thread terminates 80 # Renamed various private globals with _ 81 # Version 3.2 5/4/05 82 # Added Pixmap object for simple image manipulation. 83 # Version 3.1 4/13/05 84 # Improved the Tk thread communication so that most Tk calls 85 # do not have to wait for synchonization with the Tk thread. 86 # (see _tkCall and _tkExec) 87 # Version 3.0 12/30/04 88 # Implemented Tk event loop in separate thread. Should now work 89 # interactively with IDLE. Undocumented autoflush feature is 90 # no longer necessary. Its default is now False (off). It may 91 # be removed in a future version. 92 # Better handling of errors regarding operations on windows that 93 # have been closed. 94 # Addition of an isClosed method to GraphWindow class. 95 # Version 2.2 8/26/04 96 # Fixed cloning bug reported by Joseph Oldham. 97 # Now implements deep copy of config info. 98 # Version 2.1 1/15/04 99 # Added autoflush option to GraphWin. When True (default) updates on 100 # the window are done after each action. This makes some graphics 101 # intensive programs sluggish. Turning off autoflush causes updates 102 # to happen during idle periods or when flush is called. 103 # Version 2.0 104 # Updated Documentation 105 # Made Polygon accept a list of Points in constructor 106 # Made all drawing functions call TK update for easier animations 107 # and to make the overall package work better with 108 # Python 2.3 and IDLE 1.0 under Windows (still some issues). 109 # Removed vestigial turtle graphics. 110 # Added ability to configure font for Entry objects (analogous to Text) 111 # Added setTextColor for Text as an alias of setFill 112 # Changed to class-style exceptions 113 # Fixed cloning of Text objects 114 # Version 1.6 115 # Fixed Entry so StringVar uses _root as master, solves weird 116 # interaction with shell in Idle 117 # Fixed bug in setCoords. X and Y coordinates can increase in 118 # "non-intuitive" direction. 119 # Tweaked wm_protocol so window is not resizable and kill box closes. 120 # Version 1.5 121 # Fixed bug in Entry. Can now define entry before creating a 122 # GraphWin. All GraphWins are now toplevel windows and share 123 # a fixed root (called _root). 124 # Version 1.4 125 # Fixed Garbage collection of Tkinter images bug. 126 # Added ability to set text atttributes. 127 # Added Entry boxes. 128 import time, os, sys 129 try: # import as appropriate for 2.x vs. 3.x 130 import tkinter as tk 131 except: 132 import Tkinter as tk 133 ########################################################################## 134 # Module Exceptions 135 class GraphicsError(Exception): 136 """Generic error class for graphics module exceptions.""" 137 pass 138 OBJ_ALREADY_DRAWN = "Object currently drawn" 139 UNSUPPORTED_METHOD = "Object doesn't support operation" 140 BAD_OPTION = "Illegal option value" 141 DEAD_THREAD = "Graphics thread quit unexpectedly" 142 _root = tk.Tk() 143 _root.withdraw() 144 def update(): 145 _root.update() 146 ############################################################################ 147 # Graphics classes start here 148 149 class GraphWin(tk.Canvas): 150 """A GraphWin is a toplevel window for displaying graphics.""" 151 def __init__(self, title="Graphics Window", 152 width=200, height=200, autoflush=True): 153 master = tk.Toplevel(_root) 154 master.protocol("WM_DELETE_WINDOW", self.close) 155 tk.Canvas.__init__(self, master, width=width, height=height) 156 self.master.title(title) 157 self.pack() 158 master.resizable(0,0) 159 self.foreground = "black" 160 self.items = [] 161 self.mouseX = None 162 self.mouseY = None 163 self.bind("<Button-1>", self._onClick) 164 self.height = height 165 self.width = width 166 self.autoflush = autoflush 167 self._mouseCallback = None 168 self.trans = None 169 self.closed = False 170 master.lift() 171 if autoflush: _root.update() 172 173 def __checkOpen(self): 174 if self.closed: 175 raise GraphicsError("window is closed") 176 def setBackground(self, color): 177 """Set background color of the window""" 178 self.__checkOpen() 179 self.config(bg=color) 180 self.__autoflush() 181 182 def setCoords(self, x1, y1, x2, y2): 183 """Set coordinates of window to run from (x1,y1) in the 184 lower-left corner to (x2,y2) in the upper-right corner.""" 185 self.trans = Transform(self.width, self.height, x1, y1, x2, y2) 186 def close(self): 187 """Close the window""" 188 if self.closed: return 189 self.closed = True 190 self.master.destroy() 191 self.__autoflush() 192 def isClosed(self): 193 return self.closed 194 def isOpen(self): 195 return not self.closed 196 def __autoflush(self): 197 if self.autoflush: 198 _root.update() 199 200 def plot(self, x, y, color="black"): 201 """Set pixel (x,y) to the given color""" 202 self.__checkOpen() 203 xs,ys = self.toScreen(x,y) 204 self.create_line(xs,ys,xs+1,ys, fill=color) 205 self.__autoflush() 206 207 def plotPixel(self, x, y, color="black"): 208 """Set pixel raw (independent of window coordinates) pixel 209 (x,y) to color""" 210 self.__checkOpen() 211 self.create_line(x,y,x+1,y, fill=color) 212 self.__autoflush() 213 214 def flush(self): 215 """Update drawing to the window""" 216 self.__checkOpen() 217 self.update_idletasks() 218 219 def getMouse(self): 220 """Wait for mouse click and return Point object representing 221 the click""" 222 self.update() # flush any prior clicks 223 self.mouseX = None 224 self.mouseY = None 225 while self.mouseX == None or self.mouseY == None: 226 self.update() 227 if self.isClosed(): raise GraphicsError("getMouse in closed window") 228 time.sleep(.1) # give up thread 229 x,y = self.toWorld(self.mouseX, self.mouseY) 230 self.mouseX = None 231 self.mouseY = None 232 return Point(x,y) 233 def checkMouse(self): 234 """Return last mouse click or None if mouse has 235 not been clicked since last call""" 236 if self.isClosed(): 237 raise GraphicsError("checkMouse in closed window") 238 self.update() 239 if self.mouseX != None and self.mouseY != None: 240 x,y = self.toWorld(self.mouseX, self.mouseY) 241 self.mouseX = None 242 self.mouseY = None 243 return Point(x,y) 244 else: 245 return None 246 247 def getHeight(self): 248 """Return the height of the window""" 249 return self.height 250 251 def getWidth(self): 252 """Return the width of the window""" 253 return self.width 254 255 def toScreen(self, x, y): 256 trans = self.trans 257 if trans: 258 return self.trans.screen(x,y) 259 else: 260 return x,y 261 262 def toWorld(self, x, y): 263 trans = self.trans 264 if trans: 265 return self.trans.world(x,y) 266 else: 267 return x,y 268 269 def setMouseHandler(self, func): 270 self._mouseCallback = func 271 272 def _onClick(self, e): 273 self.mouseX = e.x 274 self.mouseY = e.y 275 if self._mouseCallback: 276 self._mouseCallback(Point(e.x, e.y)) 277 278 class Transform: 279 """Internal class for 2-D coordinate transformations""" 280 281 def __init__(self, w, h, xlow, ylow, xhigh, yhigh): 282 # w, h are width and height of window 283 # (xlow,ylow) coordinates of lower-left [raw (0,h-1)] 284 # (xhigh,yhigh) coordinates of upper-right [raw (w-1,0)] 285 xspan = (xhigh-xlow) 286 yspan = (yhigh-ylow) 287 self.xbase = xlow 288 self.ybase = yhigh 289 self.xscale = xspan/float(w-1) 290 self.yscale = yspan/float(h-1) 291 292 def screen(self,x,y): 293 # Returns x,y in screen (actually window) coordinates 294 xs = (x-self.xbase) / self.xscale 295 ys = (self.ybase-y) / self.yscale 296 return int(xs+0.5),int(ys+0.5) 297 298 def world(self,xs,ys): 299 # Returns xs,ys in world coordinates 300 x = xs*self.xscale + self.xbase 301 y = self.ybase - ys*self.yscale 302 return x,y 303 # Default values for various item configuration options. Only a subset of 304 # keys may be present in the configuration dictionary for a given item 305 DEFAULT_CONFIG = {"fill":"", 306 "outline":"black", 307 "width":"1", 308 "arrow":"none", 309 "text":"", 310 "justify":"center", 311 "font": ("helvetica", 12, "normal")} 312 class GraphicsObject: 313 """Generic base class for all of the drawable objects""" 314 # A subclass of GraphicsObject should override _draw and 315 # and _move methods. 316 317 def __init__(self, options): 318 # options is a list of strings indicating which options are 319 # legal for this object. 320 321 # When an object is drawn, canvas is set to the GraphWin(canvas) 322 # object where it is drawn and id is the TK identifier of the 323 # drawn shape. 324 self.canvas = None 325 self.id = None 326 # config is the dictionary of configuration options for the widget. 327 config = {} 328 for option in options: 329 config[option] = DEFAULT_CONFIG[option] 330 self.config = config 331 332 def setFill(self, color): 333 """Set interior color to color""" 334 self._reconfig("fill", color) 335 336 def setOutline(self, color): 337 """Set outline color to color""" 338 self._reconfig("outline", color) 339 340 def setWidth(self, width): 341 """Set line weight to width""" 342 self._reconfig("width", width) 343 def draw(self, graphwin): 344 """Draw the object in graphwin, which should be a GraphWin 345 object. A GraphicsObject may only be drawn into one 346 window. Raises an error if attempt made to draw an object that 347 is already visible.""" 348 if self.canvas and not self.canvas.isClosed(): raise GraphicsError(OBJ_ALREADY_DRAWN) 349 if graphwin.isClosed(): raise GraphicsError("Can't draw to closed window") 350 self.canvas = graphwin 351 self.id = self._draw(graphwin, self.config) 352 if graphwin.autoflush: 353 _root.update() 354 355 def undraw(self): 356 """Undraw the object (i.e. hide it). Returns silently if the 357 object is not currently drawn.""" 358 359 if not self.canvas: return 360 if not self.canvas.isClosed(): 361 self.canvas.delete(self.id) 362 if self.canvas.autoflush: 363 _root.update() 364 self.canvas = None 365 self.id = None 366 def move(self, dx, dy): 367 """move object dx units in x direction and dy units in y 368 direction""" 369 370 self._move(dx,dy) 371 canvas = self.canvas 372 if canvas and not canvas.isClosed(): 373 trans = canvas.trans 374 if trans: 375 x = dx/ trans.xscale 376 y = -dy / trans.yscale 377 else: 378 x = dx 379 y = dy 380 self.canvas.move(self.id, x, y) 381 if canvas.autoflush: 382 _root.update() 383 384 def _reconfig(self, option, setting): 385 # Internal method for changing configuration of the object 386 # Raises an error if the option does not exist in the config 387 # dictionary for this object 388 if option not in self.config: 389 raise GraphicsError(UNSUPPORTED_METHOD) 390 options = self.config 391 options[option] = setting 392 if self.canvas and not self.canvas.isClosed(): 393 self.canvas.itemconfig(self.id, options) 394 if self.canvas.autoflush: 395 _root.update() 396 def _draw(self, canvas, options): 397 """draws appropriate figure on canvas with options provided 398 Returns Tk id of item drawn""" 399 pass # must override in subclass 400 def _move(self, dx, dy): 401 """updates internal state of object to move it dx,dy units""" 402 pass # must override in subclass 403 404 class Point(GraphicsObject): 405 def __init__(self, x, y): 406 GraphicsObject.__init__(self, ["outline", "fill"]) 407 self.setFill = self.setOutline 408 self.x = x 409 self.y = y 410 411 def _draw(self, canvas, options): 412 x,y = canvas.toScreen(self.x,self.y) 413 return canvas.create_rectangle(x,y,x+1,y+1,options) 414 415 def _move(self, dx, dy): 416 self.x = self.x + dx 417 self.y = self.y + dy 418 419 def clone(self): 420 other = Point(self.x,self.y) 421 other.config = self.config.copy() 422 return other 423 424 def getX(self): return self.x 425 def getY(self): return self.y 426 class _BBox(GraphicsObject): 427 # Internal base class for objects represented by bounding box 428 # (opposite corners) Line segment is a degenerate case. 429 430 def __init__(self, p1, p2, options=["outline","width","fill"]): 431 GraphicsObject.__init__(self, options) 432 self.p1 = p1.clone() 433 self.p2 = p2.clone() 434 def _move(self, dx, dy): 435 self.p1.x = self.p1.x + dx 436 self.p1.y = self.p1.y + dy 437 self.p2.x = self.p2.x + dx 438 self.p2.y = self.p2.y + dy 439 440 def getP1(self): return self.p1.clone() 441 def getP2(self): return self.p2.clone() 442 443 def getCenter(self): 444 p1 = self.p1 445 p2 = self.p2 446 return Point((p1.x+p2.x)/2.0, (p1.y+p2.y)/2.0) 447 448 class Rectangle(_BBox): 449 450 def __init__(self, p1, p2): 451 _BBox.__init__(self, p1, p2) 452 453 def _draw(self, canvas, options): 454 p1 = self.p1 455 p2 = self.p2 456 x1,y1 = canvas.toScreen(p1.x,p1.y) 457 x2,y2 = canvas.toScreen(p2.x,p2.y) 458 return canvas.create_rectangle(x1,y1,x2,y2,options) 459 460 def clone(self): 461 other = Rectangle(self.p1, self.p2) 462 other.config = self.config.copy() 463 return other 464 465 class Oval(_BBox): 466 467 def __init__(self, p1, p2): 468 _BBox.__init__(self, p1, p2) 469 470 def clone(self): 471 other = Oval(self.p1, self.p2) 472 other.config = self.config.copy() 473 return other 474 475 def _draw(self, canvas, options): 476 p1 = self.p1 477 p2 = self.p2 478 x1,y1 = canvas.toScreen(p1.x,p1.y) 479 x2,y2 = canvas.toScreen(p2.x,p2.y) 480 return canvas.create_oval(x1,y1,x2,y2,options) 481 482 class Circle(Oval): 483 484 def __init__(self, center, radius): 485 p1 = Point(center.x-radius, center.y-radius) 486 p2 = Point(center.x+radius, center.y+radius) 487 Oval.__init__(self, p1, p2) 488 self.radius = radius 489 490 def clone(self): 491 other = Circle(self.getCenter(), self.radius) 492 other.config = self.config.copy() 493 return other 494 495 def getRadius(self): 496 return self.radius 497 498 class Line(_BBox): 499 500 def __init__(self, p1, p2): 501 _BBox.__init__(self, p1, p2, ["arrow","fill","width"]) 502 self.setFill(DEFAULT_CONFIG['outline']) 503 self.setOutline = self.setFill 504 505 def clone(self): 506 other = Line(self.p1, self.p2) 507 other.config = self.config.copy() 508 return other 509 510 def _draw(self, canvas, options): 511 p1 = self.p1 512 p2 = self.p2 513 x1,y1 = canvas.toScreen(p1.x,p1.y) 514 x2,y2 = canvas.toScreen(p2.x,p2.y) 515 return canvas.create_line(x1,y1,x2,y2,options) 516 517 def setArrow(self, option): 518 if not option in ["first","last","both","none"]: 519 raise GraphicsError(BAD_OPTION) 520 self._reconfig("arrow", option) 521 522 class Polygon(GraphicsObject): 523 524 def __init__(self, *points): 525 # if points passed as a list, extract it 526 if len(points) == 1 and type(points[0]) == type([]): 527 points = points[0] 528 self.points = list(map(Point.clone, points)) 529 GraphicsObject.__init__(self, ["outline", "width", "fill"]) 530 531 def clone(self): 532 other = Polygon(*self.points) 533 other.config = self.config.copy() 534 return other 535 def getPoints(self): 536 return list(map(Point.clone, self.points)) 537 def _move(self, dx, dy): 538 for p in self.points: 539 p.move(dx,dy) 540 541 def _draw(self, canvas, options): 542 args = [canvas] 543 for p in self.points: 544 x,y = canvas.toScreen(p.x,p.y) 545 args.append(x) 546 args.append(y) 547 args.append(options) 548 return GraphWin.create_polygon(*args) 549 class Text(GraphicsObject): 550 551 def __init__(self, p, text): 552 GraphicsObject.__init__(self, ["justify","fill","text","font"]) 553 self.setText(text) 554 self.anchor = p.clone() 555 self.setFill(DEFAULT_CONFIG['outline']) 556 self.setOutline = self.setFill 557 558 def _draw(self, canvas, options): 559 p = self.anchor 560 x,y = canvas.toScreen(p.x,p.y) 561 return canvas.create_text(x,y,options) 562 563 def _move(self, dx, dy): 564 self.anchor.move(dx,dy) 565 566 def clone(self): 567 other = Text(self.anchor, self.config['text']) 568 other.config = self.config.copy() 569 return other 570 def setText(self,text): 571 self._reconfig("text", text) 572 573 def getText(self): 574 return self.config["text"] 575 576 def getAnchor(self): 577 return self.anchor.clone() 578 def setFace(self, face): 579 if face in ['helvetica','arial','courier','times roman']: 580 f,s,b = self.config['font'] 581 self._reconfig("font",(face,s,b)) 582 else: 583 raise GraphicsError(BAD_OPTION) 584 def setSize(self, size): 585 if 5 <= size <= 36: 586 f,s,b = self.config['font'] 587 self._reconfig("font", (f,size,b)) 588 else: 589 raise GraphicsError(BAD_OPTION) 590 def setStyle(self, style): 591 if style in ['bold','normal','italic', 'bold italic']: 592 f,s,b = self.config['font'] 593 self._reconfig("font", (f,s,style)) 594 else: 595 raise GraphicsError(BAD_OPTION) 596 def setTextColor(self, color): 597 self.setFill(color) 598 class Entry(GraphicsObject): 599 def __init__(self, p, width): 600 GraphicsObject.__init__(self, []) 601 self.anchor = p.clone() 602 #print self.anchor 603 self.width = width 604 self.text = tk.StringVar(_root) 605 self.text.set("") 606 self.fill = "gray" 607 self.color = "black" 608 self.font = DEFAULT_CONFIG['font'] 609 self.entry = None 610 def _draw(self, canvas, options): 611 p = self.anchor 612 x,y = canvas.toScreen(p.x,p.y) 613 frm = tk.Frame(canvas.master) 614 self.entry = tk.Entry(frm, 615 width=self.width, 616 textvariable=self.text, 617 bg = self.fill, 618 fg = self.color, 619 font=self.font) 620 self.entry.pack() 621 #self.setFill(self.fill) 622 return canvas.create_window(x,y,window=frm) 623 def getText(self): 624 return self.text.get() 625 def _move(self, dx, dy): 626 self.anchor.move(dx,dy) 627 def getAnchor(self): 628 return self.anchor.clone() 629 def clone(self): 630 other = Entry(self.anchor, self.width) 631 other.config = self.config.copy() 632 other.text = tk.StringVar() 633 other.text.set(self.text.get()) 634 other.fill = self.fill 635 return other 636 def setText(self, t): 637 self.text.set(t) 638 639 def setFill(self, color): 640 self.fill = color 641 if self.entry: 642 self.entry.config(bg=color) 643 644 def _setFontComponent(self, which, value): 645 font = list(self.font) 646 font[which] = value 647 self.font = tuple(font) 648 if self.entry: 649 self.entry.config(font=self.font) 650 def setFace(self, face): 651 if face in ['helvetica','arial','courier','times roman']: 652 self._setFontComponent(0, face) 653 else: 654 raise GraphicsError(BAD_OPTION) 655 def setSize(self, size): 656 if 5 <= size <= 36: 657 self._setFontComponent(1,size) 658 else: 659 raise GraphicsError(BAD_OPTION) 660 def setStyle(self, style): 661 if style in ['bold','normal','italic', 'bold italic']: 662 self._setFontComponent(2,style) 663 else: 664 raise GraphicsError(BAD_OPTION) 665 def setTextColor(self, color): 666 self.color=color 667 if self.entry: 668 self.entry.config(fg=color) 669 class Image(GraphicsObject): 670 idCount = 0 671 imageCache = {} # tk photoimages go here to avoid GC while drawn 672 673 def __init__(self, p, *pixmap): 674 GraphicsObject.__init__(self, []) 675 self.anchor = p.clone() 676 self.imageId = Image.idCount 677 Image.idCount = Image.idCount + 1 678 if len(pixmap) == 1: # file name provided 679 self.img = tk.PhotoImage(file=pixmap[0], master=_root) 680 else: # width and height provided 681 width, height = pixmap 682 self.img = tk.PhotoImage(master=_root, width=width, height=height) 683 684 def _draw(self, canvas, options): 685 p = self.anchor 686 x,y = canvas.toScreen(p.x,p.y) 687 self.imageCache[self.imageId] = self.img # save a reference 688 return canvas.create_image(x,y,image=self.img) 689 690 def _move(self, dx, dy): 691 self.anchor.move(dx,dy) 692 693 def undraw(self): 694 del self.imageCache[self.imageId] # allow gc of tk photoimage 695 GraphicsObject.undraw(self) 696 def getAnchor(self): 697 return self.anchor.clone() 698 699 def clone(self): 700 other = Image(Point(0,0), 0, 0) 701 other.img = self.img.copy() 702 other.anchor = self.anchor.clone() 703 other.config = self.config.copy() 704 return other 705 def getWidth(self): 706 """Returns the width of the image in pixels""" 707 return self.img.width() 708 def getHeight(self): 709 """Returns the height of the image in pixels""" 710 return self.img.height() 711 def getPixel(self, x, y): 712 """Returns a list [r,g,b] with the RGB color values for pixel (x,y) 713 r,g,b are in range(256) 714 """ 715 716 value = self.img.get(x,y) 717 if type(value) == type(0): 718 return [value, value, value] 719 else: 720 return list(map(int, value.split())) 721 def setPixel(self, x, y, color): 722 """Sets pixel (x,y) to the given color 723 724 """ 725 self.img.put("{" + color +"}", (x, y)) 726 727 def save(self, filename): 728 """Saves the pixmap image to filename. 729 The format for the save image is determined from the filname extension. 730 """ 731 732 path, name = os.path.split(filename) 733 ext = name.split(".")[-1] 734 self.img.write( filename, format=ext) 735 736 def color_rgb(r,g,b): 737 """r,g,b are intensities of red, green, and blue in range(256) 738 Returns color specifier string for the resulting color""" 739 return "#%02x%02x%02x" % (r,g,b) 740 def test(): 741 win = GraphWin() 742 win.setCoords(0,0,10,10) 743 t = Text(Point(5,5), "Centered Text") 744 t.draw(win) 745 p = Polygon(Point(1,1), Point(5,3), Point(2,7)) 746 p.draw(win) 747 e = Entry(Point(5,6), 10) 748 e.draw(win) 749 win.getMouse() 750 p.setFill("red") 751 p.setOutline("blue") 752 p.setWidth(2) 753 s = "" 754 for pt in p.getPoints(): 755 s = s + "(%0.1f,%0.1f) " % (pt.getX(), pt.getY()) 756 t.setText(e.getText()) 757 e.setFill("green") 758 e.setText("Spam!") 759 e.move(2,0) 760 win.getMouse() 761 p.move(2,3) 762 s = "" 763 for pt in p.getPoints(): 764 s = s + "(%0.1f,%0.1f) " % (pt.getX(), pt.getY()) 765 t.setText(s) 766 win.getMouse() 767 p.undraw() 768 e.undraw() 769 t.setStyle("bold") 770 win.getMouse() 771 t.setStyle("normal") 772 win.getMouse() 773 t.setStyle("italic") 774 win.getMouse() 775 t.setStyle("bold italic") 776 win.getMouse() 777 t.setSize(14) 778 win.getMouse() 779 t.setFace("arial") 780 t.setSize(20) 781 win.getMouse() 782 win.close() 783 if __name__ == "__main__": 784 test()