From msa01 at bitflipper.ca Sat Apr 12 04:36:16 2014 From: msa01 at bitflipper.ca (Cam Farnell) Date: Fri, 11 Apr 2014 23:36:16 -0300 Subject: [Tkinter-discuss] Tkinter Text Undo In-Reply-To: References: <3766A980-82BA-4AA0-9F1F-5822C79AF1E1@passcal.nmt.edu> <5310BADA.6020301@bitflipper.ca> <6E01C189-AA5E-4F6F-A303-2C635608ADBB@passcal.nmt.edu> <03EB34F3-F69D-4A29-BBAB-EC1A27AD4229@passcal.nmt.edu> <532CF4B9.1020708@bitflipper.ca> Message-ID: <5348A6A0.4090102@bitflipper.ca> Am I missing something here? I was trying the Tkinter Text widget's undo feature. It works, sort of, but if for example you delete some text then when you undo the delete the text comes back but all it's tags are gone. Really????? If that's how it actually works and not just me being stupid, it makes the undo feature almost totally useless. Could someone who knows more about this than me shed some light on this? Python 2.7.3 on Ubuntu Linux. Thanks Cam Farnell From alan.gauld at btinternet.com Sun Apr 20 19:28:09 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 20 Apr 2014 18:28:09 +0100 Subject: [Tkinter-discuss] importing tk.W? In-Reply-To: References: Message-ID: On 11/03/14 03:27, memilanuk wrote: > appears I can use either a wildcard import, enclose it in quotes, or use > explicit reference e.g. tk.W. > > My question is this: How / why does this make any sense, that an > attribute (W) to an option (sticky=) would be imported at the same level > as widgets themselves? Is it some artifact left over from tcl, In a way it is a Tcl thing. The earliest Tcl including the original Tk did everything with strings using implicit conversion as needed. So in Tcl W and 'W' were treated as the same thing, no need for a constant. When Tkinter was invented Python needed constants or strings so Tkinter provided for both. Personally, I generally use the strings for options. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From alan.gauld at btinternet.com Sun Apr 20 19:30:04 2014 From: alan.gauld at btinternet.com (Alan Gauld) Date: Sun, 20 Apr 2014 18:30:04 +0100 Subject: [Tkinter-discuss] Is this the right place for Tix questions? Message-ID: I don't see a separate Tix group so is this a valid place to ask Tix questions? I've been trying to use some of the Tix widgets and running into issues, especially with tix.Grid formatting. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From Cameron at phaseit.net Mon Apr 21 14:58:02 2014 From: Cameron at phaseit.net (Cameron Laird) Date: Mon, 21 Apr 2014 12:58:02 +0000 Subject: [Tkinter-discuss] Is this the right place for Tix questions? In-Reply-To: References: Message-ID: <20140421125802.GA13402@lairds.us> On Sun, Apr 20, 2014 at 06:30:04PM +0100, Alan Gauld wrote: . . . > I don't see a separate Tix group so is this a valid place > to ask Tix questions? I've been trying to use some of > the Tix widgets and running into issues, especially > with tix.Grid formatting. . . . YES. From alan.gauld at btinternet.com Mon Apr 21 17:26:26 2014 From: alan.gauld at btinternet.com (ALAN GAULD) Date: Mon, 21 Apr 2014 16:26:26 +0100 (BST) Subject: [Tkinter-discuss] Tix Grid question, was: Re: Is this the right place for Tix questions? In-Reply-To: <20140421125802.GA13402@lairds.us> References: <20140421125802.GA13402@lairds.us> Message-ID: <1398093986.25781.YahooMailNeo@web186005.mail.ir2.yahoo.com> >> I don't see a separate Tix group so is this a valid place >> to ask Tix questions?? >??? ??? ??? . >YES. Good. I've been trying to convert some of the Tix examples in the Tcl/Tk? in a Ntshell O'Reilly book to Tkinter/Tix. The Tcl version works fine but the Python version gives an error although? it does display but without any grid/border formatting. The error I get is: Exception in Tkinter callback Traceback (most recent call last): ? File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__ ? ? return self.func(*args) ? File "tixgrid-test.py", line 10, in simpleFormat ? ? grd.format('grid', x1,y1,x2,y2, anchor='se', fill=0, relief='raised', ? File "/usr/lib/python3.2/tkinter/tix.py", line 341, in __getattr__ ? ? raise AttributeError(name) AttributeError: format The code is pretty much a straight translation of the Tcl from the book.: import tkinter.tix as tix top = tix.Tk() def simpleFormat(area, x1, y1, x2, y2): ? ? print(area,x1,y1,x2,y2) ? ? # see debug output below... ? ? if area == 'main': ? ? ? ?grd.format('grid', x1,y1,x2,y2, anchor='se', fill=0, relief='raised',? ? ? ? ? ? ? ? ? ? bd=1, bordercolor='gray20') ? ? elif area in ["x-margin", "y-margin", "s-margin"]: ? ? ? ?grd.format('border', x1,y1,x2,y2, fill=0, relief='raised',? ? ? ? ? ? ? ? ? ? bd=1, bordercolor='gray65') ? ? ? ? grd = tix.Grid(top, height=10, width=10) grd.config(formatcmd=simpleFormat) for x in range(10): ? ? grd.size_column(x, size='auto') ? ? for y in range(10): ? ? ? ? grd.set(x,y, itemtype='text', text="({},{})".format(x,y)) grd.size_column(0,size='10char') grd.pack(expand=True, fill='both') top.mainloop() The print() debug output looks like: y-margin 0 1 0 9 s-margin 0 0 0 0 main 1 1 9 9 and so on. It looks as if the format command is not recognised. I notice the docs? say it should only be called from the formatcmd function but that's? what I'm doing... Any pointers appreciated. And if anyone knows a decent book or? web site for Python Tix that would also be much appreciated.? I can get most things to work in Tix but the Grid has me beat? so far. Alan Gauld Author of the Learn To Program website http://www.alan-g.me.uk/ http://www.flickr.com/photos/alangauldphotos From klappnase at web.de Tue Apr 22 12:35:39 2014 From: klappnase at web.de (Michael Lange) Date: Tue, 22 Apr 2014 12:35:39 +0200 Subject: [Tkinter-discuss] Tix Grid question, was: Re: Is this the right place for Tix questions? In-Reply-To: <1398093986.25781.YahooMailNeo@web186005.mail.ir2.yahoo.com> References: <20140421125802.GA13402@lairds.us> <1398093986.25781.YahooMailNeo@web186005.mail.ir2.yahoo.com> Message-ID: <20140422123539.61124781825313f348fbd317@web.de> Hi, On Mon, 21 Apr 2014 16:26:26 +0100 (BST) ALAN GAULD wrote: (...) > The Tcl version works fine but the Python version gives an error > although it does display but without any grid/border formatting. The > error I get is: > > Exception in Tkinter callback > Traceback (most recent call last): > ? File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__ > ? ? return self.func(*args) > ? File "tixgrid-test.py", line 10, in simpleFormat > ? ? grd.format('grid', x1,y1,x2,y2, anchor='se', fill=0, > relief='raised', File "/usr/lib/python3.2/tkinter/tix.py", line 341, in > __getattr__ raise AttributeError(name) > AttributeError: format (...) A couple of years ago I have been playing around with this. IIRC some of the tixGrid's method are not implemented in the Python wrapper, probably because they are (were?) not documented in the tixGrid man page. According to http://tix.sourceforge.net/man/html/TixCmd/tixGrid.htm#M32 this is still the case for the format, index, selection and a number of other commands. Back then I wrote myself a custom Tix module with the missing Grid methods included, as far as I remember it served me well. I'll copy'n'paste my custom Grid class below, in case you have a use for it (but of course without warranty ;) Regards Michael ############################################################### class Grid(TixWidget): '''The Tix Grid command creates a new window and makes it into a tixGrid widget. Additional options, may be specified on the command line or in the option database to configure aspects such as its cursor and relief. A Grid widget displays its contents in a two dimensional grid of cells. Each cell may contain one Tix display item, which may be in text, graphics or other formats. See the DisplayStyle class for more information about Tix display items. Individual cells, or groups of cells, can be formatted with a wide range of attributes, such as its color, relief and border. Subwidgets - None STANDARD OPTIONS background borderwidth cursor font foreground height highlightbackground highlightcolor highlightthickness padx pady relief selectbackground selectborderwidth selectforeground state takefocus width xscrollcommand yscrollcommand WIDGET-SPECIFIC OPTIONS editdonecmd - If non-empty, gives a Tcl command to be executed when the user has edited a grid cell. When this command is called, it is passed with two additional parameters: column, row, where (column, row) is the location of the cell that has just been edited. editnotifycmd - If non-empty, gives a Tcl command to be executed when the user tries to edit a grid cell. When this command is called, it is passed with two additional parameters: column, row, where (column, row) is the location of the cell. This command should return a boolean value: true indicates that the cell is editable and false oth- erwise. floatingcols - ??? Requires a boolean. The default value is 0. ??? floatingrows - ??? Requires a boolean. The default value is 0. ??? formatcmd - If non-empty, gives a Tcl command to be executed when the grid cells need to be formatted on the screen. Normally, this command calls the format() widget command (see below). When this command is called, it is passed with five additional parameters: type x1 y1 x2 y2. type gives the logical type of the region in the grid. It may be one of the following. "x-region": the horizontal margin (as defined with topmargin); "y-region": the vertical margin (as defined with leftmargin); "s-region", the area where the horizontal and vertical margins are joined; "main": all the cells that do not fall into the above three types. x1 y1 x2 y2 gives the extent of the region that needs formatting. itemtype - ??? the default type of newly created grid cell items; may be "text" or "image"; default is "text" ??? leftmargin - In the number of cells, gives the width of vertical margin. A zero indicates that no vertical should be drawn (default: 1). Defines the number of columns that are fixed when the widget is horizontally scrolled. These column(s) can be used as label(s) for the row(s). selectmode - Specifies one of several styles for manipulating the selection. The value of the option may be arbitrary, but the default bind- ings expect it to be either single, browse, multiple, or extended; the default value is single. selectunit - Specifies the selection unit. Valid values are "cell", "column" or "row". sizecmd - ??? A command that is called whenever a grid cell is resized ??? topmargin - In the number of cells, gives the height of horizontal margin. A zero indicates that no horizontal should be drawn (default: 1). Defines the number of rows that are fixed when the widget is vertically scrolled. These row(s) can be used as label(s) for the column(s). ''' def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixGrid', ['options'], cnf, kw) def anchor_clear(self): '''Clears the selection anchor.''' self.tk.call(self._w, 'anchor', 'clear') def anchor_get(self): '''Return a tuple of the form (column, row) describing the cell that is the current selection anchor.''' return self._getints(self.tk.call(self._w, 'anchor', 'get')) def anchor_set(self, column, row): '''Set the selection anchor to the cell at (column, row).''' self.tk.call(self._w, 'anchor', 'set', column, row) def bdtype(self, x, y, xbdWidth=None, ybdWidth=None): '''?????''' # FIXME # what is this for? return self.tk.call(self._w, 'bdtype', x, y, xbdWidth, ybdWidth) def delete_column(self, from_, to=None): '''If TO is not given, deletes a single column at the position FROM. If TO is given, deletes the range of columns from position FROM through TO.''' self.tk.call(self._w, 'delete', 'column', from_, to) def delete_row(self, from_, to=None): '''If TO is not given, deletes a single row at the position FROM. If TO is given, deletes the range of rows from position FROM through TO.''' self.tk.call(self._w, 'delete', 'row', from_, to) # FIXME: dragsite and dropsite are not documented, but they seem to do at least *something* def dragsite_clear(self): self.tk.call(self._w, 'dragsite', 'clear') def dragsite_get(self): return self._getints(self.tk.call(self._w, 'dragsite', 'get')) def dragsite_set(self, x, y): self.tk.call(self._w, 'dragsite', 'set', x, y) def dropsite_clear(self): self.tk.call(self._w, 'dropsite', 'clear') def dropsite_get(self): return self._getints(self.tk.call(self._w, 'dropsite', 'get')) def dropsite_set(self, x, y): self.tk.call(self._w, 'dropsite', 'set', x, y) def edit_apply(self): '''If any cell is being edited, de-highlight the cell and applies the changes.''' self.tk.call(self._w, 'edit', 'apply') def edit_set(self, column, row): '''Highlights the cell at (column, row) for editing, if the -editnotify command returns True for this cell.''' self.tk.call(self._w, 'edit', 'set', column, row) def entrycget(self, column, row, option): '''Returns the current value of the configuration option given by OPTION of the cell at (column, row). OPTION may have any of the values accepted by the set() widget command.''' return self.tk.call(self._w, 'entrycget', column, row, '-'+option) def entryconfigure(self, column, row, cnf=None, **kw): '''Query or modify the configuration options of the cell at (x,y). If no option is specified, returns a list describing all of the available options for the cell (see Tk_ConfigureInfo(n) for information on the format of this list.) If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the correspond- ing sublist of the value returned if no option is specified.) If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the values accepted by the set() widget command.''' return self._configure(('entryconfigure', column, row), cnf, kw) entryconfig = entryconfigure def format_border(self, col0, row0, col1, row1, **kw): '''The format_border() method can only be called by the formatcmd callback of the widget. Formats the border of the grid cells from (col0, row0) through (col1, row1). Possible options are: filled - boolean xon - boolean xoff - boolean yon - boolean yoff - boolean relief, bg, bd, selectbackground etc. ???''' self.tk.call(self._w, 'format', 'border', col0, row0, col1, row1, *self._options({}, kw)) def format_grid(self, col0, row0, col1, row1, **kw): '''The format_grid() method can only be called by the formatcmd callback of the widget. Formats the grid cells from (col0, row0) through (col1, row1). Possible options are: bordercolor - color filled - boolean xon - boolean xoff - boolean yon - boolean yoff - boolean bg, selectbackground, anchor etc ????''' self.tk.call(self._w, 'format', 'grid', col0, row0, col1, row1, *self._options({}, kw)) # FIXME: geometryinfo is not documented, and though it seems to work I cannot # find the use of this command def geometryinfo(self, width=None, height=None): '''?????''' # has this really to be done like this? return tuple([self._getdoubles(x) for x in self.tk.split(self.tk.call(self._w, 'geometryinfo', width, height))]) def index(self, column, row): '''Return a tuple of the form (column, row) describing the grid cell at index (column, row). COLUMN and ROW may be "max" (i.e. the last defined column resp. row) or "end" (i.e. max + 1). (???)''' # FIXME # COLUMN or ROW may be "end" or "max" instead of a numerical index; is this all of this method's use? return self._getints(self.tk.call(self._w, 'index', column, row)) # FIXME: info is not documented, maybe because info_bbox() does not seem to have any effect # info_exists seems to work well def info_bbox(self, column, row): '''???''' return self._getints(self.tk.call(self._w, 'info', 'bbox', column, row)) def info_exists(self, column, row): '''Returns True if the cell at COLUMN and ROW exists, else returns False.''' return self._getboolean(self.tk.call(self._w, 'info', 'exists', column, row)) def move_column(self, from_, to, offset): '''Moves the the range of columns from position FROM through TO by the distance indicated by OFFSET. For example, move_column(2, 4, 1) moves the columns 2,3,4 to columns 3,4,5.''' self.tk.call(self._w, 'move', 'column', from_, to, offset) def move_row(self, from_, to, offset): '''Moves the the range of rows from position FROM through TO by the distance indicated by OFFSET. For example, move_row(2, 4, 1) moves the rows 2,3,4 to rows 3,4,5.''' self.tk.call(self._w, 'move', 'row', from_, to, offset) # FIXME: this is not documented, but seems to work def nearest(self, x, y): '''Returns a tuple of the form (column, row) describing the grid cell nearest to window coordinates x and y.''' return self._getints(self.tk.call(self._w, 'nearest', x, y)) # FIXME: selection methods are not documented in the man page # maybe this is because only adjust, set and toggle (and partially clear) seem to work def selection_adjust(self, col0, row0, col1=None, row1=None): '''Removes the selection from all grid cells and adds the cell at (col0, row0) to the selection; if col1 and row1 are given, adds the range of cells from (col0, row0) through (col1, row1) to the selection.''' self.tk.call(self._w, 'selection', 'adjust', col0, row0, col1, row1) select_adjust = selection_adjust def selection_clear(self, col0=0, row0=0, col1='max', row1='max'): # this seems to work only with selection_clear(0, 0, 'max', 'max'), # which removes any selection '''Removes the selection from all grid cells.''' self.tk.call(self._w, 'select', 'clear', col0, row0, col1, row1) select_clear = selection_clear def selection_includes(self, column, row): # this does not seem to have any effect '''???Returns True if the grid cell at (column, row) is currently selected, else returns False.??? (I guess it should).''' return self._getboolean(self.tk.call(self._w, 'selection', 'includes', column, row)) select_includes = selection_includes def selection_set(self, col0, row0, col1=None, row1=None): '''Adds the cell at (col0, row0) to the selection; if col1 and row1 are given, adds the range of cells from (col0, row0) through (col1, row1) to the selection.''' self.tk.call(self._w, 'selection', 'set', col0, row0, col1, row1) select_set = selection_set def selection_toggle(self, col0, row0, col1=None, row1=None): '''Changes the state of selection for the cell at (col0, row0); if col1 and row1 are given, changes the state of selection for the range of cells from (col0, row0) through (col1, row1).''' self.tk.call(self._w, 'selection', 'toggle', col0, row0, col1, row1) select_toggle = selection_toggle def set(self, column, row, **kw): '''Creates a new display item at the cell at (column, row). The optional -itemtype parameter gives the type of the display item ("text" or "image" ???). An addi- tional list of option-value pairs specify options of the display item. If a display item already exists at this cell, the old item will be deleted automatically. Possible options for text items are: text, style, underline Possible options for image items are: image, style.''' self.tk.call(self._w, 'set', column, row, *self._options({}, kw)) def size_column(self, index, **kw): '''Queries or sets the size of the column given by INDEX. INDEX may be any non-negative integer that gives the position of a given column. INDEX can also be the string "default"; in this case, this command queries or sets the default size of all columns. When no option-value pair is given, this command returns a tuple con- taining the current size setting of the given column. When option-value pairs are given, the corresponding options of the size setting of the given column are changed. Options may be one of the foll- wing: pad0 pixels Specifies the paddings to the left of a column. pad1 pixels Specifies the paddings to the right of a column. size val Specifies the width of a column . Val may be: "auto" -- the width of the column is set the the widest cell in the column; a valid Tk screen distance unit (see Tk_GetPixels(n)); or a real number following by the word chars (e.g. 3.4chars) that sets the width of the column to the given number of characters.''' return self.tk.split(self.tk.call(self._w, 'size', 'column', index, *self._options({}, kw))) def size_row(self, index, **kw): '''Queries or sets the size of the row given by INDEX. INDEX may be any non-negative integer that gives the position of a given row . INDEX can also be the string "default"; in this case, this command queries or sets the default size of all rows. When no option-value pair is given, this command returns a list con- taining the current size setting of the given row . When option-value pairs are given, the corresponding options of the size setting of the given row are changed. Options may be one of the foll- wing: pad0 pixels Specifies the paddings to the top of a row. pad1 pixels Specifies the paddings to the the bottom of a row. size val Specifies the height of a row. Val may be: "auto" -- the height of the row is set the the highest cell in the row; a valid Tk screen distance unit (see Tk_GetPixels(n)); or a real number following by the word chars (e.g. 3.4chars) that sets the height of the row to the given number of characters.''' return self.tk.split(self.tk.call(self._w, 'size', 'row', index, *self._options({}, kw))) # FIXME: sort is not documented, but the the widget accepts the command # and it seems to work at least for the most part def sort_column(self, first, last, **kw): '''Sorts columns in the range from FIRST through LAST, according to the given options. Possible options are: command : a tcl command that accepts two items as arguments, compares these and returns a proper boolean value. key : the index of the row to compare the items' values from. order : must be "increasing" or "decreasing". type : must be "ascii", "integer" or "real".''' self.tk.call(self._w, 'sort', 'column', first, last, *self._options({}, kw)) def sort_row(self, first, last, **kw): '''Sorts rows in the range from FIRST through LAST, according to the given options. Possible options are: command : a tcl command that accepts two items as arguments, compares these and returns a proper boolean value. key : the index of the column to compare the items' values from. order : must be "increasing" or "decreasing". type : must be "ascii", "integer" or "real".''' self.tk.call(self._w, 'sort', 'row', first, last, *self._options({}, kw)) def unset(self, column, row): '''Clears the cell at (column, row) by removing its display item.''' self.tk.call(self._w, 'unset', column, row) def xview(self, *what): """Query and change horizontal position of the view.""" if not what: return self._getdoubles(self.tk.call(self._w, 'xview')) self.tk.call((self._w, 'xview') + what) def xview_moveto(self, fraction): """Adjust the view in the window so that FRACTION of the total width of the entry is off-screen to the left.""" self.tk.call(self._w, 'xview', 'moveto', fraction) def xview_scroll(self, number, what): """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'xview', 'scroll', number, what) def yview(self, *what): """Query and change vertical position of the view.""" if not what: return self._getdoubles(self.tk.call(self._w, 'yview')) self.tk.call((self._w, 'yview') + what) def yview_moveto(self, fraction): """Adjust the view in the window so that FRACTION of the total width of the entry is off-screen to the top.""" self.tk.call(self._w, 'yview', 'moveto', fraction) def yview_scroll(self, number, what): """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) class _dummyGrid(Grid, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class ScrolledGrid(TixWidget): '''Scrolled Grid widgets''' # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixScrolledGrid', ['options'], cnf, kw) self.subwidget_list['grid'] = _dummyGrid(self, 'grid') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') # we cannot use the self.grid shortcut to access the Grid subwidget here # because it conflicts with the grid() geometry method, so add a grid_ attribute as a replacement self.grid_ = self.subwidget('grid') ############################################################### .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Vulcans do not approve of violence. -- Spock, "Journey to Babel", stardate 3842.4