Module tkintertable.App

Sample App to illustrate table functionality. Created January 2008 Copyright (C) Damien Farrell

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Source code
#!/usr/bin/env python
"""
    Sample App to illustrate table functionality.
    Created January 2008
    Copyright (C) Damien Farrell

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""

from __future__ import absolute_import, division, print_function
try:
    from tkinter import *
    from tkinter.ttk import *
except:
    from Tkinter import *
    from ttk import *
if (sys.version_info > (3, 0)):
    from tkinter import filedialog, messagebox, simpledialog
    from tkinter import font
else:
    import tkFileDialog as filedialog
    import tkSimpleDialog as simpledialog
    import tkMessageBox as messagebox
    import tkFont as font

#import Pmw
import re, os, time, pickle
from collections import OrderedDict
from .Custom import MyTable
from .TableModels import TableModel
from .Tables_IO import TableImporter
from .Prefs import Preferences

class TablesApp(Frame):
    """
    Tables app
    """
    def __init__(self,parent=None,data=None,datafile=None):
        "Initialize the application."
        self.parent=parent

        #If there is data to be loaded, show the dialog first
        if not self.parent:
            Frame.__init__(self)
            self.tablesapp_win=self.master

        else:
            self.tablesapp_win=Toplevel()

        # Get platform into a variable
        import platform
        self.currplatform=platform.system()
        if not hasattr(self,'defaultsavedir'):
            self.defaultsavedir = os.getcwd()

        self.preferences=Preferences('TablesApp',{'check_for_update':1})
        self.loadprefs()
        self.tablesapp_win.title('Tables Application')
        self.tablesapp_win.geometry('+200+200')
        self.x_size=800
        self.y_size=600
        self.createMenuBar()
        self.apptoolBar = ToolBar(self.tablesapp_win, self)
        self.apptoolBar.pack(fill=BOTH, expand=NO)
        #add find bar
        #self.createSearchBar()

        if data != None:
            self.data = data
            self.new_project(data)
        elif datafile != None:
            self.open_project(datafile)
        else:
            self.new_project()

        self.tablesapp_win.protocol('WM_DELETE_WINDOW',self.quit)
        return

    def createMenuBar(self):
        """Create the menu bar for the application. """

        self.menu=Menu(self.tablesapp_win)
        self.proj_menu={'01New':{'cmd':self.new_project},
                        '02Open':{'cmd':self.open_project},
                        '03Close':{'cmd':self.close_project},
                        '04Save':{'cmd':self.save_project},
                        '05Save As':{'cmd':self.save_as_project},
                        '06Preferences..':{'cmd':self.showPrefsDialog},
                        '08Quit':{'cmd':self.quit}}
        if self.parent:
            self.proj_menu['08Return to Database']={'cmd':self.return_data}
        self.proj_menu=self.create_pulldown(self.menu,self.proj_menu)
        self.menu.add_cascade(label='Project',menu=self.proj_menu['var'])

        self.records_menu={'01Add Row':{'cmd':self.add_Row},
                         '02Delete Row':{'cmd':self.delete_Row},
                         '03Add Column':{'cmd':self.add_Column},
                         '04Delete Column':{'cmd':self.delete_Column},
                         '05Auto Add Rows':{'cmd':self.autoAdd_Rows},
                         '06Auto Add Columns':{'cmd':self.autoAdd_Columns},
                         '07Find':{'cmd':self.createSearchBar},
                         }
        self.records_menu=self.create_pulldown(self.menu,self.records_menu)
        self.menu.add_cascade(label='Records',menu=self.records_menu['var'])

        self.sheet_menu={'01Add Sheet':{'cmd':self.add_Sheet},
                         '02Remove Sheet':{'cmd':self.delete_Sheet},
                         '03Copy Sheet':{'cmd':self.copy_Sheet},
                         '04Rename Sheet':{'cmd':self.rename_Sheet},
                         }
        self.sheet_menu=self.create_pulldown(self.menu,self.sheet_menu)
        self.menu.add_cascade(label='Sheet',menu=self.sheet_menu['var'])

        self.IO_menu={'01Import from csv file':{'cmd':self.import_csv},
                      '02Export to csv file':{'cmd':self.export_csv},
                      }

        self.IO_menu=self.create_pulldown(self.menu,self.IO_menu)
        self.menu.add_cascade(label='Import/Export',menu=self.IO_menu['var'])

        # Help menu
        self.help_menu={'01Online Help':{'cmd':self.online_documentation},
                        '02About':{'cmd':self.about_Tables}}
        self.help_menu=self.create_pulldown(self.menu,self.help_menu)
        self.menu.add_cascade(label='Help',menu=self.help_menu['var'])

        self.tablesapp_win.config(menu=self.menu)

        return

    def create_pulldown(self,menu,dict):
        """ Create a pulldown in var from the info in dict  """

        var = Menu(menu,tearoff=0)
        items = dict.keys()
        #items.sort()
        for item in items:
            if item[-3:]=='sep':
                var.add_separator()
            else:
                # Do we have a command?
                command=None
                if 'cmd' in  dict[item]:
                    command=dict[item]['cmd']

                # Put the command in there
                if 'sc' in dict[item]:
                    var.add_command(label='%-25s %9s' %(item[2:],dict[item]['sc']),command=command)
                else:
                    var.add_command(label='%-25s' %(item[2:]),command=command)
        dict['var']=var
        return dict

    def createSearchBar(self, event=None):
        """Add a find entry box"""

        frame = Frame(self.tablesapp_win)
        row=0
        def close():
            frame.destroy()
        self.findtext=StringVar()
        self.findbox=Entry(frame,textvariable=self.findtext,width=30,bg='white')
        self.findbox.grid(row=row,column=1,sticky='news',columnspan=2,padx=2,pady=2)
        self.findbox.bind('<Return>',self.do_find_text)
        Label(frame,text='Find:').grid(row=row,column=0,sticky='ew')
        self.findagainbutton=Button(frame,text='Find Again', command=self.do_find_again)
        self.findagainbutton.grid(row=row,column=3,sticky='news',padx=2,pady=2)
        self.cbutton=Button(frame,text='Close', command=close)
        self.cbutton.grid(row=row,column=4,sticky='news',padx=2,pady=2)
        frame.pack(fill=BOTH, expand=NO)
        return

    def loadprefs(self):
        """Setup default prefs file if any of the keys are not present"""

        defaultprefs = {'textsize':14,
                         'windowwidth': 800 ,'windowheight':600}
        for prop in defaultprefs.keys():
            try:
                self.preferences.get(prop)
            except:
                self.preferences.set(prop, defaultprefs[prop])

        return

    def showPrefsDialog(self):
        self.prefswindow = self.currenttable.showtablePrefs()
        return

    def new_project(self, data=None):
        """Create a new table, with model and add the frame"""

        if hasattr(self,'currenttable'):
            self.notebook.destroy()
            self.currenttable.destroy()

        #Create the sheets dict
        self.sheets = {}
        self.notebook = Notebook(self.tablesapp_win)
        self.notebook.pack(fill='both', expand=1, padx=4, pady=4)
        if data !=None:
            for s in data.keys():
                sdata = data[s]
                try:
                    self.add_Sheet(s ,sdata)
                except:
                    print ('skipping')
        else:
            #do the table adding stuff for the initial sheet
            self.add_Sheet('sheet1')
        #self.notebook.setnaturalsize()
        return

    def open_project(self, filename=None):

        if filename == None:
            filename=filedialog.askopenfilename(defaultextension='.tblprj"',
                                                      initialdir=os.getcwd(),
                                                      filetypes=[("TableApp project","*.tblprj"),
                                                                 ("All files","*.*")],
                                                      parent=self.tablesapp_win)
        if os.path.isfile(filename):
            fd = open(filename, 'rb')
            data = pickle.load(fd)
            fd.close()
        self.new_project(data)
        self.filename=filename
        return

    def save_project(self):

        if not hasattr(self, 'filename'):
            self.save_as_project()
        elif self.filename == None:
            self.save_as_project()
        else:
            self.do_save_project(self.filename)

        return

    def save_as_project(self):
        """Save as a new filename"""

        filename=filedialog.asksaveasfilename(parent=self.tablesapp_win,
                                                defaultextension='.tblprj',
                                                initialdir=self.defaultsavedir,
                                                filetypes=[("TableApp project","*.tblprj"),
                                                           ("All files","*.*")])
        if not filename:
            print ('Returning')
            return
        self.filename=filename
        self.do_save_project(self.filename)
        return

    def do_save_project(self, filename):
        """Get model dicts and write all to pickle file"""

        data={}
        for s in self.sheets.keys():
            currtable = self.sheets[s]
            model = currtable.getModel()
            data[s] = model.getData()

        fd=open(filename,'wb')
        pickle.dump(data,fd)
        fd.close()
        return

    def close_project(self):
        if hasattr(self,'currenttable'):
            #self.notebook.destroy()
            self.currenttable.destroy()
        return

    def import_csv(self):

        importer = TableImporter()
        #just use the dialog to load and import the file
        importdialog = importer.import_Dialog(self.tablesapp_win)
        self.tablesapp_win.wait_window(importdialog)
        model = TableModel()
        model.importDict(importer.data)
        sheetdata = {}
        sheetdata['sheet1'] = model.getData()
        self.new_project(sheetdata)
        return

    def export_csv(self):
        from .Tables_IO import TableExporter
        exporter = TableExporter()
        exporter.ExportTableData(self.currenttable)
        return

    def add_Sheet(self, sheetname=None, sheetdata=None):
        """Add a new sheet - handles all the table creation stuff"""

        def checksheet_name(name):
            if name == '':
                messagebox.showwarning("Whoops", "Name should not be blank.")
                return 0
            if name in self.sheets:
                messagebox.showwarning("Name exists", "Sheet name already exists!")
                return 0
        names = [self.notebook.tab(i, "text") for i in self.notebook.tabs()]
        noshts = len(names)
        if sheetname == None:
            sheetname = simpledialog.askstring("New sheet name?", "Enter sheet name:",
                                                initialvalue='sheet'+str(noshts+1))
        checksheet_name(sheetname)
        page = Frame(self.notebook)
        self.notebook.add(page, text=sheetname)
        #Create the table and model if data present
        if sheetdata != None:
            model = TableModel(sheetdata)
            self.currenttable = MyTable(page, model)
        else:
            self.currenttable = MyTable(page)

        #Load preferences into table
        self.currenttable.loadPrefs(self.preferences)
        #This handles all the canvas and header in the frame passed to constructor
        self.currenttable.createTableFrame()
        #add the table to the sheet dict
        self.sheets[sheetname] = self.currenttable
        self.saved = 0
        return sheetname

    def delete_Sheet(self):
        """Delete a sheet"""

        s = self.notebook.index(self.notebook.select())
        name = self.notebook.tab(s, 'text')
        #self.notebook.delete(s)
        self.notebook.forget(s)
        del self.sheets[s]
        return

    def copy_Sheet(self, newname=None):
        """Copy a sheet"""

        newdata = self.currenttable.getModel().getData().copy()
        if newname==None:
            self.add_Sheet(None, newdata)
        else:
            self.add_Sheet(newname, newdata)
        return

    def rename_Sheet(self):
        """Rename a sheet"""

        #s = self.notebook.getcurselection()
        s = self.notebook.index(self.notebook.select())
        newname = simpledialog.askstring("New sheet name?", "Enter new sheet name:",
                                                initialvalue=s)
        if newname == None:
            return
        self.copy_Sheet(newname)
        self.delete_Sheet()
        return

    def setcurrenttable(self, event):
        """Set the currenttable so that menu items work with visible sheet"""

        try:
            #s = self.notebook.getcurselection()
            s = self.notebook.index(self.notebook.select())
            self.currenttable = self.sheets[s]
        except:
            pass
        return

    def add_Row(self):
        """Add a new row"""
        self.currenttable.addRow()
        self.saved = 0
        return

    def delete_Row(self):
        """Delete currently selected row"""

        self.currenttable.deleteRow()
        self.saved = 0
        return

    def add_Column(self):
        """Add a new column"""

        self.currenttable.addColumn()
        self.saved = 0
        return

    def delete_Column(self):
        """Delete currently selected column in table"""

        self.currenttable.deleteColumn()
        self.saved = 0
        return

    def autoAdd_Rows(self):
        """Auto add x rows"""

        self.currenttable.autoAddRows()
        self.saved = 0
        return

    def autoAdd_Columns(self):
        """Auto add x rows"""

        self.currenttable.autoAddColumns()
        self.saved = 0
        return

    def findValue(self):
        self.currenttable.findValue()
        return

    def do_find_text(self, event=None):
        """Find the text in the table"""

        if not hasattr(self,'currenttable'):
            return
        import string
        if string.strip(self.findtext.get())=='':
            return
        searchstring=self.findtext.get()
        if self.currenttable!=None:
            self.currenttable.findValue(searchstring)
        return

    def do_find_again(self, event=None):
        """Find again"""

        if not hasattr(self,'currenttable'):
            return
        searchstring=self.findtext.get()
        if self.currenttable!=None:
            self.currenttable.findValue(searchstring, findagain=1)
        return

    def plot(self, event=None):
        self.currenttable.plotSelected()
        return

    def plotSetup(self, event=None):
        self.currenttable.plotSetup()
        return

    def about_Tables(self):

        self.ab_win=Toplevel()
        self.ab_win.geometry('+100+350')
        self.ab_win.title('About TablesApp')

        from . import Table_images
        logo = Table_images.tableapp_logo()
        label = Label(self.ab_win,image=logo)
        label.image = logo
        label.grid(row=0,column=0,sticky='news',padx=4,pady=4)

        text=['Tables Sample App ','Shows the use of Tablecanvas class for tkinter',
                'Copyright (C) Damien Farrell 2008-', 'This program is free software; you can redistribute it and/or',
                'modify it under the terms of the GNU General Public License',
                'as published by the Free Software Foundation; either version 2',
                'of the License, or (at your option) any later version.']
        row=1
        for line in text:
            tmp=Label(self.ab_win,text=line)
            tmp.grid(row=row,column=0,sticky='news',padx=4)
            row=row+1
        return

    def online_documentation(self,event=None):
        """Open the online documentation"""

        import webbrowser
        link='http://sourceforge.net/projects/tkintertable/'
        webbrowser.open(link,autoraise=1)
        return

    def quit(self):
        self.tablesapp_win.destroy()

        return

class ToolBar(Frame):
    """Uses the parent instance to provide the functions"""

    def __init__(self, parent=None, parentapp=None):
        Frame.__init__(self, parent, width=600, height=40)
        from . import Table_images
        self.parentframe = parent
        self.parentapp = parentapp
        #add buttons
        img = Table_images.new_proj()
        self.add_button('New Project', self.parentapp.new_project, img)
        img = Table_images.open_proj()
        self.add_button('Open Project', self.parentapp.open_project, img)
        img = Table_images.save_proj()
        self.add_button('Save Project', self.parentapp.save_project, img)
        img = Table_images.add_row()
        self.add_button('Add record', self.parentapp.add_Row, img)
        img = Table_images.add_col()
        self.add_button('Add col', self.parentapp.add_Column, img)
        img = Table_images.del_row()
        self.add_button('Delete record', self.parentapp.delete_Row, img)
        img = Table_images.del_col()
        self.add_button('Delete col', self.parentapp.delete_Column, img)
        img = Table_images.plot()
        self.add_button('Plot', self.parentapp.plot, img)
        img = Table_images.plotprefs()
        self.add_button('Plot Prefs', self.parentapp.plotSetup, img)

        return

    def add_button(self, name, callback, img=None):
        if img==None:
            b = Button(self, text=name, command=callback)
        else:
            b = Button(self, text=name, command=callback,
                             image=img)
        b.image = img
        b.pack(side=LEFT, padx=2, pady=2, ipadx=1, ipady=1)

        return

# Main function, run when invoked as a stand-alone Python program.

def main():
    "Run the application"
    import sys, os
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-f", "--file", dest="tablefile",
                        help="Open a table file", metavar="FILE")
    opts, remainder = parser.parse_args()
    if opts.tablefile != None:
        app=TablesApp(datafile=opts.tablefile)
    else:
        app=TablesApp()
    app.mainloop()
    return

if __name__ == '__main__':
    main()

Functions

def main()

Run the application

Source code
def main():
    "Run the application"
    import sys, os
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-f", "--file", dest="tablefile",
                        help="Open a table file", metavar="FILE")
    opts, remainder = parser.parse_args()
    if opts.tablefile != None:
        app=TablesApp(datafile=opts.tablefile)
    else:
        app=TablesApp()
    app.mainloop()
    return

Classes

class TablesApp (parent=None, data=None, datafile=None)

Tables app

Initialize the application.

Source code
class TablesApp(Frame):
    """
    Tables app
    """
    def __init__(self,parent=None,data=None,datafile=None):
        "Initialize the application."
        self.parent=parent

        #If there is data to be loaded, show the dialog first
        if not self.parent:
            Frame.__init__(self)
            self.tablesapp_win=self.master

        else:
            self.tablesapp_win=Toplevel()

        # Get platform into a variable
        import platform
        self.currplatform=platform.system()
        if not hasattr(self,'defaultsavedir'):
            self.defaultsavedir = os.getcwd()

        self.preferences=Preferences('TablesApp',{'check_for_update':1})
        self.loadprefs()
        self.tablesapp_win.title('Tables Application')
        self.tablesapp_win.geometry('+200+200')
        self.x_size=800
        self.y_size=600
        self.createMenuBar()
        self.apptoolBar = ToolBar(self.tablesapp_win, self)
        self.apptoolBar.pack(fill=BOTH, expand=NO)
        #add find bar
        #self.createSearchBar()

        if data != None:
            self.data = data
            self.new_project(data)
        elif datafile != None:
            self.open_project(datafile)
        else:
            self.new_project()

        self.tablesapp_win.protocol('WM_DELETE_WINDOW',self.quit)
        return

    def createMenuBar(self):
        """Create the menu bar for the application. """

        self.menu=Menu(self.tablesapp_win)
        self.proj_menu={'01New':{'cmd':self.new_project},
                        '02Open':{'cmd':self.open_project},
                        '03Close':{'cmd':self.close_project},
                        '04Save':{'cmd':self.save_project},
                        '05Save As':{'cmd':self.save_as_project},
                        '06Preferences..':{'cmd':self.showPrefsDialog},
                        '08Quit':{'cmd':self.quit}}
        if self.parent:
            self.proj_menu['08Return to Database']={'cmd':self.return_data}
        self.proj_menu=self.create_pulldown(self.menu,self.proj_menu)
        self.menu.add_cascade(label='Project',menu=self.proj_menu['var'])

        self.records_menu={'01Add Row':{'cmd':self.add_Row},
                         '02Delete Row':{'cmd':self.delete_Row},
                         '03Add Column':{'cmd':self.add_Column},
                         '04Delete Column':{'cmd':self.delete_Column},
                         '05Auto Add Rows':{'cmd':self.autoAdd_Rows},
                         '06Auto Add Columns':{'cmd':self.autoAdd_Columns},
                         '07Find':{'cmd':self.createSearchBar},
                         }
        self.records_menu=self.create_pulldown(self.menu,self.records_menu)
        self.menu.add_cascade(label='Records',menu=self.records_menu['var'])

        self.sheet_menu={'01Add Sheet':{'cmd':self.add_Sheet},
                         '02Remove Sheet':{'cmd':self.delete_Sheet},
                         '03Copy Sheet':{'cmd':self.copy_Sheet},
                         '04Rename Sheet':{'cmd':self.rename_Sheet},
                         }
        self.sheet_menu=self.create_pulldown(self.menu,self.sheet_menu)
        self.menu.add_cascade(label='Sheet',menu=self.sheet_menu['var'])

        self.IO_menu={'01Import from csv file':{'cmd':self.import_csv},
                      '02Export to csv file':{'cmd':self.export_csv},
                      }

        self.IO_menu=self.create_pulldown(self.menu,self.IO_menu)
        self.menu.add_cascade(label='Import/Export',menu=self.IO_menu['var'])

        # Help menu
        self.help_menu={'01Online Help':{'cmd':self.online_documentation},
                        '02About':{'cmd':self.about_Tables}}
        self.help_menu=self.create_pulldown(self.menu,self.help_menu)
        self.menu.add_cascade(label='Help',menu=self.help_menu['var'])

        self.tablesapp_win.config(menu=self.menu)

        return

    def create_pulldown(self,menu,dict):
        """ Create a pulldown in var from the info in dict  """

        var = Menu(menu,tearoff=0)
        items = dict.keys()
        #items.sort()
        for item in items:
            if item[-3:]=='sep':
                var.add_separator()
            else:
                # Do we have a command?
                command=None
                if 'cmd' in  dict[item]:
                    command=dict[item]['cmd']

                # Put the command in there
                if 'sc' in dict[item]:
                    var.add_command(label='%-25s %9s' %(item[2:],dict[item]['sc']),command=command)
                else:
                    var.add_command(label='%-25s' %(item[2:]),command=command)
        dict['var']=var
        return dict

    def createSearchBar(self, event=None):
        """Add a find entry box"""

        frame = Frame(self.tablesapp_win)
        row=0
        def close():
            frame.destroy()
        self.findtext=StringVar()
        self.findbox=Entry(frame,textvariable=self.findtext,width=30,bg='white')
        self.findbox.grid(row=row,column=1,sticky='news',columnspan=2,padx=2,pady=2)
        self.findbox.bind('<Return>',self.do_find_text)
        Label(frame,text='Find:').grid(row=row,column=0,sticky='ew')
        self.findagainbutton=Button(frame,text='Find Again', command=self.do_find_again)
        self.findagainbutton.grid(row=row,column=3,sticky='news',padx=2,pady=2)
        self.cbutton=Button(frame,text='Close', command=close)
        self.cbutton.grid(row=row,column=4,sticky='news',padx=2,pady=2)
        frame.pack(fill=BOTH, expand=NO)
        return

    def loadprefs(self):
        """Setup default prefs file if any of the keys are not present"""

        defaultprefs = {'textsize':14,
                         'windowwidth': 800 ,'windowheight':600}
        for prop in defaultprefs.keys():
            try:
                self.preferences.get(prop)
            except:
                self.preferences.set(prop, defaultprefs[prop])

        return

    def showPrefsDialog(self):
        self.prefswindow = self.currenttable.showtablePrefs()
        return

    def new_project(self, data=None):
        """Create a new table, with model and add the frame"""

        if hasattr(self,'currenttable'):
            self.notebook.destroy()
            self.currenttable.destroy()

        #Create the sheets dict
        self.sheets = {}
        self.notebook = Notebook(self.tablesapp_win)
        self.notebook.pack(fill='both', expand=1, padx=4, pady=4)
        if data !=None:
            for s in data.keys():
                sdata = data[s]
                try:
                    self.add_Sheet(s ,sdata)
                except:
                    print ('skipping')
        else:
            #do the table adding stuff for the initial sheet
            self.add_Sheet('sheet1')
        #self.notebook.setnaturalsize()
        return

    def open_project(self, filename=None):

        if filename == None:
            filename=filedialog.askopenfilename(defaultextension='.tblprj"',
                                                      initialdir=os.getcwd(),
                                                      filetypes=[("TableApp project","*.tblprj"),
                                                                 ("All files","*.*")],
                                                      parent=self.tablesapp_win)
        if os.path.isfile(filename):
            fd = open(filename, 'rb')
            data = pickle.load(fd)
            fd.close()
        self.new_project(data)
        self.filename=filename
        return

    def save_project(self):

        if not hasattr(self, 'filename'):
            self.save_as_project()
        elif self.filename == None:
            self.save_as_project()
        else:
            self.do_save_project(self.filename)

        return

    def save_as_project(self):
        """Save as a new filename"""

        filename=filedialog.asksaveasfilename(parent=self.tablesapp_win,
                                                defaultextension='.tblprj',
                                                initialdir=self.defaultsavedir,
                                                filetypes=[("TableApp project","*.tblprj"),
                                                           ("All files","*.*")])
        if not filename:
            print ('Returning')
            return
        self.filename=filename
        self.do_save_project(self.filename)
        return

    def do_save_project(self, filename):
        """Get model dicts and write all to pickle file"""

        data={}
        for s in self.sheets.keys():
            currtable = self.sheets[s]
            model = currtable.getModel()
            data[s] = model.getData()

        fd=open(filename,'wb')
        pickle.dump(data,fd)
        fd.close()
        return

    def close_project(self):
        if hasattr(self,'currenttable'):
            #self.notebook.destroy()
            self.currenttable.destroy()
        return

    def import_csv(self):

        importer = TableImporter()
        #just use the dialog to load and import the file
        importdialog = importer.import_Dialog(self.tablesapp_win)
        self.tablesapp_win.wait_window(importdialog)
        model = TableModel()
        model.importDict(importer.data)
        sheetdata = {}
        sheetdata['sheet1'] = model.getData()
        self.new_project(sheetdata)
        return

    def export_csv(self):
        from .Tables_IO import TableExporter
        exporter = TableExporter()
        exporter.ExportTableData(self.currenttable)
        return

    def add_Sheet(self, sheetname=None, sheetdata=None):
        """Add a new sheet - handles all the table creation stuff"""

        def checksheet_name(name):
            if name == '':
                messagebox.showwarning("Whoops", "Name should not be blank.")
                return 0
            if name in self.sheets:
                messagebox.showwarning("Name exists", "Sheet name already exists!")
                return 0
        names = [self.notebook.tab(i, "text") for i in self.notebook.tabs()]
        noshts = len(names)
        if sheetname == None:
            sheetname = simpledialog.askstring("New sheet name?", "Enter sheet name:",
                                                initialvalue='sheet'+str(noshts+1))
        checksheet_name(sheetname)
        page = Frame(self.notebook)
        self.notebook.add(page, text=sheetname)
        #Create the table and model if data present
        if sheetdata != None:
            model = TableModel(sheetdata)
            self.currenttable = MyTable(page, model)
        else:
            self.currenttable = MyTable(page)

        #Load preferences into table
        self.currenttable.loadPrefs(self.preferences)
        #This handles all the canvas and header in the frame passed to constructor
        self.currenttable.createTableFrame()
        #add the table to the sheet dict
        self.sheets[sheetname] = self.currenttable
        self.saved = 0
        return sheetname

    def delete_Sheet(self):
        """Delete a sheet"""

        s = self.notebook.index(self.notebook.select())
        name = self.notebook.tab(s, 'text')
        #self.notebook.delete(s)
        self.notebook.forget(s)
        del self.sheets[s]
        return

    def copy_Sheet(self, newname=None):
        """Copy a sheet"""

        newdata = self.currenttable.getModel().getData().copy()
        if newname==None:
            self.add_Sheet(None, newdata)
        else:
            self.add_Sheet(newname, newdata)
        return

    def rename_Sheet(self):
        """Rename a sheet"""

        #s = self.notebook.getcurselection()
        s = self.notebook.index(self.notebook.select())
        newname = simpledialog.askstring("New sheet name?", "Enter new sheet name:",
                                                initialvalue=s)
        if newname == None:
            return
        self.copy_Sheet(newname)
        self.delete_Sheet()
        return

    def setcurrenttable(self, event):
        """Set the currenttable so that menu items work with visible sheet"""

        try:
            #s = self.notebook.getcurselection()
            s = self.notebook.index(self.notebook.select())
            self.currenttable = self.sheets[s]
        except:
            pass
        return

    def add_Row(self):
        """Add a new row"""
        self.currenttable.addRow()
        self.saved = 0
        return

    def delete_Row(self):
        """Delete currently selected row"""

        self.currenttable.deleteRow()
        self.saved = 0
        return

    def add_Column(self):
        """Add a new column"""

        self.currenttable.addColumn()
        self.saved = 0
        return

    def delete_Column(self):
        """Delete currently selected column in table"""

        self.currenttable.deleteColumn()
        self.saved = 0
        return

    def autoAdd_Rows(self):
        """Auto add x rows"""

        self.currenttable.autoAddRows()
        self.saved = 0
        return

    def autoAdd_Columns(self):
        """Auto add x rows"""

        self.currenttable.autoAddColumns()
        self.saved = 0
        return

    def findValue(self):
        self.currenttable.findValue()
        return

    def do_find_text(self, event=None):
        """Find the text in the table"""

        if not hasattr(self,'currenttable'):
            return
        import string
        if string.strip(self.findtext.get())=='':
            return
        searchstring=self.findtext.get()
        if self.currenttable!=None:
            self.currenttable.findValue(searchstring)
        return

    def do_find_again(self, event=None):
        """Find again"""

        if not hasattr(self,'currenttable'):
            return
        searchstring=self.findtext.get()
        if self.currenttable!=None:
            self.currenttable.findValue(searchstring, findagain=1)
        return

    def plot(self, event=None):
        self.currenttable.plotSelected()
        return

    def plotSetup(self, event=None):
        self.currenttable.plotSetup()
        return

    def about_Tables(self):

        self.ab_win=Toplevel()
        self.ab_win.geometry('+100+350')
        self.ab_win.title('About TablesApp')

        from . import Table_images
        logo = Table_images.tableapp_logo()
        label = Label(self.ab_win,image=logo)
        label.image = logo
        label.grid(row=0,column=0,sticky='news',padx=4,pady=4)

        text=['Tables Sample App ','Shows the use of Tablecanvas class for tkinter',
                'Copyright (C) Damien Farrell 2008-', 'This program is free software; you can redistribute it and/or',
                'modify it under the terms of the GNU General Public License',
                'as published by the Free Software Foundation; either version 2',
                'of the License, or (at your option) any later version.']
        row=1
        for line in text:
            tmp=Label(self.ab_win,text=line)
            tmp.grid(row=row,column=0,sticky='news',padx=4)
            row=row+1
        return

    def online_documentation(self,event=None):
        """Open the online documentation"""

        import webbrowser
        link='http://sourceforge.net/projects/tkintertable/'
        webbrowser.open(link,autoraise=1)
        return

    def quit(self):
        self.tablesapp_win.destroy()

        return

Ancestors

  • tkinter.ttk.Frame
  • tkinter.ttk.Widget
  • tkinter.Widget
  • tkinter.BaseWidget
  • tkinter.Misc
  • tkinter.Pack
  • tkinter.Place
  • tkinter.Grid

Methods

def about_Tables(self)
Source code
def about_Tables(self):

    self.ab_win=Toplevel()
    self.ab_win.geometry('+100+350')
    self.ab_win.title('About TablesApp')

    from . import Table_images
    logo = Table_images.tableapp_logo()
    label = Label(self.ab_win,image=logo)
    label.image = logo
    label.grid(row=0,column=0,sticky='news',padx=4,pady=4)

    text=['Tables Sample App ','Shows the use of Tablecanvas class for tkinter',
            'Copyright (C) Damien Farrell 2008-', 'This program is free software; you can redistribute it and/or',
            'modify it under the terms of the GNU General Public License',
            'as published by the Free Software Foundation; either version 2',
            'of the License, or (at your option) any later version.']
    row=1
    for line in text:
        tmp=Label(self.ab_win,text=line)
        tmp.grid(row=row,column=0,sticky='news',padx=4)
        row=row+1
    return
def add_Column(self)

Add a new column

Source code
def add_Column(self):
    """Add a new column"""

    self.currenttable.addColumn()
    self.saved = 0
    return
def add_Row(self)

Add a new row

Source code
def add_Row(self):
    """Add a new row"""
    self.currenttable.addRow()
    self.saved = 0
    return
def add_Sheet(self, sheetname=None, sheetdata=None)

Add a new sheet - handles all the table creation stuff

Source code
def add_Sheet(self, sheetname=None, sheetdata=None):
    """Add a new sheet - handles all the table creation stuff"""

    def checksheet_name(name):
        if name == '':
            messagebox.showwarning("Whoops", "Name should not be blank.")
            return 0
        if name in self.sheets:
            messagebox.showwarning("Name exists", "Sheet name already exists!")
            return 0
    names = [self.notebook.tab(i, "text") for i in self.notebook.tabs()]
    noshts = len(names)
    if sheetname == None:
        sheetname = simpledialog.askstring("New sheet name?", "Enter sheet name:",
                                            initialvalue='sheet'+str(noshts+1))
    checksheet_name(sheetname)
    page = Frame(self.notebook)
    self.notebook.add(page, text=sheetname)
    #Create the table and model if data present
    if sheetdata != None:
        model = TableModel(sheetdata)
        self.currenttable = MyTable(page, model)
    else:
        self.currenttable = MyTable(page)

    #Load preferences into table
    self.currenttable.loadPrefs(self.preferences)
    #This handles all the canvas and header in the frame passed to constructor
    self.currenttable.createTableFrame()
    #add the table to the sheet dict
    self.sheets[sheetname] = self.currenttable
    self.saved = 0
    return sheetname
def autoAdd_Columns(self)

Auto add x rows

Source code
def autoAdd_Columns(self):
    """Auto add x rows"""

    self.currenttable.autoAddColumns()
    self.saved = 0
    return
def autoAdd_Rows(self)

Auto add x rows

Source code
def autoAdd_Rows(self):
    """Auto add x rows"""

    self.currenttable.autoAddRows()
    self.saved = 0
    return
def close_project(self)
Source code
def close_project(self):
    if hasattr(self,'currenttable'):
        #self.notebook.destroy()
        self.currenttable.destroy()
    return
def copy_Sheet(self, newname=None)

Copy a sheet

Source code
def copy_Sheet(self, newname=None):
    """Copy a sheet"""

    newdata = self.currenttable.getModel().getData().copy()
    if newname==None:
        self.add_Sheet(None, newdata)
    else:
        self.add_Sheet(newname, newdata)
    return
def createMenuBar(self)

Create the menu bar for the application.

Source code
def createMenuBar(self):
    """Create the menu bar for the application. """

    self.menu=Menu(self.tablesapp_win)
    self.proj_menu={'01New':{'cmd':self.new_project},
                    '02Open':{'cmd':self.open_project},
                    '03Close':{'cmd':self.close_project},
                    '04Save':{'cmd':self.save_project},
                    '05Save As':{'cmd':self.save_as_project},
                    '06Preferences..':{'cmd':self.showPrefsDialog},
                    '08Quit':{'cmd':self.quit}}
    if self.parent:
        self.proj_menu['08Return to Database']={'cmd':self.return_data}
    self.proj_menu=self.create_pulldown(self.menu,self.proj_menu)
    self.menu.add_cascade(label='Project',menu=self.proj_menu['var'])

    self.records_menu={'01Add Row':{'cmd':self.add_Row},
                     '02Delete Row':{'cmd':self.delete_Row},
                     '03Add Column':{'cmd':self.add_Column},
                     '04Delete Column':{'cmd':self.delete_Column},
                     '05Auto Add Rows':{'cmd':self.autoAdd_Rows},
                     '06Auto Add Columns':{'cmd':self.autoAdd_Columns},
                     '07Find':{'cmd':self.createSearchBar},
                     }
    self.records_menu=self.create_pulldown(self.menu,self.records_menu)
    self.menu.add_cascade(label='Records',menu=self.records_menu['var'])

    self.sheet_menu={'01Add Sheet':{'cmd':self.add_Sheet},
                     '02Remove Sheet':{'cmd':self.delete_Sheet},
                     '03Copy Sheet':{'cmd':self.copy_Sheet},
                     '04Rename Sheet':{'cmd':self.rename_Sheet},
                     }
    self.sheet_menu=self.create_pulldown(self.menu,self.sheet_menu)
    self.menu.add_cascade(label='Sheet',menu=self.sheet_menu['var'])

    self.IO_menu={'01Import from csv file':{'cmd':self.import_csv},
                  '02Export to csv file':{'cmd':self.export_csv},
                  }

    self.IO_menu=self.create_pulldown(self.menu,self.IO_menu)
    self.menu.add_cascade(label='Import/Export',menu=self.IO_menu['var'])

    # Help menu
    self.help_menu={'01Online Help':{'cmd':self.online_documentation},
                    '02About':{'cmd':self.about_Tables}}
    self.help_menu=self.create_pulldown(self.menu,self.help_menu)
    self.menu.add_cascade(label='Help',menu=self.help_menu['var'])

    self.tablesapp_win.config(menu=self.menu)

    return
def createSearchBar(self, event=None)

Add a find entry box

Source code
def createSearchBar(self, event=None):
    """Add a find entry box"""

    frame = Frame(self.tablesapp_win)
    row=0
    def close():
        frame.destroy()
    self.findtext=StringVar()
    self.findbox=Entry(frame,textvariable=self.findtext,width=30,bg='white')
    self.findbox.grid(row=row,column=1,sticky='news',columnspan=2,padx=2,pady=2)
    self.findbox.bind('<Return>',self.do_find_text)
    Label(frame,text='Find:').grid(row=row,column=0,sticky='ew')
    self.findagainbutton=Button(frame,text='Find Again', command=self.do_find_again)
    self.findagainbutton.grid(row=row,column=3,sticky='news',padx=2,pady=2)
    self.cbutton=Button(frame,text='Close', command=close)
    self.cbutton.grid(row=row,column=4,sticky='news',padx=2,pady=2)
    frame.pack(fill=BOTH, expand=NO)
    return
def create_pulldown(self, menu, dict)

Create a pulldown in var from the info in dict

Source code
def create_pulldown(self,menu,dict):
    """ Create a pulldown in var from the info in dict  """

    var = Menu(menu,tearoff=0)
    items = dict.keys()
    #items.sort()
    for item in items:
        if item[-3:]=='sep':
            var.add_separator()
        else:
            # Do we have a command?
            command=None
            if 'cmd' in  dict[item]:
                command=dict[item]['cmd']

            # Put the command in there
            if 'sc' in dict[item]:
                var.add_command(label='%-25s %9s' %(item[2:],dict[item]['sc']),command=command)
            else:
                var.add_command(label='%-25s' %(item[2:]),command=command)
    dict['var']=var
    return dict
def delete_Column(self)

Delete currently selected column in table

Source code
def delete_Column(self):
    """Delete currently selected column in table"""

    self.currenttable.deleteColumn()
    self.saved = 0
    return
def delete_Row(self)

Delete currently selected row

Source code
def delete_Row(self):
    """Delete currently selected row"""

    self.currenttable.deleteRow()
    self.saved = 0
    return
def delete_Sheet(self)

Delete a sheet

Source code
def delete_Sheet(self):
    """Delete a sheet"""

    s = self.notebook.index(self.notebook.select())
    name = self.notebook.tab(s, 'text')
    #self.notebook.delete(s)
    self.notebook.forget(s)
    del self.sheets[s]
    return
def do_find_again(self, event=None)

Find again

Source code
def do_find_again(self, event=None):
    """Find again"""

    if not hasattr(self,'currenttable'):
        return
    searchstring=self.findtext.get()
    if self.currenttable!=None:
        self.currenttable.findValue(searchstring, findagain=1)
    return
def do_find_text(self, event=None)

Find the text in the table

Source code
def do_find_text(self, event=None):
    """Find the text in the table"""

    if not hasattr(self,'currenttable'):
        return
    import string
    if string.strip(self.findtext.get())=='':
        return
    searchstring=self.findtext.get()
    if self.currenttable!=None:
        self.currenttable.findValue(searchstring)
    return
def do_save_project(self, filename)

Get model dicts and write all to pickle file

Source code
def do_save_project(self, filename):
    """Get model dicts and write all to pickle file"""

    data={}
    for s in self.sheets.keys():
        currtable = self.sheets[s]
        model = currtable.getModel()
        data[s] = model.getData()

    fd=open(filename,'wb')
    pickle.dump(data,fd)
    fd.close()
    return
def export_csv(self)
Source code
def export_csv(self):
    from .Tables_IO import TableExporter
    exporter = TableExporter()
    exporter.ExportTableData(self.currenttable)
    return
def findValue(self)
Source code
def findValue(self):
    self.currenttable.findValue()
    return
def import_csv(self)
Source code
def import_csv(self):

    importer = TableImporter()
    #just use the dialog to load and import the file
    importdialog = importer.import_Dialog(self.tablesapp_win)
    self.tablesapp_win.wait_window(importdialog)
    model = TableModel()
    model.importDict(importer.data)
    sheetdata = {}
    sheetdata['sheet1'] = model.getData()
    self.new_project(sheetdata)
    return
def loadprefs(self)

Setup default prefs file if any of the keys are not present

Source code
def loadprefs(self):
    """Setup default prefs file if any of the keys are not present"""

    defaultprefs = {'textsize':14,
                     'windowwidth': 800 ,'windowheight':600}
    for prop in defaultprefs.keys():
        try:
            self.preferences.get(prop)
        except:
            self.preferences.set(prop, defaultprefs[prop])

    return
def new_project(self, data=None)

Create a new table, with model and add the frame

Source code
def new_project(self, data=None):
    """Create a new table, with model and add the frame"""

    if hasattr(self,'currenttable'):
        self.notebook.destroy()
        self.currenttable.destroy()

    #Create the sheets dict
    self.sheets = {}
    self.notebook = Notebook(self.tablesapp_win)
    self.notebook.pack(fill='both', expand=1, padx=4, pady=4)
    if data !=None:
        for s in data.keys():
            sdata = data[s]
            try:
                self.add_Sheet(s ,sdata)
            except:
                print ('skipping')
    else:
        #do the table adding stuff for the initial sheet
        self.add_Sheet('sheet1')
    #self.notebook.setnaturalsize()
    return
def online_documentation(self, event=None)

Open the online documentation

Source code
def online_documentation(self,event=None):
    """Open the online documentation"""

    import webbrowser
    link='http://sourceforge.net/projects/tkintertable/'
    webbrowser.open(link,autoraise=1)
    return
def open_project(self, filename=None)
Source code
def open_project(self, filename=None):

    if filename == None:
        filename=filedialog.askopenfilename(defaultextension='.tblprj"',
                                                  initialdir=os.getcwd(),
                                                  filetypes=[("TableApp project","*.tblprj"),
                                                             ("All files","*.*")],
                                                  parent=self.tablesapp_win)
    if os.path.isfile(filename):
        fd = open(filename, 'rb')
        data = pickle.load(fd)
        fd.close()
    self.new_project(data)
    self.filename=filename
    return
def plot(self, event=None)
Source code
def plot(self, event=None):
    self.currenttable.plotSelected()
    return
def plotSetup(self, event=None)
Source code
def plotSetup(self, event=None):
    self.currenttable.plotSetup()
    return
def quit(self)

Quit the Tcl interpreter. All widgets will be destroyed.

Source code
def quit(self):
    self.tablesapp_win.destroy()

    return
def rename_Sheet(self)

Rename a sheet

Source code
def rename_Sheet(self):
    """Rename a sheet"""

    #s = self.notebook.getcurselection()
    s = self.notebook.index(self.notebook.select())
    newname = simpledialog.askstring("New sheet name?", "Enter new sheet name:",
                                            initialvalue=s)
    if newname == None:
        return
    self.copy_Sheet(newname)
    self.delete_Sheet()
    return
def save_as_project(self)

Save as a new filename

Source code
def save_as_project(self):
    """Save as a new filename"""

    filename=filedialog.asksaveasfilename(parent=self.tablesapp_win,
                                            defaultextension='.tblprj',
                                            initialdir=self.defaultsavedir,
                                            filetypes=[("TableApp project","*.tblprj"),
                                                       ("All files","*.*")])
    if not filename:
        print ('Returning')
        return
    self.filename=filename
    self.do_save_project(self.filename)
    return
def save_project(self)
Source code
def save_project(self):

    if not hasattr(self, 'filename'):
        self.save_as_project()
    elif self.filename == None:
        self.save_as_project()
    else:
        self.do_save_project(self.filename)

    return
def setcurrenttable(self, event)

Set the currenttable so that menu items work with visible sheet

Source code
def setcurrenttable(self, event):
    """Set the currenttable so that menu items work with visible sheet"""

    try:
        #s = self.notebook.getcurselection()
        s = self.notebook.index(self.notebook.select())
        self.currenttable = self.sheets[s]
    except:
        pass
    return
def showPrefsDialog(self)
Source code
def showPrefsDialog(self):
    self.prefswindow = self.currenttable.showtablePrefs()
    return
class ToolBar (parent=None, parentapp=None)

Uses the parent instance to provide the functions

Construct a Ttk Frame with parent master.

STANDARD OPTIONS

class, cursor, style, takefocus

WIDGET-SPECIFIC OPTIONS

borderwidth, relief, padding, width, height
Source code
class ToolBar(Frame):
    """Uses the parent instance to provide the functions"""

    def __init__(self, parent=None, parentapp=None):
        Frame.__init__(self, parent, width=600, height=40)
        from . import Table_images
        self.parentframe = parent
        self.parentapp = parentapp
        #add buttons
        img = Table_images.new_proj()
        self.add_button('New Project', self.parentapp.new_project, img)
        img = Table_images.open_proj()
        self.add_button('Open Project', self.parentapp.open_project, img)
        img = Table_images.save_proj()
        self.add_button('Save Project', self.parentapp.save_project, img)
        img = Table_images.add_row()
        self.add_button('Add record', self.parentapp.add_Row, img)
        img = Table_images.add_col()
        self.add_button('Add col', self.parentapp.add_Column, img)
        img = Table_images.del_row()
        self.add_button('Delete record', self.parentapp.delete_Row, img)
        img = Table_images.del_col()
        self.add_button('Delete col', self.parentapp.delete_Column, img)
        img = Table_images.plot()
        self.add_button('Plot', self.parentapp.plot, img)
        img = Table_images.plotprefs()
        self.add_button('Plot Prefs', self.parentapp.plotSetup, img)

        return

    def add_button(self, name, callback, img=None):
        if img==None:
            b = Button(self, text=name, command=callback)
        else:
            b = Button(self, text=name, command=callback,
                             image=img)
        b.image = img
        b.pack(side=LEFT, padx=2, pady=2, ipadx=1, ipady=1)

        return

Ancestors

  • tkinter.ttk.Frame
  • tkinter.ttk.Widget
  • tkinter.Widget
  • tkinter.BaseWidget
  • tkinter.Misc
  • tkinter.Pack
  • tkinter.Place
  • tkinter.Grid

Methods

def add_button(self, name, callback, img=None)
Source code
def add_button(self, name, callback, img=None):
    if img==None:
        b = Button(self, text=name, command=callback)
    else:
        b = Button(self, text=name, command=callback,
                         image=img)
    b.image = img
    b.pack(side=LEFT, padx=2, pady=2, ipadx=1, ipady=1)

    return