0

如何复制 tkinter 文本小部件以便您可以将其添加到每个笔记本选项卡中?我正在使用 tkinter 编写编辑器,并且还添加了撤消功能。问题是,当我添加一个新选项卡时,撤消功能仅适用于该选项卡。当我删除该选项卡时,它也不适用于其他选项卡。

from tkinter.ttk import Notebook
import tkinter.messagebox


class TextClass(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)

        self.text = Text(self, bg='white', foreground="black", undo=True,
                         insertbackground='black', height=35, width=135,
                         selectbackground="blue")

        self.scrollbar = Scrollbar(self, orient=VERTICAL, command=self.text.yview)
        self.text.configure(yscrollcommand=self.scrollbar.set)

        self.numberLines = TextLineNumbers(self, width=40, bg='#2A2A2A')
        self.numberLines.attach(self.text)

        self.scrollbar.pack(side=RIGHT, fill=Y)
        self.numberLines.pack(side=LEFT, fill=Y, padx=(5, 0))
        self.text.pack(fill='both', expand=True)

        self.text.bind("<Key>", self.onPressDelay)
        self.text.bind("<Button-1>", self.numberLines.redraw)
        self.scrollbar.bind("<Button-1>", self.onScrollPress)
        self.text.bind("<MouseWheel>", self.onPressDelay)

        def undo():

            try:
                self.text.edit_undo()

            except TclError:
                tkinter.messagebox.showerror(
                    "Nothing to Undo",
                    "You have not typed anything to undo. Please type and try again!"
                )

        undo_button = Button(toolbar, text='Undo', relief='ridge', command=undo, bg='black', fg='white',
                             width=6)
        undo_button.place(x=170, y=5)
        hover(undo_button, on_entrance='white', on_exit='black', entrance_foreground='black', exit_fg='white')

        def redo():

            try:
                self.text.edit_redo()

            except TclError:
                tkinter.messagebox.showerror(
                    "Nothing to Redo",
                    "You have not done an undo to redo. Please type and try again!"
                )

        redo_button = Button(toolbar, text='Redo', relief='ridge', command=redo, bg='black', fg='white',
                             width=6)
        redo_button.place(x=230, y=5)
        hover(redo_button, on_entrance='white', on_exit='black', entrance_foreground='black', exit_fg='white')

    def onScrollPress(self, *args):
        self.scrollbar.bind("<B1-Motion>", self.numberLines.redraw)

    def onScrollRelease(self, *args):
        self.scrollbar.unbind("<B1-Motion>", self.numberLines.redraw)

    def onPressDelay(self, *args):
        self.after(2, self.numberLines.redraw)

    def get(self, *args, **kwargs):
        return self.text.get(*args, **kwargs)

    def insert(self, *args, **kwargs):
        return self.text.insert(*args, **kwargs)

    def delete(self, *args, **kwargs):
        return self.text.delete(*args, **kwargs)

    def index(self, *args, **kwargs):
        return self.text.index(*args, **kwargs)

    def redraw(self):
        self.numberLines.redraw()


class TextLineNumbers(Canvas):
    Canvas.text_widget = None

    def attach(self, text_widget):
        self.text_widget = text_widget

    def redraw(self, *args):
        self.delete("all")

        i = self.text_widget.index("@0,0")
        while True:
            d_line = self.text_widget.dlineinfo(i)
            if d_line is None:
                break
            y = d_line[1]
            line_numbers = str(i).split(".")[0]
            self.create_text(2, y, anchor="nw", text=line_numbers, fill="white")
            i = self.text_widget.index("%s+1line" % i)

def add_tab():
    global tab
    tab = Frame(notebook)
    notebook.add(tab, text=f'{"Untitled1.txt": ^20}')
    global text
    text = TextClass(tab, bg='white')
    text.pack()
    text.text.focus()


def close_tab():
    notebook.forget('current')

def hover(widget, entrance_foreground, exit_fg, on_entrance, on_exit):
    widget.bind("<Enter>", func=lambda e: widget.config(
        bg=on_entrance,
        fg=entrance_foreground
    ))

    widget.bind("<Leave>", func=lambda e: widget.config(
        bg=on_exit,
        fg=exit_fg
    ))


root = Tk()
root.config(bg='white')
root.geometry("1260x680")

toolbar = Frame(root, bg='white', height=45)
toolbar.pack(expand=False, fill='x')

notebook = Notebook(root)
tab = Frame(notebook)
notebook.add(tab, text=f'{"Untitled.txt": ^20}')
notebook.place(x=50, y=60)


text = TextClass(tab, bg='white')
text.pack()

add_tab_btn = Button(toolbar, text='Add new tab', command=add_tab, relief='ridge', bg='black', fg='white')
hover(add_tab_btn, on_entrance='white', on_exit='black', entrance_foreground='black', exit_fg='white')
add_tab_btn.place(x=15, y=5)

delete_tab_btn = Button(toolbar, text='Delete tab', command=close_tab, relief='ridge', bg='black', fg='white')
hover(delete_tab_btn, on_entrance='white', on_exit='black', entrance_foreground='black', exit_fg='white')
delete_tab_btn.place(x=100, y=5)

root.after(200, text.redraw())
scr_menu()
root.mainloop()
4

1 回答 1

0

正如我怀疑你每次创建新标签时都会在旧按钮上制作新的撤消/重做按钮。这意味着该按钮仅适用于最后一个选项卡。要解决该问题,您必须在笔记本内移动撤消/重做按钮。就像概念证明一样改变这条线:

undo_button = Button(toolbar, text='Undo', relief='ridge', command=undo, bg='black', fg='white',
                     width=6)

undo_button = Button(self, text='Undo', relief='ridge', command=undo, bg='black', fg='white',
                     width=6)
于 2021-02-16T11:30:44.580 回答