Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter Text Widget Save to File

So, I'm quite new to using python and I wanted to learn more about it so I decided to download a sticky note program from the internet (Rhinote) and study / modify it to use a menu bar instead of control commands to execute the methods. I also modified it to work with Python 3.x instead of Python 2.

The problem I'm coming up with after modifying it with the menu bar is that it creates the file but doesn't actually write to it. I've been trying to fix this for a while now so any help is appreciated.

Here is the code I have currently:

from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system

# the root window:
def Sticky():
    r = Tk()
    r.option_add('*font', '{Helvetica} 11')
    t = Text(r, bg = '#f9f3a9', wrap = 'word', undo = True)
    t.focus_set()
    t.pack(fill = 'both', expand = 1)
    r.geometry('220x235')
    r.title('Note')

    text = TextWidget()

    m = tkinter.Menu(r)
    m.add_command(label="+", command=text.new_window)
    m.add_command(label="Save", command=text.save_file)
    m.add_command(label="Save As", command=text.save_file_as)
    m.add_command(label="Open", command=text.open_file)
    r.config(menu=m)

    r.mainloop()

# the text widget, and all of its functions:
class TextWidget(Text):
    def __init__(self):
        Text.__init__(self)
        self.filename = ''
        self._filetypes = [
        ('Text', '*.txt'),
            ('All files', '*'),
            ]

    def save_file(self, whatever = None):
        if (self.filename == ''):
            self.save_file_as()
        else:
            f = open(self.filename, 'w')
            f.write(self.get('1.0', 'end'))
            f.close()
            tkinter.messagebox.showinfo('FYI', 'File Saved.')

    def save_file_as(self, whatever = None):
        self.filename = tkinter.filedialog.asksaveasfilename(defaultextension='.txt',
                                                             filetypes = self._filetypes)
        f = open(self.filename, 'w')
        f.write(self.get('1.0', 'end'))
        f.close()
        tkinter.messagebox.showinfo('FYI', 'File Saved')

    def open_file(self, whatever = None, filename = None):
        if not filename:
            self.filename = tkinter.filedialog.askopenfilename(filetypes = self._filetypes)
        else:
            self.filename = filename
        if not (self.filename == ''):
            f = open(self.filename, 'r')
            f2 = f.read()
            self.delete('1.0', 'end')
            self.insert('1.0', f2)
            f.close()
            self.title('Sticky %s)' % self.filename)

    def new_window(self):
        Sticky()

    def help(whatever = None):
        tkinter.messagebox.showinfo('Help', message = '''
Help
''')
# make it so:
if __name__ == '__main__':
    Sticky()

And here is the Rhinote program I'm trying to modify:

from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system

# the root window:
def Rhinote():
    r = Tk()
    r.option_add('*font', '{Helvetica} 11')
    t = TextWidget(r, bg = '#f9f3a9', wrap = 'word', undo = True)
    t.focus_set()
    t.pack(fill = 'both', expand = 1)
    r.geometry('220x235')
    r.title('Rhinote')
    r.mainloop()

# the text widget, and all of its functions:
class TextWidget(Text):

    def save_file(self, whatever = None):
        if (self.filename == ''):
            self.save_file_as()
            self.master.title('Rhinote %s' % self.filename)
        else:
            f = open(self.filename, 'w')
            f.write(self.get('1.0', 'end'))
            f.close()
            self.master.title('Rhinote %s' % self.filename)
            tkinter.messageb ox.showinfo('FYI', 'File Saved.')

    def save_file_as(self, whatever = None):
        self.filename = tkinter.filedialog.asksaveasfilename(filetypes = self._filetypes)
        f = open(self.filename, 'w')
        f.write(self.get('1.0', 'end'))
        f.close()
        tkinter.messagebox.showinfo('FYI', 'File Saved')

    def open_file(self, whatever = None, filename = None):
        if not filename:
            self.filename = tkinter.filedialog.askopenfilename(filetypes = self._filetypes)
            self.master.title('Rhinote %s' % self.filename)
        else:
            self.filename = filename
            self.master.title('Rhinote %s' % self.filename)
        if not (self.filename == ''):
            f = open(self.filename, 'r')
            f2 = f.read()
            self.delete('1.0', 'end')
            self.insert('1.0', f2)
            f.close()
            self.master.title('Rhinote %s)' % self.filename)

    def new_window(self, event):
        Rhinote()

    def printfile(self, whatever = None):
        f = open(self.printfilename, 'w')
        f.write(self.get('1.0', 'end'))
        f.close
        # 'enscript' formats the text; lpr sends it to the default printer;
        # enscript's -B option suppresses page headers.
        system('enscript -B --word-wrap $HOME/.Rhinoteprintfile > lpr &')

    def help(self, whatever = None):
        tkinter.messagebox.showinfo('Rhinote Help', message = '''
Editing Commands
    Ctrl-x : Cut selected text
    Ctrl-c : Copy selected text
    Ctrl-v : Paste cut/copied text
    Ctrl-Z : Undo
    Ctrl-Shift-z : Redo

File Commands
    Ctrl-o : Open file
    Ctrl-s : Save current note
    Ctrl-a : Save current note as <filename>
    Ctrl-p : Print current note
    Ctrl-n : Open new Rhinote

General
    Ctrl-h : Display this help window

Rhinote version 0.7.4
Free Software distributed under the GNU General Public License
http://rhinote.tuxfamily.org
''')

    def __init__(self, master, **kw):
        Text.__init__(self, master, **kw)
        self.bind('<Control-n>', self.new_window)
        self.bind('<Control-N>', self.new_window)
        self.bind('<Control-o>', self.open_file)
        self.bind('<Control-O>', self.open_file)
        self.bind('<Control-s>', self.save_file)
        self.bind('<Control-S>', self.save_file)
        self.bind('<Control-a>', self.save_file_as)
        self.bind('<Control-A>', self.save_file_as)
        self.bind('<Control-p>', self.printfile)
        self.bind('<Control-P>', self.printfile)
        self.bind('<Control-h>', self.help)
        self.bind('<Control-H>', self.help)
        self.master = master
        self.filename = ''
        self.printfilename = os.environ['HOME']+'/.Rhinoteprintfile'
        self._filetypes = [
        ('Text/ASCII', '*.txt'),
        ('Rhinote files', '*.rhi'),
            ('All files', '*'),
            ]

