问题描述
如何复制 tkinter 文本小部件,以便您可以将其添加到每个 Notebook 选项卡中?我正在使用 tkinter 编写编辑器,并且还添加了撤消功能。问题是,当我添加一个新选项卡时,撤消功能仅适用于该选项卡。当我删除该选项卡时,它也不适用于其他选项卡。
from tkinter.ttk import Notebook
import tkinter.messageBox
class TextClass(Frame):
def __init__(self,*args,**kwargs):
Frame.__init__(self,**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',command=redo,width=6)
redo_button.place(x=230,y=5)
hover(redo_button,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,**kwargs):
return self.text.get(*args,**kwargs)
def insert(self,**kwargs):
return self.text.insert(*args,**kwargs)
def delete(self,**kwargs):
return self.text.delete(*args,**kwargs)
def index(self,**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,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,fg='white')
hover(add_tab_btn,exit_fg='white')
add_tab_btn.place(x=15,y=5)
delete_tab_btn = Button(toolbar,text='Delete tab',command=close_tab,fg='white')
hover(delete_tab_btn,exit_fg='white')
delete_tab_btn.place(x=100,y=5)
root.after(200,text.redraw())
scr_menu()
root.mainloop()
解决方法
我怀疑您每次创建新标签时都会在旧按钮上制作新的撤消/重做按钮。这意味着该按钮仅适用于最后一个选项卡。要解决该问题,您必须移动笔记本内的撤消/重做按钮。正如概念证明改变这一行:
undo_button = Button(toolbar,text='Undo',relief='ridge',command=undo,bg='black',fg='white',width=6)
到
undo_button = Button(self,width=6)