Tkinter文本小部件保存到文件

时间:2017-04-12 00:27:39

标签: python python-3.x tkinter

所以,我是使用python的新手,我想了解更多信息,所以我决定从互联网上下载一个便利贴的程序(Rhinote)并研究/修改它以使用菜单栏而不是控制命令来执行方法。我还修改了它以使用Python 3.x而不是Python 2.

我用菜单栏修改它后出现的问题是它创建了文件但实际上没有写入文件。我已经尝试解决这个问题一段时间了,所以任何帮助都会受到赞赏。

以下是我目前的代码:

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()

以下是我试图修改的Rhinote程序:

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()

2 个答案:

答案 0 :(得分:1)

很高兴您改为使用菜单,但是有一件事你忘记了,屏幕上显示的文字不是名为text的文字,而是你#&# 39;重新检索来自text的数据,该数据为空,因为它被t覆盖,并且它甚至没有打包:

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

由于您在其上使用focus_set,因此它将高于所有其他小部件。简单来说,您可以将程序更改为这样的程序,您甚至不需要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()

答案 1 :(得分:1)

由于TextWidgetText子类,所以只要原始程序使用后者,就应该使用它。为了实现这一点,需要正确初始化其超类。

幸运的是,没有太多需要改变才能正确使用它。 以下是需要更改的代码部分:

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')
    text = TextWidget(r, bg='#f9f3a9', wrap='word', undo=True) # create subclass here (and
                                                               # call it text instead of t)
    text.focus_set()
    text.pack(fill='both', expand=1)
    r.geometry('220x235')
    r.title('Note')

    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, *args, **kwargs):
        Text.__init__(self, *args, **kwargs)  # pass all args to superclass
        self.filename = ''
        self._filetypes = [
            ('Text', '*.txt'),
            ('All files', '*'),
        ]

    def save_file(self, whatever=None):
       REST OF YOUR CODE, UNCHANGED, GOES HERE...