# make it so:
if __name__ == '__main__':
    Rhinote()
like image 332
Jim Avatar asked Feb 10 '26 20:02

Jim


1 Answers

It was nice that you changed to using menu, but there is one thing you forgot, the Text that's showing onscreen isn't the one named text, it was this while you're retrieving the data from text which is empty because it's covered by t and it wasn't even packed:

t = Text(r, bg = '#f9f3a9', wrap = 'word', undo = True)
t.focus_set()
t.pack(fill = 'both', expand = 1)

Since you used focus_set on it which will be above all other widgets. Just to say simple, you can change your program to something like this, which you wouldn't even need the text.

from tkinter import *
import tkinter.filedialog, tkinter.messagebox
import os
from os import system

# the root window:
def Sticky():
    r = Tk()
    r.option_add('*font', '{Helvetica} 11')
    t = Text(r, bg = '#f9f3a9', wrap = 'word', undo = True)
    t.focus_set()
    t.pack(fill = 'both', expand = 1)
    r.geometry('220x235')
    r.title('Note')

    TextWidget(t) # pass along t, your Text

    m = tkinter.Menu(r)
    m.add_command(label="+", command=text.new_window)
    m.add_command(label="Save", command=text.save_file)
    m.add_command(label="Save As", command=text.save_file_as)
    m.add_command(label="Open", command=text.open_file)
    r.config(menu=m)

    r.mainloop()

# the text widget, and all of its functions:
class TextWidget:
    def __init__(self, text):
        self.text = text # pass the text widget
        self.filename = ''
        self._filetypes = [
        ('Text', '*.txt'),
            ('All files', '*'),
            ]

    def save_file(self, whatever = None):
        if (self.filename == ''):
            self.save_file_as()
        else:
            f = open(self.filename, 'w')
            f.write(self.text.get('1.0', 'end')) # change every 'self' that refers to the Text, to self.text
            f.close()
            tkinter.messagebox.showinfo('FYI', 'File Saved.')

    def save_file_as(self, whatever = None):
        self.filename = tkinter.filedialog.asksaveasfilename(defaultextension='.txt',
                                                             filetypes = self._filetypes)
        f = open(self.filename, 'w')
        f.write(self.text.get('1.0', 'end'))
        f.close()
        tkinter.messagebox.showinfo('FYI', 'File Saved')

    def open_file(self, whatever = None, filename = None):
        if not filename:
            self.filename = tkinter.filedialog.askopenfilename(filetypes = self._filetypes)
        else:
            self.filename = filename
        if not (self.filename == ''):
            f = open(self.filename, 'r')
            f2 = f.read()
            self.text.delete('1.0', 'end')
            self.text.insert('1.0', f2)
            f.close()
            self.text.title('Sticky %s)' % self.filename)

    def new_window(self):
        Sticky()

    def help(whatever = None):
        tkinter.messagebox.showinfo('Help', message = '''
Help
''')
# make it so:
if __name__ == '__main__':
    Sticky()
like image 168
Taku Avatar answered Feb 12 '26 14:02

Taku



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!