3

This is a simple notepad program that i am currently writing. Most things are working but cannot get the save to work. Where i have defined save i don't know how to create the save function(not save as).

NOT THE FULL CODE

from tkinter import *
from tkinter.messagebox import *
from tkinter.filedialog import *
from tkinter.font import *
import sys, time, sched, math

class Format:
    def __init__(self, notepad):
        print("Font")

class ZPad:
    def __init__(self):
        self.root = Tk()
        self.root.title("ZPad")
        self.root.wm_iconbitmap('Notepad.ico')

        self.scrollbar = Scrollbar(self.root)
        self.scrollbar.pack(side=RIGHT, fill=Y)

        self.textbox = Text(self.root, yscrollcommand=self.scrollbar.set, undo=TRUE)
        self.textbox.pack(side=LEFT, fill=BOTH, expand=YES)

        #Menu Bar
        self.menubar = Menu(self.root)
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="New", command=self.New, accelerator="Ctrl+N")
        self.filemenu.add_command(label="Open...", command=self.open, accelerator="Ctrl+O")
        self.filemenu.add_command(label="Save", command=self.Save, accelerator="Ctrl+S")
        self.filemenu.add_command(label="Save as...", command=self.Save_as, accelerator="Ctrl+Shift+S")
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.quit, accelerator="Ctrl+Q")
        self.menubar.add_cascade(label="File", menu=self.filemenu)

        self.editmenu = Menu(self.menubar, tearoff=0)
        self.editmenu.add_command(label="Undo", command=self.Undo, accelerator="Ctrl+Z")
        self.editmenu.add_command(label="Redo", command=self.Redo, accelerator="Ctrl+Y")
        self.editmenu.add_separator()
        self.editmenu.add_command(label="Cut", command=self.Cut, accelerator="Ctrl+X")
        self.editmenu.add_command(label="Copy", command=self.Copy, accelerator="Ctrl+C")
        self.editmenu.add_command(label="Paste", command=self.Paste, accelerator="Ctrl+P")
        self.editmenu.add_command(label="Clear All", command=self.Clear_All, accelerator="Ctrl+Shift+A")
        self.editmenu.add_separator()
        self.editmenu.add_command(label="Format", command=self.options, accelerator="Ctrl+T")
        self.menubar.add_cascade(label="Edit", menu=self.editmenu)

        self.helpmenu = Menu(self.menubar, tearoff=0)
        self.helpmenu.add_command(label="About...", command=self.About)
        self.menubar.add_cascade(label="Help", menu=self.helpmenu)


        self.root.config(menu=self.menubar)

        self.root.mainloop()

def Save(self):
    print("Save")

def Save_as(self):
    global file
    file = tkinter.filedialog.asksaveasfile(mode='w', defaultextension=".z", filetypes = ( ("ztext file", "*.z"),("zytext", "*.zy") ) )
    if file is None:
        return
    else:
        print(file)
    textoutput = self.textbox.get(0.0, END)
    file.write(textoutput.rstrip())
    file.write("\n")

notepad = ZPad()

I am using python 3.4 in windows 8.1. Thanks.

zacdevil10
  • 47
  • 3
  • 9
  • Can you check the indentation on your code block? Specifically, the save and save_as functions are outside the zpad class. Is that correct? Also, are you looking for a method to write the save function, or is there some error calling it, or what? – atlasologist Apr 03 '14 at 20:26
  • They are within the ZPAD class. i am looking for a method to write the save function. – zacdevil10 Apr 03 '14 at 21:45

1 Answers1

3

Here's a quick example of a save and save as function, with comments:

def save(self):
    contents = self.textbox.get(1.0,"end-1c") #store the contents of the text widget in a str
    try:                                       #this try/except block checks to
        with open(self.f, 'w') as outputFile:  #see if the str containing the output
            outputFile.write(contents)         #file (self.f) exists, and we can write to it,
    except AttributeError:                     #and if it doesn't,
        self.save_as()                         #call save_as

def save_as(self):
    contents = self.textbox.get(1.0,"end-1c")
    self.f = tkFileDialog.asksaveasfilename(   #this will make the file path a string
        defaultextension=".z",                 #so it's easier to check if it exists
        filetypes = (("ztext file", "*.z"),    #in the save function
                     ("zytext", "*.zy")))
    with open(self.f, 'w') as outputFile:
        outputFile.write(contents)

There are other ways to do this, but this will work in a pinch. Just think about what the save function needs: text to save and a file to save in, and go from there.

atlasologist
  • 3,824
  • 1
  • 21
  • 35
  • 1
    You should use `"end-1c"` rather than `END`. Tkinter always adds an extra newline. If you don't take care of this little detail, every time you open the file and immediately save it, it will grow by one line. Also, the first character is `1.0`, not `0.0` – Bryan Oakley Apr 03 '14 at 23:14
  • Thanks but it returns the error: Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\Zac\Documents\School\notepad with classes.py", line 133, in Save with open(self.f, 'w') as outputFile: AttributeError: 'ZPad' object has no attribute 'f' – zacdevil10 Apr 04 '14 at 20:26
  • During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:\Python34\lib\tkinter\__init__.py", line 1482, in __call__ return self.func(*args) File "C:\Users\Zac\Documents\School\notepad with classes.py", line 136, in Save self.Save_as() File "C:\Users\Zac\Documents\School\notepad with classes.py", line 141, in Save_as with open(self.f, 'w') as outputFile: TypeError: invalid file: <_io.TextIOWrapper name='C:/Users/Zac/Desktop/txy.z' mode='w' encoding='cp1252'> – zacdevil10 Apr 04 '14 at 20:26