def __init__(self, master, id_priority_sort_function = lambda ids : ids, mesh_step = 20 ): GUIFrame.__init__ (self, master) self.canvas = Canvas (self, width = 100, # default width height = 100, # default height relief = RIDGE, background = "white", borderwidth = 1 ) self.canvas.pack(expand = 1, fill = BOTH) self.align = False self.mesh_step = IntVar(value = mesh_step) self.dragging = False self.off = None self.canvas.bind("<ButtonPress-1>", self.down, "+") self.canvas.bind("<ButtonRelease-1>", self.up, "+") self.canvas.bind("<Motion>", self.motion, "+") self.id_priority_sort_function = id_priority_sort_function
def configure(self, **kw): if "xscrollcommand" in kw: self._xscrollcommand = kw.pop("xscrollcommand") if "yscrollcommand" in kw: self._yscrollcommand = kw.pop("yscrollcommand") if kw: Canvas.configure(self, **kw)
class DoubleScrollbarFrame(Frame): def __init__(self, master, **kwargs): ''' Initialisation. The DoubleScrollbarFrame consist of : - an horizontal scrollbar - a vertical scrollbar - a canvas in which the user can place sub-elements ''' Frame.__init__(self, master, **kwargs) # Canvas creation with double scrollbar self.hscrollbar = Scrollbar(self, orient=HORIZONTAL) self.vscrollbar = Scrollbar(self, orient=VERTICAL) self.sizegrip = Sizegrip(self) self.canvas = Canvas(self, bd=0, highlightthickness=0, yscrollcommand=self.vscrollbar.set, xscrollcommand=self.hscrollbar.set) self.vscrollbar.config(command=self.canvas.yview) self.hscrollbar.config(command=self.canvas.xview) def pack(self, **kwargs): ''' Pack the scrollbar and canvas correctly in order to recreate the same look as MFC's windows. ''' self.hscrollbar.pack(side=BOTTOM, fill=X, expand=FALSE) self.vscrollbar.pack(side=RIGHT, fill=Y, expand=FALSE) self.sizegrip.pack(in_=self.hscrollbar, side=BOTTOM, anchor="se") self.canvas.pack(side=LEFT, padx=5, pady=5, fill=BOTH, expand=TRUE) Frame.pack(self, **kwargs)
def __init__(self, master, **kw): kw.setdefault("background", "white") self._xscrollcommand = kw.pop("xscrollcommand", None) self._yscrollcommand = kw.pop("yscrollcommand", None) self._encoding = kw.pop("encoding", "utf-8") self._encoding_errors = kw.pop("encoding_errors", "replace") stream = kw.pop("stream", None) Canvas.__init__(self, master, **kw) self.bind("<Configure>", self._on_configure, "+") bind_mouse_wheel(self, self._on_mouse_wheel) self.bind("<Enter>", self._on_enter, "+") self.bind("<Prior>", self._on_prior, "+") # Page Up self.bind("<Next>", self._on_next, "+") # Page Down self._var_total_lines = total_var = IntVar(self) total_var.set(0) # Contains showed line number. It's one greater than internally used # index of line. self._var_lineno = lineno_var = IntVar(self) lineno_var.set(1) # TODO: make it configurable fonts = [ Font(font = ("Courier", 10, NORMAL)), Font(font = ("Courier", 10, BOLD)), ] self._main_font, self._lineno_font = fonts self._linespace = max(f.metrics("linespace") for f in fonts) # Note, padding space is used for selected lines highlighting. self._ylinepadding = 1 self._lineno_padding = 10 self._page_size = 100 # in lines self._page_width = 0 # in Canvas units self._x_offset = 0 self._index = None # index of lines offsets self._stream = None # trigger the property self.stream = stream self._state = None # Selection is defined by two tuples: (lineidx, charidx) self._sel_start = None # first selected char self._sel_limit = None # a char immediately after last selected one self.selection_threshold = 10 self.bind("<ButtonPress-1>", self._on_bt1_press, "+") self.bind("<ButtonRelease-1>", self._on_bt1_release, "+") self.bind("<Motion>", self._on_motion, "+") self.bind("<Control-Key>", self._on_ctrl_key, "+")
def _create_ui(self): '''Create all UI widgets.''' #self._l = Label(self, text="My Ships") #self._l.grid(row=0) self._c = Canvas(self) self._c.grid(row=1) self._create_ships() self.pack_ui()
def _create_ui(self): '''Create all UI objects.''' #self._tl = Label(self, text="Staged Ship", f) self._sl = Label(self, textvariable=self._ship_name) self._c = Canvas(self) self._c.config(width=self.CANVAS_WIDTH) self._rb = Button(self, text="Rotate", command=self.rotate_current_ship) self.pack_ui()
def __init__(self, master, home=False): '''Create a new grid. home determines if this is your grid or the opponent's.''' Canvas.__init__(self, master) self.size = self.GRID_SIZE * self.RECT_SIZE + 2 * max(self.GRID_X_OFFSET, self.GRID_Y_OFFSET) self.config(height=self.size, width=self.size) self._home = home self._model = GridModel() self._make_grid() self.reset()
def main(): root = Tk() sizex = 800 sizey = 600 posx = 100 posy = 100 root.wm_geometry("%dx%d+%d+%d" % (sizex, sizey, posx, posy)) root.grid() root.rowconfigure(0, weight=1) root.columnconfigure(0, weight=1) myframe = Frame(root, relief=GROOVE, bd=1) myframe.grid(row=0, column=0, sticky="NESW") myframe.rowconfigure(0, weight=1) myframe.columnconfigure(0, weight=1) myframe.columnconfigure(1, weight=0) canvas = Canvas(myframe) canvas.grid(row=0, column=0, sticky="NESW") frame = Frame(canvas) myscrollbar = Scrollbar(myframe, orient="vertical", command=canvas.yview) myscrollbar.grid(row=0, column=1, sticky="NESW") canvas.configure(yscrollcommand=myscrollbar.set) canvas.create_window((0, 0), window=frame, anchor='nw') frame.bind("<Configure>", lambda e, c=canvas: myfunction(c, e)) data(frame) root.mainloop()
def __init__(self, master, home=False): '''Create a new grid. home determines if this is your grid or the opponent's.''' Canvas.__init__(self, master) self.size = self.GRID_SIZE * self.RECT_SIZE + 2 * max( self.GRID_X_OFFSET, self.GRID_Y_OFFSET) self.config(height=self.size, width=self.size) self._home = home self._model = GridModel() self._make_grid() self.reset()
def __init__(self, master=None, min_val=0, max_val=100, converter=None, **kw): self.log = logging.getLogger(__name__) self.min_val = min_val self.max_val = max_val self.converter = converter kw['width'] = kw.get('width', 100) kw['height'] = kw.get('height', 10) kw['background'] = kw.get('background', "black") self.rect = None Canvas.__init__(*(self, master), **kw)
def __init__(self, drs, size_canvas=True, canvas=None): """ :param drs: ``DrtExpression``, The DRS to be drawn :param size_canvas: bool, True if the canvas size should be the exact size of the DRS :param canvas: ``Canvas`` The canvas on which to draw the DRS. If none is given, create a new canvas. """ master = None if not canvas: master = Tk() master.title("DRT") font = Font(family='helvetica', size=12) if size_canvas: canvas = Canvas(master, width=0, height=0) canvas.font = font self.canvas = canvas (right, bottom) = self._visit(drs, self.OUTERSPACE, self.TOPSPACE) width = max(right+self.OUTERSPACE, 100) height = bottom+self.OUTERSPACE canvas = Canvas(master, width=width, height=height)#, bg='white') else: canvas = Canvas(master, width=300, height=300) canvas.pack() canvas.font = font self.canvas = canvas self.drs = drs self.master = master
def __init__(self, master, **kwargs): ''' Initialisation. The DoubleScrollbarFrame consist of : - an horizontal scrollbar - a vertical scrollbar - a canvas in which the user can place sub-elements ''' Frame.__init__(self, master, **kwargs) # Canvas creation with double scrollbar self.hscrollbar = Scrollbar(self, orient=HORIZONTAL) self.vscrollbar = Scrollbar(self, orient=VERTICAL) self.sizegrip = Sizegrip(self) self.canvas = Canvas(self, bd=0, highlightthickness=0, yscrollcommand=self.vscrollbar.set, xscrollcommand=self.hscrollbar.set) self.vscrollbar.config(command=self.canvas.yview) self.hscrollbar.config(command=self.canvas.xview)
def __init__(self, master, id_priority_sort_function=lambda ids: ids, mesh_step=20, **kw): # override some defaults for arg, val in [("width", 100), ("height", 100), ("relief", RIDGE), ("background", "white"), ("borderwidth", 1)]: kw.setdefault(arg, val) Canvas.__init__(self, master, **kw) self.align = False self.mesh_step = IntVar(value=mesh_step) self._state = None self.off = None self.bind("<ButtonPress-1>", self.down, "+") self.bind("<ButtonRelease-1>", self.up, "+") self.bind("<ButtonPress-3>", self.b3down, "+") self.bind("<ButtonRelease-3>", self.b3up, "+") self.bind("<Motion>", self.motion, "+") self.id_priority_sort_function = id_priority_sort_function
def add_scrollbars(outer, InnerType, *inner_args, **inner_kw): """ Creates widget of type `InnerType` inside `outer` widget and adds vertical and horizontal scroll bars for created widget. """ outer.rowconfigure(0, weight=1) outer.rowconfigure(1, weight=0) outer.columnconfigure(0, weight=1) outer.columnconfigure(1, weight=0) # container for inner frame, it supports scrolling canvas = Canvas(outer, width=1, height=1) canvas.grid(row=0, column=0, sticky="NESW") inner = InnerType(canvas, *inner_args, **inner_kw) inner_id = canvas.create_window((0, 0), window=inner, anchor="nw") h_sb = Scrollbar(outer, orient="horizontal", command=canvas.xview) h_sb._visible = False v_sb = Scrollbar(outer, orient="vertical", command=canvas.yview) v_sb._visible = False canvas.configure(xscrollcommand=h_sb.set, yscrollcommand=v_sb.set) def scrollbar_visibility(): "Automatically shows & hides the scroll bar." cnv_w, cnv_h = canvas.winfo_width(), canvas.winfo_height() inner_w, inner_h = inner.winfo_width(), inner.winfo_height() if inner_w <= cnv_w: if h_sb._visible: h_sb.grid_forget() h_sb._visible = False else: if not h_sb._visible: h_sb.grid(row=1, column=0, sticky="NESW") h_sb._visible = True if inner_h <= cnv_h: if v_sb._visible: v_sb.grid_forget() v_sb._visible = False else: if not v_sb._visible: v_sb.grid(row=0, column=1, sticky="NESW") v_sb._visible = True def inner_configure(_): scrollbar_visibility() canvas.configure( scrollregion=canvas.bbox(ALL), # Require as many space as inner widget do. width=inner.winfo_reqwidth(), height=inner.winfo_reqheight()) inner.bind("<Configure>", inner_configure, "+") def canvas_configure(e): scrollbar_visibility() # Get to the inner widget at least desired space. # Stretch it when possible. canvas.itemconfig(inner_id, width=max(e.width, inner.winfo_reqwidth()), height=max(e.height, inner.winfo_reqheight())) canvas.bind("<Configure>", canvas_configure, "+") return inner
class CFGDemo(object): def __init__(self, grammar, text): self._grammar = grammar self._text = text # Set up the main window. self._top = Tk() self._top.title('Context Free Grammar Demo') # Base font size self._size = IntVar(self._top) self._size.set(12) # = medium # Set up the key bindings self._init_bindings(self._top) # Create the basic frames frame1 = Frame(self._top) frame1.pack(side='left', fill='y', expand=0) self._init_menubar(self._top) self._init_buttons(self._top) self._init_grammar(frame1) self._init_treelet(frame1) self._init_workspace(self._top) #////////////////////////////////////////////////// # Initialization #////////////////////////////////////////////////// def _init_bindings(self, top): top.bind('<Control-q>', self.destroy) def _init_menubar(self, parent): pass def _init_buttons(self, parent): pass def _init_grammar(self, parent): self._prodlist = ProductionList(parent, self._grammar, width=20) self._prodlist.pack(side='top', fill='both', expand=1) self._prodlist.focus() self._prodlist.add_callback('select', self._selectprod_cb) self._prodlist.add_callback('move', self._selectprod_cb) def _init_treelet(self, parent): self._treelet_canvas = Canvas(parent, background='white') self._treelet_canvas.pack(side='bottom', fill='x') self._treelet = None def _init_workspace(self, parent): self._workspace = CanvasFrame(parent, background='white') self._workspace.pack(side='right', fill='both', expand=1) self._tree = None self.reset_workspace() #////////////////////////////////////////////////// # Workspace #////////////////////////////////////////////////// def reset_workspace(self): c = self._workspace.canvas() fontsize = int(self._size.get()) node_font = ('helvetica', -(fontsize+4), 'bold') leaf_font = ('helvetica', -(fontsize+2)) # Remove the old tree if self._tree is not None: self._workspace.remove_widget(self._tree) # The root of the tree. start = self._grammar.start().symbol() rootnode = TextWidget(c, start, font=node_font, draggable=1) # The leaves of the tree. leaves = [] for word in self._text: leaves.append(TextWidget(c, word, font=leaf_font, draggable=1)) # Put it all together into one tree self._tree = TreeSegmentWidget(c, rootnode, leaves, color='white') # Add it to the workspace. self._workspace.add_widget(self._tree) # Move the leaves to the bottom of the workspace. for leaf in leaves: leaf.move(0,100) #self._nodes = {start:1} #self._leaves = dict([(l,1) for l in leaves]) def workspace_markprod(self, production): pass def _markproduction(self, prod, tree=None): if tree is None: tree = self._tree for i in range(len(tree.subtrees())-len(prod.rhs())): if tree['color', i] == 'white': self._markproduction for j, node in enumerate(prod.rhs()): widget = tree.subtrees()[i+j] if (isinstance(node, Nonterminal) and isinstance(widget, TreeSegmentWidget) and node.symbol == widget.label().text()): pass # matching nonterminal elif (isinstance(node, string_types) and isinstance(widget, TextWidget) and node == widget.text()): pass # matching nonterminal else: break else: # Everything matched! print('MATCH AT', i) #////////////////////////////////////////////////// # Grammar #////////////////////////////////////////////////// def _selectprod_cb(self, production): canvas = self._treelet_canvas self._prodlist.highlight(production) if self._treelet is not None: self._treelet.destroy() # Convert the production to a tree. rhs = production.rhs() for (i, elt) in enumerate(rhs): if isinstance(elt, Nonterminal): elt = Tree(elt) tree = Tree(production.lhs().symbol(), *rhs) # Draw the tree in the treelet area. fontsize = int(self._size.get()) node_font = ('helvetica', -(fontsize+4), 'bold') leaf_font = ('helvetica', -(fontsize+2)) self._treelet = tree_to_treesegment(canvas, tree, node_font=node_font, leaf_font=leaf_font) self._treelet['draggable'] = 1 # Center the treelet. (x1, y1, x2, y2) = self._treelet.bbox() w, h = int(canvas['width']), int(canvas['height']) self._treelet.move((w-x1-x2)/2, (h-y1-y2)/2) # Mark the places where we can add it to the workspace. self._markproduction(production) def destroy(self, *args): self._top.destroy() def mainloop(self, *args, **kwargs): self._top.mainloop(*args, **kwargs)
class ShipWarPanel(Frame): '''Panel to keep track of ships during wartime. Track damage and status.''' ########### colors ############ RECT_NULL_FILL = "forest green" RECT_HIT_FILL = "red" ############################### ######### geometry ############ Y_SPACING = 20 RECT_SIZE = 15 LEFT_PADDING = 10 TOP_PADDING = 10 ############################### def __init__(self, master): Frame.__init__(self, master) self._create_ui() def _create_ui(self): '''Create all UI widgets.''' #self._l = Label(self, text="My Ships") #self._l.grid(row=0) self._c = Canvas(self) self._c.grid(row=1) self._create_ships() self.pack_ui() def update(self, ship, hit_list=None): '''Update the given ship. <ship> should be a Ship object. <hit_list> should be a binary list''' assert ship is not None if hit_list is None: hit_list = ship.get_hit_list() for i, r in enumerate(hit_list): item = self._ship_squares[ship.get_short_name()][i] if r: self._c.itemconfig(item, fill=self.RECT_HIT_FILL) else: self._c.itemconfig(item, fill=self.RECT_NULL_FILL) def reset(self): for ship in Ship.SHORT_NAMES: s = Ship(0, 0, ship, False) self.update(s, [0] * s.get_size()) def redraw(self, model): '''Redraw the panel based on the GridModel. <model> is an instance of GridModel.''' for ship_name, ship in model.get_ships().items(): self.update(ship) def _create_ships(self): '''Create ships on the canvas.''' self._ship_squares = {} for i, ship in enumerate(Ship.SHORT_NAMES): y = self.TOP_PADDING + i * (self.Y_SPACING * 2 + self.RECT_SIZE) s = Ship(0, 0, ship, False) self._c.create_text(self.LEFT_PADDING, y, text=s.get_full_name().title(), anchor=NW) self._ship_squares[ship] = [None] * s.get_size() for x in range(s.get_size()): self._ship_squares[ship][x] = self._c.create_rectangle( self.LEFT_PADDING + x * self.RECT_SIZE, y + self.Y_SPACING, self.LEFT_PADDING + (x + 1) * self.RECT_SIZE, y + self.Y_SPACING + self.RECT_SIZE, fill=self.RECT_NULL_FILL, outline="black" ) def pack_ui(self): '''Remedy for my method of hiding frames.''' #self._l.pack() self._c.pack()
def _init_treelet(self, parent): self._treelet_canvas = Canvas(parent, background="white") self._treelet_canvas.pack(side="bottom", fill="x") self._treelet = None
def _init_treelet(self, parent): self._treelet_canvas = Canvas(parent, background='white') self._treelet_canvas.pack(side='bottom', fill='x') self._treelet = None
Canvas, Label, BOTH, Frame ) from widgets import ( CanvasFrame ) if __name__ == "__main__": root = Tk() root.rowconfigure(0, weight = 1) root.columnconfigure(0, weight = 1) cnv = Canvas(root, bg = "white") cnv.grid(row = 0, column = 0, sticky = "NESW") cf = CanvasFrame(cnv, 100, 100) cnv.itemconfig(cf.id, width = 150, height = 150) Label(cf, text = "Test").pack(fill = BOTH, expand = 0) f2 = Frame(cf, bg = "white", width = 100, height = 100) f2.pack(fill = BOTH, expand = 1) def on_motion(e): print (e.x, e.y) f2.bind("<Motion>", on_motion, "+")
class CFGDemo(object): def __init__(self, grammar, text): self._grammar = grammar self._text = text # Set up the main window. self._top = Tk() self._top.title('Context Free Grammar Demo') # Base font size self._size = IntVar(self._top) self._size.set(12) # = medium # Set up the key bindings self._init_bindings(self._top) # Create the basic frames frame1 = Frame(self._top) frame1.pack(side='left', fill='y', expand=0) self._init_menubar(self._top) self._init_buttons(self._top) self._init_grammar(frame1) self._init_treelet(frame1) self._init_workspace(self._top) # ////////////////////////////////////////////////// # Initialization # ////////////////////////////////////////////////// def _init_bindings(self, top): top.bind('<Control-q>', self.destroy) def _init_menubar(self, parent): pass def _init_buttons(self, parent): pass def _init_grammar(self, parent): self._prodlist = ProductionList(parent, self._grammar, width=20) self._prodlist.pack(side='top', fill='both', expand=1) self._prodlist.focus() self._prodlist.add_callback('select', self._selectprod_cb) self._prodlist.add_callback('move', self._selectprod_cb) def _init_treelet(self, parent): self._treelet_canvas = Canvas(parent, background='white') self._treelet_canvas.pack(side='bottom', fill='x') self._treelet = None def _init_workspace(self, parent): self._workspace = CanvasFrame(parent, background='white') self._workspace.pack(side='right', fill='both', expand=1) self._tree = None self.reset_workspace() # ////////////////////////////////////////////////// # Workspace # ////////////////////////////////////////////////// def reset_workspace(self): c = self._workspace.canvas() fontsize = int(self._size.get()) node_font = ('helvetica', -(fontsize + 4), 'bold') leaf_font = ('helvetica', -(fontsize + 2)) # Remove the old tree if self._tree is not None: self._workspace.remove_widget(self._tree) # The root of the tree. start = self._grammar.start().symbol() rootnode = TextWidget(c, start, font=node_font, draggable=1) # The leaves of the tree. leaves = [] for word in self._text: leaves.append(TextWidget(c, word, font=leaf_font, draggable=1)) # Put it all together into one tree self._tree = TreeSegmentWidget(c, rootnode, leaves, color='white') # Add it to the workspace. self._workspace.add_widget(self._tree) # Move the leaves to the bottom of the workspace. for leaf in leaves: leaf.move(0, 100) # self._nodes = {start:1} # self._leaves = dict([(l,1) for l in leaves]) def workspace_markprod(self, production): pass def _markproduction(self, prod, tree=None): if tree is None: tree = self._tree for i in range(len(tree.subtrees()) - len(prod.rhs())): if tree['color', i] == 'white': self._markproduction # FIXME: Is this necessary at all? for j, node in enumerate(prod.rhs()): widget = tree.subtrees()[i + j] if ( isinstance(node, Nonterminal) and isinstance(widget, TreeSegmentWidget) and node.symbol == widget.label().text() ): pass # matching nonterminal elif ( isinstance(node, string_types) and isinstance(widget, TextWidget) and node == widget.text() ): pass # matching nonterminal else: break else: # Everything matched! print('MATCH AT', i) # ////////////////////////////////////////////////// # Grammar # ////////////////////////////////////////////////// def _selectprod_cb(self, production): canvas = self._treelet_canvas self._prodlist.highlight(production) if self._treelet is not None: self._treelet.destroy() # Convert the production to a tree. rhs = production.rhs() for (i, elt) in enumerate(rhs): if isinstance(elt, Nonterminal): elt = Tree(elt) tree = Tree(production.lhs().symbol(), *rhs) # Draw the tree in the treelet area. fontsize = int(self._size.get()) node_font = ('helvetica', -(fontsize + 4), 'bold') leaf_font = ('helvetica', -(fontsize + 2)) self._treelet = tree_to_treesegment( canvas, tree, node_font=node_font, leaf_font=leaf_font ) self._treelet['draggable'] = 1 # Center the treelet. (x1, y1, x2, y2) = self._treelet.bbox() w, h = int(canvas['width']), int(canvas['height']) self._treelet.move((w - x1 - x2) / 2, (h - y1 - y2) / 2) # Mark the places where we can add it to the workspace. self._markproduction(production) def destroy(self, *args): self._top.destroy() def mainloop(self, *args, **kwargs): self._top.mainloop(*args, **kwargs)
class CanvasDnD(GUIFrame): def __init__(self, master, id_priority_sort_function = lambda ids : ids, mesh_step = 20 ): GUIFrame.__init__ (self, master) self.canvas = Canvas (self, width = 100, # default width height = 100, # default height relief = RIDGE, background = "white", borderwidth = 1 ) self.canvas.pack(expand = 1, fill = BOTH) self.align = False self.mesh_step = IntVar(value = mesh_step) self.dragging = False self.off = None self.canvas.bind("<ButtonPress-1>", self.down, "+") self.canvas.bind("<ButtonRelease-1>", self.up, "+") self.canvas.bind("<Motion>", self.motion, "+") self.id_priority_sort_function = id_priority_sort_function def down(self, event): x, y = event.widget.canvasx(event.x), event.widget.canvasy(event.y) touched = self.canvas.find_overlapping(x - 1, y - 1, x + 1, y + 1) touched = [ t for t in touched if ("DnD" in self.canvas.gettags(t)) ] if not touched: return touched = self.id_priority_sort_function(touched) self.dnd_dragged = touched[0] offset = event.widget.coords(self.dnd_dragged) self.off = (x - offset[0], y - offset[1]) #print str((x,y)) + " - " + str(self.off) self.dragging = True self.event_generate('<<DnDDown>>') def motion(self, event): if not self.dragging: return self.master.config(cursor = "fleur") c = self.canvas xy = c.canvasx(event.x), c.canvasy(event.y) points = c.coords(self.dnd_dragged) offset = self.off if self.align: new_pos = ( xy[0] - offset[0], xy[1] - offset[1], ) m = self.mesh_step.get() aligned_pos = ( int(new_pos[0] / m) * m, int(new_pos[1] / m) * m ) align_gain = ( aligned_pos[0] - new_pos[0], aligned_pos[1] - new_pos[1] ) else: align_gain = (0, 0) dxy = ( xy[0] - (points[0] + offset[0]) + align_gain[0], xy[1] - (points[1] + offset[1]) + align_gain[1] ) #print str(points) + " - " + str(self.off) tags = c.gettags(self.dnd_dragged) if "fixed_x" not in tags: for idx in xrange(0, len(points), 2): points[idx] = dxy[0] + points[idx] if "fixed_y" not in tags: for idx in xrange(1, len(points), 2): points[idx] = dxy[1] + points[idx] #print points c.coords(*([self.dnd_dragged] + points)) self.event_generate('<<DnDMoved>>') def up(self, event): if self.dragging: self.master.config(cursor = "") self.dragging = False self.off = None self.event_generate('<<DnDUp>>') """ Right after event. Listeners should be able to get which id is not dragged now. """ del self.dnd_dragged
class ShipPlacementPanel(Frame): '''A frame which contains visualizations for placing ships.''' # the size of a single tile SHIP_TILE_SIZE = 20 SHIP_TILE_COLOR = "steel blue" TAG = "staging_ship" CANVAS_WIDTH = 150 def __init__(self, master): '''Create a new panel with the given parent.''' Frame.__init__(self, master) self._ship_name = StringVar() self._create_ui() self.reset() def reset(self): '''Alias for unstage_all''' self.unstage_all() def _create_ui(self): '''Create all UI objects.''' #self._tl = Label(self, text="Staged Ship", f) self._sl = Label(self, textvariable=self._ship_name) self._c = Canvas(self) self._c.config(width=self.CANVAS_WIDTH) self._rb = Button(self, text="Rotate", command=self.rotate_current_ship) self.pack_ui() def pack_ui(self): '''(re) pack the UI. Created mostly to counter hiding by unpacking.''' #self._tl.pack() #self._tl.grid(row=0) self._sl.pack() self._sl.grid(row=1, pady=10) self._c.pack() self._c.grid(row=2, pady=15) self._rb.pack() self._rb.grid(row=3) def unstage_all(self): '''Remove all ships from staging area. Clear all staging preferences.''' self._staged_ship = None self._clear_staging_grid() self._ship_name.set("") self._disable_rotate_button() def _clear_staging_grid(self): '''Remove previously staged ships from staging grid.''' for item in self._c.find_withtag(self.TAG): self._c.delete(item) def _draw_staged_ship(self): '''Draw the currently staged ship.''' # remove prior drawings self._clear_staging_grid() if self._staged_ship.is_vertical(): x = 0 x_pad = (self._c.winfo_width() - self.SHIP_TILE_SIZE) / 2.0 y_pad = (self._c.winfo_height() - self.SHIP_TILE_SIZE * self._staged_ship.get_size()) / 2.0 for y in range(self._staged_ship.get_size()): self._draw_ship_tile(x_pad + x * self.SHIP_TILE_SIZE, y_pad + y * self.SHIP_TILE_SIZE) else: y = 0 x_pad = (self._c.winfo_width() - self.SHIP_TILE_SIZE * self._staged_ship.get_size()) / 2.0 y_pad = (self._c.winfo_height() - self.SHIP_TILE_SIZE) / 2.0 for x in range(self._staged_ship.get_size()): self._draw_ship_tile(x_pad + x * self.SHIP_TILE_SIZE, y_pad + y * self.SHIP_TILE_SIZE) def add_ship(self, s): '''Alias for stage ship.''' self.stage_ship(s) def _disable_rotate_button(self): '''Disable / hide the rotate button.''' self._rb.grid_forget() def _enable_rotate_button(self): '''Enable / show the rotate button.''' self._rb.grid(row=3) def stage_ship(self, s): '''Add a ship to the staging area. Display what it would look like on the grid. Create support for accidentally adding ship that isn't ready''' if s is not None: self._staged_ship = s self._ship_name.set(s.get_full_name().title()) self._draw_staged_ship() self._enable_rotate_button() else: self._disable_rotate_button() def _draw_ship_tile(self, x, y): '''Draw a single tile for the ship at given coordinates.''' self._c.create_rectangle(x, y, x + self.SHIP_TILE_SIZE, y + self.SHIP_TILE_SIZE, fill=self.SHIP_TILE_COLOR, outline="black", tag=self.TAG) def get_staged_ship(self): '''Return the currently staged ship.''' return self._staged_ship def rotate_current_ship(self): '''Rotate the currently staged ship.''' if self._staged_ship is not None: self._staged_ship.rotate() self._draw_staged_ship()
raise ValueError("Wrong layout: different number of groups in rows") offset_w = outer_pad for group in zip(*groups): offset_w += prepare_group(group, offset_w) w = offset_w + outer_pad h = max(b.h + b.y for b in all_buttons) + outer_pad return all_buttons, w, h if __name__ == "__main__": root = Tk() root.title("Keyboard") cnv = Canvas(root, bg="white") cnv.pack(fill=BOTH, expand=True) buttons, w, h = generate_buttons() cnv.configure(width=w, height=h) lb_code = Label(root) lb_code.pack(fill=X, expand=False) def resize(): # XXX: it's a bit less that ideally needed because of borders root.geometry("%ux%u" % (w, h + lb_code.winfo_reqheight())) root.after(10, resize)
from six.moves.tkinter import (Tk, RAISED, Canvas, BOTH, HORIZONTAL, VERTICAL) from widgets import (AutoPanedWindow) if __name__ == "__main__": r = Tk() r.title("AutoPanedWindow example") a = AutoPanedWindow(r, sashrelief=RAISED, orient=HORIZONTAL) a.pack(fill=BOTH, expand=True) a.add(Canvas(a, bg="red"), sticky="NESW") a1 = AutoPanedWindow(a, sashrelief=RAISED, orient=VERTICAL) a.add(a1, sticky="NESW") blue = Canvas(a1, bg="blue") a1.add(blue, sticky="NESW") green = Canvas(a1, bg="green") a1.add(green, sticky="NESW") a1.add(Canvas(a1, bg="brown"), after=blue, sticky="NESW") yellow = Canvas(a, bg="yellow") a.add(yellow, sticky="NESW") a.add(Canvas(a, bg="pink"), before=yellow, sticky="NESW") r.geometry("800x600") r.mainloop()
def add_scrollbars(outer, InnerType, *inner_args, **kw): """ Creates widget of type `InnerType` inside `outer` widget and adds vertical and horizontal scroll bars for created widget. :param kw: those arguments are passed to `InnerType` constructor except for: - row/column: `grid` coordinates inside `outer` (default: 0) - wheel: support wheel scrolling when mouse is over inner widget (default: False) - inner_kw: see below To pass same named arguments to `InnerType` wrap them into a `dict` and pass it with name "inner_kw" in "kw". """ row, column = kw.pop("row", 0), kw.pop("column", 0) wheel = kw.pop("wheel", False) kw.update(kw.pop("inner_kw", {})) outer.rowconfigure(row, weight=1) outer.rowconfigure(row + 1, weight=0) outer.columnconfigure(column, weight=1) outer.columnconfigure(column + 1, weight=0) # container for inner frame, it supports scrolling canvas = Canvas(outer, width=1, height=1) canvas.grid(row=row, column=row, sticky="NESW") inner = InnerType(canvas, *inner_args, **kw) inner_id = canvas.create_window((0, 0), window=inner, anchor="nw") h_sb = Scrollbar(outer, orient="horizontal", command=canvas.xview) h_sb._visible = False v_sb = Scrollbar(outer, orient="vertical", command=canvas.yview) v_sb._visible = False canvas.configure(xscrollcommand=h_sb.set, yscrollcommand=v_sb.set) def scrollbar_visibility(): "Automatically shows & hides the scroll bar." cnv_w, cnv_h = canvas.winfo_width(), canvas.winfo_height() inner_w, inner_h = inner.winfo_width(), inner.winfo_height() if inner_w <= cnv_w: if h_sb._visible: h_sb.grid_forget() h_sb._visible = False else: if not h_sb._visible: h_sb.grid(row=row + 1, column=column, sticky="NESW") h_sb._visible = True if inner_h <= cnv_h: if v_sb._visible: v_sb.grid_forget() v_sb._visible = False else: if not v_sb._visible: v_sb.grid(row=row, column=column + 1, sticky="NESW") v_sb._visible = True def inner_configure(_): scrollbar_visibility() canvas.configure( scrollregion=canvas.bbox(ALL), # Require as many space as inner widget do. width=inner.winfo_reqwidth(), height=inner.winfo_reqheight()) inner.bind("<Configure>", inner_configure, "+") def canvas_configure(e): scrollbar_visibility() # Get to the inner widget at least desired space. # Stretch it when possible. canvas.itemconfig(inner_id, width=max(e.width, inner.winfo_reqwidth()), height=max(e.height, inner.winfo_reqheight())) canvas.bind("<Configure>", canvas_configure, "+") if not wheel: return inner def on_wheel(e): w = e.widget # Is the `w`idget our inner? m = w while m is not None: if m is inner: break m = m.master else: # Outer widget return cls = w.winfo_class() if cls in WHEELED_WIDGETS: # When mouse pointer is over `WHEELED_WIDGETS` the canvas # must not be scrolled. But there are few exceptions for # convenience. try: a, b = w.yview() except: # not all "wheeled" widgets provides `yview` and those values # prevents heuristics about fully scrolled `w`idgets below. a, b = None, None if e.delta > 0: if a == 0.0: pass # w is fully scrolled up elif w.winfo_rooty() < canvas.winfo_rooty(): pass # user does not see upper border of w # XXX: we also have to prevent scrolling of `w` but # returning "break" does not work. else: return elif e.delta < 0: if b == 1.0: pass # w is fully scrolled down elif (w.winfo_rooty() + w.winfo_height() > canvas.winfo_rooty() + canvas.winfo_height()): pass # user does not see bottom border of w else: return else: return canvas.yview("scroll", -e.delta, "units") bind_all_mouse_wheel(inner, on_wheel, "+") return inner