diff --git a/Graph.py b/Graph.py deleted file mode 100644 index 5a7b1cd..0000000 --- a/Graph.py +++ /dev/null @@ -1,15 +0,0 @@ -from graphics import * - -class Graph(object): - - def __init__(self, p_width, p_height, p_name): - self.win = GraphWin("perceptron", p_width, p_height) - self.win.setCoords(0, 0, 640, 480) - self.x_offset = p_width / 2 - self.y_offset = p_height / 2 - self.win.setCoords(0, 0, 640, 480) - Line(Point(0, p_height / 2), Point(p_width, p_height / 2)).draw(self.win) - Line(Point(p_width / 2, 0), Point(p_width / 2, p_height)).draw(self.win) - - def drawLine(self, p_point1, p_point2): - Line(p_point1, p_point2).draw(self.win).move(self.x_offset, self.y_offset) diff --git a/Main.py b/Main.py index 4bce33d..1b34499 100644 --- a/Main.py +++ b/Main.py @@ -1,17 +1,14 @@ from Perceptron import Perceptron from random import Random from Dataset import Dataset -from Graph import * - -graph = Graph(640, 480, "Perceptron") -graph.drawLine(Point(-1000, -1000 + 20), Point(1000, 1000 + 20)) rand = Random() -data = Dataset(open("input.txt").read().split('\n'), open("target.txt").read().split('\n')) +#data = Dataset(open("input.txt").read().split('\n'), +# open("target.txt").read().split('\n')) learn_rate = 0.01 p = Perceptron() -i = data.inputs +#i = data.inputs def line_perceptron(): @@ -40,10 +37,8 @@ def line_perceptron(): y = int(input("y: ")) p.input(x, y) if p.activation() == 1: - graph.win.plot(x, y, "green") print("TRUE") else: - graph.win.plot(x, y, "red") print("FALSE") diff --git a/graphics.py b/graphics.py deleted file mode 100644 index d59d796..0000000 --- a/graphics.py +++ /dev/null @@ -1,1001 +0,0 @@ -# graphics.py -"""Simple object oriented graphics library - -The library is designed to make it very easy for novice programmers to -experiment with computer graphics in an object oriented fashion. It is -written by John Zelle for use with the book "Python Programming: An -Introduction to Computer Science" (Franklin, Beedle & Associates). - -LICENSE: This is open-source software released under the terms of the -GPL (http://www.gnu.org/licenses/gpl.html). - -PLATFORMS: The package is a wrapper around Tkinter and should run on -any platform where Tkinter is available. - -INSTALLATION: Put this file somewhere where Python can see it. - -OVERVIEW: There are two kinds of objects in the library. The GraphWin -class implements a window where drawing can be done and various -GraphicsObjects are provided that can be drawn into a GraphWin. As a -simple example, here is a complete program to draw a circle of radius -10 centered in a 100x100 window: - --------------------------------------------------------------------- -from graphics import * - -def main(): - win = GraphWin("My Circle", 100, 100) - c = Circle(Point(50,50), 10) - c.draw(win) - win.getMouse() # Pause to view result - win.close() # Close window when done - -main() --------------------------------------------------------------------- -GraphWin objects support coordinate transformation through the -setCoords method and mouse and keyboard interaction methods. - -The library provides the following graphical objects: - Point - Line - Circle - Oval - Rectangle - Polygon - Text - Entry (for text-based input) - Image - -Various attributes of graphical objects can be set such as -outline-color, fill-color and line-width. Graphical objects also -support moving and hiding for animation effects. - -The library also provides a very simple class for pixel-based image -manipulation, Pixmap. A pixmap can be loaded from a file and displayed -using an Image object. Both getPixel and setPixel methods are provided -for manipulating the image. - -DOCUMENTATION: For complete documentation, see Chapter 4 of "Python -Programming: An Introduction to Computer Science" by John Zelle, -published by Franklin, Beedle & Associates. Also see -http://mcsp.wartburg.edu/zelle/python for a quick reference""" - -__version__ = "5.0" - -# Version 5 8/26/2016 -# * update at bottom to fix MacOS issue causing askopenfile() to hang -# * update takes an optional parameter specifying update rate -# * Entry objects get focus when drawn -# * __repr_ for all objects -# * fixed offset problem in window, made canvas borderless - -# Version 4.3 4/25/2014 -# * Fixed Image getPixel to work with Python 3.4, TK 8.6 (tuple type handling) -# * Added interactive keyboard input (getKey and checkKey) to GraphWin -# * Modified setCoords to cause redraw of current objects, thus -# changing the view. This supports scrolling around via setCoords. -# -# Version 4.2 5/26/2011 -# * Modified Image to allow multiple undraws like other GraphicsObjects -# Version 4.1 12/29/2009 -# * Merged Pixmap and Image class. Old Pixmap removed, use Image. -# Version 4.0.1 10/08/2009 -# * Modified the autoflush on GraphWin to default to True -# * Autoflush check on close, setBackground -# * Fixed getMouse to flush pending clicks at entry -# Version 4.0 08/2009 -# * Reverted to non-threaded version. The advantages (robustness, -# efficiency, ability to use with other Tk code, etc.) outweigh -# the disadvantage that interactive use with IDLE is slightly more -# cumbersome. -# * Modified to run in either Python 2.x or 3.x (same file). -# * Added Image.getPixmap() -# * Added update() -- stand alone function to cause any pending -# graphics changes to display. -# -# Version 3.4 10/16/07 -# Fixed GraphicsError to avoid "exploded" error messages. -# Version 3.3 8/8/06 -# Added checkMouse method to GraphWin -# Version 3.2.3 -# Fixed error in Polygon init spotted by Andrew Harrington -# Fixed improper threading in Image constructor -# Version 3.2.2 5/30/05 -# Cleaned up handling of exceptions in Tk thread. The graphics package -# now raises an exception if attempt is made to communicate with -# a dead Tk thread. -# Version 3.2.1 5/22/05 -# Added shutdown function for tk thread to eliminate race-condition -# error "chatter" when main thread terminates -# Renamed various private globals with _ -# Version 3.2 5/4/05 -# Added Pixmap object for simple image manipulation. -# Version 3.1 4/13/05 -# Improved the Tk thread communication so that most Tk calls -# do not have to wait for synchonization with the Tk thread. -# (see _tkCall and _tkExec) -# Version 3.0 12/30/04 -# Implemented Tk event loop in separate thread. Should now work -# interactively with IDLE. Undocumented autoflush feature is -# no longer necessary. Its default is now False (off). It may -# be removed in a future version. -# Better handling of errors regarding operations on windows that -# have been closed. -# Addition of an isClosed method to GraphWindow class. - -# Version 2.2 8/26/04 -# Fixed cloning bug reported by Joseph Oldham. -# Now implements deep copy of config info. -# Version 2.1 1/15/04 -# Added autoflush option to GraphWin. When True (default) updates on -# the window are done after each action. This makes some graphics -# intensive programs sluggish. Turning off autoflush causes updates -# to happen during idle periods or when flush is called. -# Version 2.0 -# Updated Documentation -# Made Polygon accept a list of Points in constructor -# Made all drawing functions call TK update for easier animations -# and to make the overall package work better with -# Python 2.3 and IDLE 1.0 under Windows (still some issues). -# Removed vestigial turtle graphics. -# Added ability to configure font for Entry objects (analogous to Text) -# Added setTextColor for Text as an alias of setFill -# Changed to class-style exceptions -# Fixed cloning of Text objects - -# Version 1.6 -# Fixed Entry so StringVar uses _root as master, solves weird -# interaction with shell in Idle -# Fixed bug in setCoords. X and Y coordinates can increase in -# "non-intuitive" direction. -# Tweaked wm_protocol so window is not resizable and kill box closes. - -# Version 1.5 -# Fixed bug in Entry. Can now define entry before creating a -# GraphWin. All GraphWins are now toplevel windows and share -# a fixed root (called _root). - -# Version 1.4 -# Fixed Garbage collection of Tkinter images bug. -# Added ability to set text atttributes. -# Added Entry boxes. - -import time, os, sys - -try: # import as appropriate for 2.x vs. 3.x - import tkinter as tk -except: - import Tkinter as tk - - -########################################################################## -# Module Exceptions - -class GraphicsError(Exception): - """Generic error class for graphics module exceptions.""" - pass - - -OBJ_ALREADY_DRAWN = "Object currently drawn" -UNSUPPORTED_METHOD = "Object doesn't support operation" -BAD_OPTION = "Illegal option value" - -########################################################################## -# global variables and funtions - -_root = tk.Tk() -_root.withdraw() - -_update_lasttime = time.time() - - -def update(rate=None): - global _update_lasttime - if rate: - now = time.time() - pauseLength = 1 / rate - (now - _update_lasttime) - if pauseLength > 0: - time.sleep(pauseLength) - _update_lasttime = now + pauseLength - else: - _update_lasttime = now - - _root.update() - - -############################################################################ -# Graphics classes start here - -class GraphWin(tk.Canvas): - """A GraphWin is a toplevel window for displaying graphics.""" - - def __init__(self, title="Graphics Window", - width=200, height=200, autoflush=True): - assert type(title) == type(""), "Title must be a string" - master = tk.Toplevel(_root) - master.protocol("WM_DELETE_WINDOW", self.close) - tk.Canvas.__init__(self, master, width=width, height=height, - highlightthickness=0, bd=0) - self.master.title(title) - self.pack() - master.resizable(0, 0) - self.foreground = "black" - self.items = [] - self.mouseX = None - self.mouseY = None - self.bind("", self._onClick) - self.bind_all("", self._onKey) - self.height = int(height) - self.width = int(width) - self.autoflush = autoflush - self._mouseCallback = None - self.trans = None - self.closed = False - master.lift() - self.lastKey = "" - if autoflush: _root.update() - - def __repr__(self): - if self.isClosed(): - return "" - else: - return "GraphWin('{}', {}, {})".format(self.master.title(), - self.getWidth(), - self.getHeight()) - - def __str__(self): - return repr(self) - - def __checkOpen(self): - if self.closed: - raise GraphicsError("window is closed") - - def _onKey(self, evnt): - self.lastKey = evnt.keysym - - def setBackground(self, color): - """Set background color of the window""" - self.__checkOpen() - self.config(bg=color) - self.__autoflush() - - def setCoords(self, x1, y1, x2, y2): - """Set coordinates of window to run from (x1,y1) in the - lower-left corner to (x2,y2) in the upper-right corner.""" - self.trans = Transform(self.width, self.height, x1, y1, x2, y2) - self.redraw() - - def close(self): - """Close the window""" - - if self.closed: return - self.closed = True - self.master.destroy() - self.__autoflush() - - def isClosed(self): - return self.closed - - def isOpen(self): - return not self.closed - - def __autoflush(self): - if self.autoflush: - _root.update() - - def plot(self, x, y, color="black"): - """Set pixel (x,y) to the given color""" - self.__checkOpen() - xs, ys = self.toScreen(x, y) - self.create_line(xs, ys, xs + 1, ys, fill=color) - self.__autoflush() - - def plotPixel(self, x, y, color="black"): - """Set pixel raw (independent of window coordinates) pixel - (x,y) to color""" - self.__checkOpen() - self.create_line(x, y, x + 1, y, fill=color) - self.__autoflush() - - def flush(self): - """Update drawing to the window""" - self.__checkOpen() - self.update_idletasks() - - def getMouse(self): - """Wait for mouse click and return Point object representing - the click""" - self.update() # flush any prior clicks - self.mouseX = None - self.mouseY = None - while self.mouseX == None or self.mouseY == None: - self.update() - if self.isClosed(): raise GraphicsError("getMouse in closed window") - time.sleep(.1) # give up thread - x, y = self.toWorld(self.mouseX, self.mouseY) - self.mouseX = None - self.mouseY = None - return Point(x, y) - - def checkMouse(self): - """Return last mouse click or None if mouse has - not been clicked since last call""" - if self.isClosed(): - raise GraphicsError("checkMouse in closed window") - self.update() - if self.mouseX != None and self.mouseY != None: - x, y = self.toWorld(self.mouseX, self.mouseY) - self.mouseX = None - self.mouseY = None - return Point(x, y) - else: - return None - - def getKey(self): - """Wait for user to press a key and return it as a string.""" - self.lastKey = "" - while self.lastKey == "": - self.update() - if self.isClosed(): raise GraphicsError("getKey in closed window") - time.sleep(.1) # give up thread - - key = self.lastKey - self.lastKey = "" - return key - - def checkKey(self): - """Return last key pressed or None if no key pressed since last call""" - if self.isClosed(): - raise GraphicsError("checkKey in closed window") - self.update() - key = self.lastKey - self.lastKey = "" - return key - - def getHeight(self): - """Return the height of the window""" - return self.height - - def getWidth(self): - """Return the width of the window""" - return self.width - - def toScreen(self, x, y): - trans = self.trans - if trans: - return self.trans.screen(x, y) - else: - return x, y - - def toWorld(self, x, y): - trans = self.trans - if trans: - return self.trans.world(x, y) - else: - return x, y - - def setMouseHandler(self, func): - self._mouseCallback = func - - def _onClick(self, e): - self.mouseX = e.x - self.mouseY = e.y - if self._mouseCallback: - self._mouseCallback(Point(e.x, e.y)) - - def addItem(self, item): - self.items.append(item) - - def delItem(self, item): - self.items.remove(item) - - def redraw(self): - for item in self.items[:]: - item.undraw() - item.draw(self) - self.update() - - -class Transform: - """Internal class for 2-D coordinate transformations""" - - def __init__(self, w, h, xlow, ylow, xhigh, yhigh): - # w, h are width and height of window - # (xlow,ylow) coordinates of lower-left [raw (0,h-1)] - # (xhigh,yhigh) coordinates of upper-right [raw (w-1,0)] - xspan = (xhigh - xlow) - yspan = (yhigh - ylow) - self.xbase = xlow - self.ybase = yhigh - self.xscale = xspan / float(w - 1) - self.yscale = yspan / float(h - 1) - - def screen(self, x, y): - # Returns x,y in screen (actually window) coordinates - xs = (x - self.xbase) / self.xscale - ys = (self.ybase - y) / self.yscale - return int(xs + 0.5), int(ys + 0.5) - - def world(self, xs, ys): - # Returns xs,ys in world coordinates - x = xs * self.xscale + self.xbase - y = self.ybase - ys * self.yscale - return x, y - - -# Default values for various item configuration options. Only a subset of -# keys may be present in the configuration dictionary for a given item -DEFAULT_CONFIG = {"fill": "", - "outline": "black", - "width": "1", - "arrow": "none", - "text": "", - "justify": "center", - "font": ("helvetica", 12, "normal")} - - -class GraphicsObject: - """Generic base class for all of the drawable objects""" - - # A subclass of GraphicsObject should override _draw and - # and _move methods. - - def __init__(self, options): - # options is a list of strings indicating which options are - # legal for this object. - - # When an object is drawn, canvas is set to the GraphWin(canvas) - # object where it is drawn and id is the TK identifier of the - # drawn shape. - self.canvas = None - self.id = None - - # config is the dictionary of configuration options for the widget. - config = {} - for option in options: - config[option] = DEFAULT_CONFIG[option] - self.config = config - - def setFill(self, color): - """Set interior color to color""" - self._reconfig("fill", color) - - def setOutline(self, color): - """Set outline color to color""" - self._reconfig("outline", color) - - def setWidth(self, width): - """Set line weight to width""" - self._reconfig("width", width) - - def draw(self, graphwin): - - """Draw the object in graphwin, which should be a GraphWin - object. A GraphicsObject may only be drawn into one - window. Raises an error if attempt made to draw an object that - is already visible.""" - - if self.canvas and not self.canvas.isClosed(): raise GraphicsError(OBJ_ALREADY_DRAWN) - if graphwin.isClosed(): raise GraphicsError("Can't draw to closed window") - self.canvas = graphwin - self.id = self._draw(graphwin, self.config) - graphwin.addItem(self) - if graphwin.autoflush: - _root.update() - return self - - def undraw(self): - - """Undraw the object (i.e. hide it). Returns silently if the - object is not currently drawn.""" - - if not self.canvas: return - if not self.canvas.isClosed(): - self.canvas.delete(self.id) - self.canvas.delItem(self) - if self.canvas.autoflush: - _root.update() - self.canvas = None - self.id = None - - def move(self, dx, dy): - - """move object dx units in x direction and dy units in y - direction""" - - self._move(dx, dy) - canvas = self.canvas - if canvas and not canvas.isClosed(): - trans = canvas.trans - if trans: - x = dx / trans.xscale - y = -dy / trans.yscale - else: - x = dx - y = dy - self.canvas.move(self.id, x, y) - if canvas.autoflush: - _root.update() - - def _reconfig(self, option, setting): - # Internal method for changing configuration of the object - # Raises an error if the option does not exist in the config - # dictionary for this object - if option not in self.config: - raise GraphicsError(UNSUPPORTED_METHOD) - options = self.config - options[option] = setting - if self.canvas and not self.canvas.isClosed(): - self.canvas.itemconfig(self.id, options) - if self.canvas.autoflush: - _root.update() - - def _draw(self, canvas, options): - """draws appropriate figure on canvas with options provided - Returns Tk id of item drawn""" - pass # must override in subclass - - def _move(self, dx, dy): - """updates internal state of object to move it dx,dy units""" - pass # must override in subclass - - -class Point(GraphicsObject): - def __init__(self, x, y): - GraphicsObject.__init__(self, ["outline", "fill"]) - self.setFill = self.setOutline - self.x = float(x) - self.y = float(y) - - def __repr__(self): - return "Point({}, {})".format(self.x, self.y) - - def _draw(self, canvas, options): - x, y = canvas.toScreen(self.x, self.y) - return canvas.create_rectangle(x, y, x + 1, y + 1, options) - - def _move(self, dx, dy): - self.x = self.x + dx - self.y = self.y + dy - - def clone(self): - other = Point(self.x, self.y) - other.config = self.config.copy() - return other - - def getX(self): return self.x - - def getY(self): return self.y - - -class _BBox(GraphicsObject): - # Internal base class for objects represented by bounding box - # (opposite corners) Line segment is a degenerate case. - - def __init__(self, p1, p2, options=["outline", "width", "fill"]): - GraphicsObject.__init__(self, options) - self.p1 = p1.clone() - self.p2 = p2.clone() - - def _move(self, dx, dy): - self.p1.x = self.p1.x + dx - self.p1.y = self.p1.y + dy - self.p2.x = self.p2.x + dx - self.p2.y = self.p2.y + dy - - def getP1(self): return self.p1.clone() - - def getP2(self): return self.p2.clone() - - def getCenter(self): - p1 = self.p1 - p2 = self.p2 - return Point((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0) - - -class Rectangle(_BBox): - def __init__(self, p1, p2): - _BBox.__init__(self, p1, p2) - - def __repr__(self): - return "Rectangle({}, {})".format(str(self.p1), str(self.p2)) - - def _draw(self, canvas, options): - p1 = self.p1 - p2 = self.p2 - x1, y1 = canvas.toScreen(p1.x, p1.y) - x2, y2 = canvas.toScreen(p2.x, p2.y) - return canvas.create_rectangle(x1, y1, x2, y2, options) - - def clone(self): - other = Rectangle(self.p1, self.p2) - other.config = self.config.copy() - return other - - -class Oval(_BBox): - def __init__(self, p1, p2): - _BBox.__init__(self, p1, p2) - - def __repr__(self): - return "Oval({}, {})".format(str(self.p1), str(self.p2)) - - def clone(self): - other = Oval(self.p1, self.p2) - other.config = self.config.copy() - return other - - def _draw(self, canvas, options): - p1 = self.p1 - p2 = self.p2 - x1, y1 = canvas.toScreen(p1.x, p1.y) - x2, y2 = canvas.toScreen(p2.x, p2.y) - return canvas.create_oval(x1, y1, x2, y2, options) - - -class Circle(Oval): - def __init__(self, center, radius): - p1 = Point(center.x - radius, center.y - radius) - p2 = Point(center.x + radius, center.y + radius) - Oval.__init__(self, p1, p2) - self.radius = radius - - def __repr__(self): - return "Circle({}, {})".format(str(self.getCenter()), str(self.radius)) - - def clone(self): - other = Circle(self.getCenter(), self.radius) - other.config = self.config.copy() - return other - - def getRadius(self): - return self.radius - - -class Line(_BBox): - def __init__(self, p1, p2): - _BBox.__init__(self, p1, p2, ["arrow", "fill", "width"]) - self.setFill(DEFAULT_CONFIG['outline']) - self.setOutline = self.setFill - - def __repr__(self): - return "Line({}, {})".format(str(self.p1), str(self.p2)) - - def clone(self): - other = Line(self.p1, self.p2) - other.config = self.config.copy() - return other - - def _draw(self, canvas, options): - p1 = self.p1 - p2 = self.p2 - x1, y1 = canvas.toScreen(p1.x, p1.y) - x2, y2 = canvas.toScreen(p2.x, p2.y) - return canvas.create_line(x1, y1, x2, y2, options) - - def setArrow(self, option): - if not option in ["first", "last", "both", "none"]: - raise GraphicsError(BAD_OPTION) - self._reconfig("arrow", option) - - -class Polygon(GraphicsObject): - def __init__(self, *points): - # if points passed as a list, extract it - if len(points) == 1 and type(points[0]) == type([]): - points = points[0] - self.points = list(map(Point.clone, points)) - GraphicsObject.__init__(self, ["outline", "width", "fill"]) - - def __repr__(self): - return "Polygon" + str(tuple(p for p in self.points)) - - def clone(self): - other = Polygon(*self.points) - other.config = self.config.copy() - return other - - def getPoints(self): - return list(map(Point.clone, self.points)) - - def _move(self, dx, dy): - for p in self.points: - p.move(dx, dy) - - def _draw(self, canvas, options): - args = [canvas] - for p in self.points: - x, y = canvas.toScreen(p.x, p.y) - args.append(x) - args.append(y) - args.append(options) - return GraphWin.create_polygon(*args) - - -class Text(GraphicsObject): - def __init__(self, p, text): - GraphicsObject.__init__(self, ["justify", "fill", "text", "font"]) - self.setText(text) - self.anchor = p.clone() - self.setFill(DEFAULT_CONFIG['outline']) - self.setOutline = self.setFill - - def __repr__(self): - return "Text({}, '{}')".format(self.anchor, self.getText()) - - def _draw(self, canvas, options): - p = self.anchor - x, y = canvas.toScreen(p.x, p.y) - return canvas.create_text(x, y, options) - - def _move(self, dx, dy): - self.anchor.move(dx, dy) - - def clone(self): - other = Text(self.anchor, self.config['text']) - other.config = self.config.copy() - return other - - def setText(self, text): - self._reconfig("text", text) - - def getText(self): - return self.config["text"] - - def getAnchor(self): - return self.anchor.clone() - - def setFace(self, face): - if face in ['helvetica', 'arial', 'courier', 'times roman']: - f, s, b = self.config['font'] - self._reconfig("font", (face, s, b)) - else: - raise GraphicsError(BAD_OPTION) - - def setSize(self, size): - if 5 <= size <= 36: - f, s, b = self.config['font'] - self._reconfig("font", (f, size, b)) - else: - raise GraphicsError(BAD_OPTION) - - def setStyle(self, style): - if style in ['bold', 'normal', 'italic', 'bold italic']: - f, s, b = self.config['font'] - self._reconfig("font", (f, s, style)) - else: - raise GraphicsError(BAD_OPTION) - - def setTextColor(self, color): - self.setFill(color) - - -class Entry(GraphicsObject): - def __init__(self, p, width): - GraphicsObject.__init__(self, []) - self.anchor = p.clone() - # print self.anchor - self.width = width - self.text = tk.StringVar(_root) - self.text.set("") - self.fill = "gray" - self.color = "black" - self.font = DEFAULT_CONFIG['font'] - self.entry = None - - def __repr__(self): - return "Entry({}, {})".format(self.anchor, self.width) - - def _draw(self, canvas, options): - p = self.anchor - x, y = canvas.toScreen(p.x, p.y) - frm = tk.Frame(canvas.master) - self.entry = tk.Entry(frm, - width=self.width, - textvariable=self.text, - bg=self.fill, - fg=self.color, - font=self.font) - self.entry.pack() - # self.setFill(self.fill) - self.entry.focus_set() - return canvas.create_window(x, y, window=frm) - - def getText(self): - return self.text.get() - - def _move(self, dx, dy): - self.anchor.move(dx, dy) - - def getAnchor(self): - return self.anchor.clone() - - def clone(self): - other = Entry(self.anchor, self.width) - other.config = self.config.copy() - other.text = tk.StringVar() - other.text.set(self.text.get()) - other.fill = self.fill - return other - - def setText(self, t): - self.text.set(t) - - def setFill(self, color): - self.fill = color - if self.entry: - self.entry.config(bg=color) - - def _setFontComponent(self, which, value): - font = list(self.font) - font[which] = value - self.font = tuple(font) - if self.entry: - self.entry.config(font=self.font) - - def setFace(self, face): - if face in ['helvetica', 'arial', 'courier', 'times roman']: - self._setFontComponent(0, face) - else: - raise GraphicsError(BAD_OPTION) - - def setSize(self, size): - if 5 <= size <= 36: - self._setFontComponent(1, size) - else: - raise GraphicsError(BAD_OPTION) - - def setStyle(self, style): - if style in ['bold', 'normal', 'italic', 'bold italic']: - self._setFontComponent(2, style) - else: - raise GraphicsError(BAD_OPTION) - - def setTextColor(self, color): - self.color = color - if self.entry: - self.entry.config(fg=color) - - -class Image(GraphicsObject): - idCount = 0 - imageCache = {} # tk photoimages go here to avoid GC while drawn - - def __init__(self, p, *pixmap): - GraphicsObject.__init__(self, []) - self.anchor = p.clone() - self.imageId = Image.idCount - Image.idCount = Image.idCount + 1 - if len(pixmap) == 1: # file name provided - self.img = tk.PhotoImage(file=pixmap[0], master=_root) - else: # width and height provided - width, height = pixmap - self.img = tk.PhotoImage(master=_root, width=width, height=height) - - def __repr__(self): - return "Image({}, {}, {})".format(self.anchor, self.getWidth(), self.getHeight()) - - def _draw(self, canvas, options): - p = self.anchor - x, y = canvas.toScreen(p.x, p.y) - self.imageCache[self.imageId] = self.img # save a reference - return canvas.create_image(x, y, image=self.img) - - def _move(self, dx, dy): - self.anchor.move(dx, dy) - - def undraw(self): - try: - del self.imageCache[self.imageId] # allow gc of tk photoimage - except KeyError: - pass - GraphicsObject.undraw(self) - - def getAnchor(self): - return self.anchor.clone() - - def clone(self): - other = Image(Point(0, 0), 0, 0) - other.img = self.img.copy() - other.anchor = self.anchor.clone() - other.config = self.config.copy() - return other - - def getWidth(self): - """Returns the width of the image in pixels""" - return self.img.width() - - def getHeight(self): - """Returns the height of the image in pixels""" - return self.img.height() - - def getPixel(self, x, y): - """Returns a list [r,g,b] with the RGB color values for pixel (x,y) - r,g,b are in range(256) - - """ - - value = self.img.get(x, y) - if type(value) == type(0): - return [value, value, value] - elif type(value) == type((0, 0, 0)): - return list(value) - else: - return list(map(int, value.split())) - - def setPixel(self, x, y, color): - """Sets pixel (x,y) to the given color - - """ - self.img.put("{" + color + "}", (x, y)) - - def save(self, filename): - """Saves the pixmap image to filename. - The format for the save image is determined from the filname extension. - - """ - - path, name = os.path.split(filename) - ext = name.split(".")[-1] - self.img.write(filename, format=ext) - - -def color_rgb(r, g, b): - """r,g,b are intensities of red, green, and blue in range(256) - Returns color specifier string for the resulting color""" - return "#%02x%02x%02x" % (r, g, b) - - -def test(): - win = GraphWin() - win.setCoords(0, 0, 10, 10) - t = Text(Point(5, 5), "Centered Text") - t.draw(win) - p = Polygon(Point(1, 1), Point(5, 3), Point(2, 7)) - p.draw(win) - e = Entry(Point(5, 6), 10) - e.draw(win) - win.getMouse() - p.setFill("red") - p.setOutline("blue") - p.setWidth(2) - s = "" - for pt in p.getPoints(): - s = s + "(%0.1f,%0.1f) " % (pt.getX(), pt.getY()) - t.setText(e.getText()) - e.setFill("green") - e.setText("Spam!") - e.move(2, 0) - win.getMouse() - p.move(2, 3) - s = "" - for pt in p.getPoints(): - s = s + "(%0.1f,%0.1f) " % (pt.getX(), pt.getY()) - t.setText(s) - win.getMouse() - p.undraw() - e.undraw() - t.setStyle("bold") - win.getMouse() - t.setStyle("normal") - win.getMouse() - t.setStyle("italic") - win.getMouse() - t.setStyle("bold italic") - win.getMouse() - t.setSize(14) - win.getMouse() - t.setFace("arial") - t.setSize(20) - win.getMouse() - win.close() - - -# MacOS fix 2 -# tk.Toplevel(_root).destroy() - -# MacOS fix 1 -update() - -if __name__ == "__main__": - test() \ No newline at end of file