Anonymous
Auswahl funktioniert nicht, nachdem das Text -Widget -Fokus geändert wurde
Post
by Anonymous » 06 May 2025, 09:58
Ich habe eine Anwendung mit zwei Text -Widgets in zwei Frames. Klicken Sie in einem Text -Widget (formatierter Text mit einem Tag Bind) (formatierter Text mit einem Tag Bind) (
) sollte Text in einem anderen auswählen (
).
Wenn ich einmal auf den Link klicke, siehe Teil, mark_set und die Auswahl nicht anwenden. Ich habe versucht, "Break" aus dem Ereignishandler zurückzugeben und mit Focus_set , focus_force , update_idletasks und aktualisiert in der GOTO -Methode ohne Erfolg.
Code: Select all
import math
import tkinter as tk
from tkinter.font import Font
from typing import Any, Callable
LIPSUM = """\
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et lectus lacinia enim dictum posuere. Quisque nunc tellus, luctus quis eleifend a, placerat maximus ipsum.
Nam egestas, nisi in varius tempus, enim tortor consectetur eros, ac pretium urna ipsum at orci. Praesent ut dui eu lectus efficitur ultrices. In vehicula leo faucibus tempor posuere.
Nam et est in nisi iaculis rhoncus eu et nibh. Aliquam eget risus lacus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus."""
class Editor(tk.Frame):
def __init__(self, *args: Any, **kwargs: Any):
tk.Frame.__init__(self, *args, **kwargs)
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(1, weight=1)
self.line_num = tk.Text(
self,
width=3,
yscrollcommand=self.scroll_update,
cursor="arrow",
)
self.line_num.tag_configure("rjust", justify="right")
self.line_num.insert("1.0", "1", "rjust")
# disable selection
self.line_num.bindtags((str(self.line_num), str(self), "all"))
self.line_num.grid(row=1, column=0, sticky="ns")
self.text = tk.Text(
self,
yscrollcommand=self.scroll_update,
wrap="none",
)
self.text.bind("", lambda _: self.update_lines())
self.text.grid(row=1, column=1, sticky="nesw")
self.editor_v_sbr = tk.Scrollbar(self, command=self.editor_scroll)
self.editor_v_sbr.grid(row=1, column=2, sticky="ns")
self.editor_h_sbr = tk.Scrollbar(
self, command=self.text.xview, orient="horizontal" # type:ignore
)
self.editor_h_sbr.grid(row=2, column=0, columnspan=2, sticky="ew")
self.text.config(xscrollcommand=self.editor_h_sbr.set)
def editor_scroll(self, _: Any, position: float):
self.line_num.yview_moveto(position)
self.text.yview_moveto(position)
def scroll_update(self, first: float, last: float):
self.text.yview_moveto(first)
self.line_num.yview_moveto(first)
self.editor_v_sbr.set(first, last)
def update_lines(self, new_text: str | None = None):
if not new_text:
new_text = self.text.get("1.0", "end")
self.line_num.config(state="normal")
self.line_num.delete("1.0", "end")
num_lines = len(new_text.splitlines(True))
if num_lines >= 1000:
new_width = int(math.log10(num_lines)) + 1
self.line_num.config(width=new_width)
self.line_num.insert(
"1.0",
"\n".join([str(x + 1) for x in range(num_lines)]),
"rjust",
)
self.line_num.config(state="disabled")
def view_file(self):
self.text_content = LIPSUM
self.update_lines(self.text_content)
self.text.delete("1.0", "end")
self.text.insert("1.0", self.text_content)
def goto(self, start: tuple[int, int], end: tuple[int, int]):
pos: Callable[[tuple[int, int]], str] = lambda x: f"{x[0]}.{x[1]-1}"
self.text.focus_set()
self.text.see(pos(start))
self.text.mark_set("insert", pos(start))
self.text.tag_remove("sel", "1.0", "end")
self.text.tag_add("sel", pos(start), pos(end))
class Results(tk.LabelFrame):
def __init__(
self,
master: tk.Tk,
goto: Callable[[tuple[int, int], tuple[int, int]], None],
*args: Any,
**kwargs: Any,
):
tk.LabelFrame.__init__(self, master, *args, text="Results", **kwargs)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.text = tk.Text(
self,
wrap="none",
)
self.text.insert("end", "Lorem ipsum dolor sit amet\n")
self.text.insert("end", "View in editor", "link")
def callback():
self.goto((1, 1), (1, 27))
return "break"
self.text.tag_bind("link", "", lambda _: callback())
self.link_font = Font(self, "TkDefaultFont")
self.link_font.configure(underline=True)
self.text.tag_configure("link", font=self.link_font, foreground="SlateBlue3")
self.text.configure(state="disabled")
self.text.tag_bind("link", "", self.link_enter)
self.text.tag_bind("link", "", self.link_leave)
self.text.grid(row=0, column=0, sticky="nesw", padx=(10, 0), pady=(10, 0))
self.y_sbr = tk.Scrollbar(self, command=self.text.yview) # type:ignore
self.y_sbr.grid(row=0, column=1, sticky="ns", padx=(0, 10), pady=(10, 0))
self.x_sbr = tk.Scrollbar(
self, command=self.text.xview, orient="horizontal" # type:ignore
)
self.x_sbr.grid(row=1, column=0, sticky="ew", pady=(0, 10), padx=(10, 0))
self.text.configure(yscrollcommand=self.y_sbr.set)
self.text.configure(xscrollcommand=self.x_sbr.set)
self.goto = goto
def link_enter(self, _: Any):
self.text.config(cursor="hand2")
def link_leave(self, _: Any):
self.text.config(cursor="")
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.editor = Editor(self)
self.editor.grid(row=0, column=1, sticky="nesw", padx=10, pady=10)
self.results = Results(self, self.editor.goto)
self.results.grid(row=0, column=2, sticky="nesw", padx=10, pady=10)
self.editor.text.focus()
self.editor.view_file()
if __name__ == "__main__":
app = App()
app.mainloop()
1746518301
Anonymous
Ich habe eine Anwendung mit zwei Text -Widgets in zwei Frames. Klicken Sie in einem Text -Widget (formatierter Text mit einem Tag Bind) (formatierter Text mit einem Tag Bind) ([code]Results.text[/code]) sollte Text in einem anderen auswählen ([code]Editor.text[/code]). Wenn ich einmal auf den Link klicke, siehe Teil, mark_set und die Auswahl nicht anwenden. Ich habe versucht, "Break" aus dem Ereignishandler zurückzugeben und mit Focus_set , focus_force , update_idletasks und aktualisiert in der GOTO -Methode ohne Erfolg.[code]import math import tkinter as tk from tkinter.font import Font from typing import Any, Callable LIPSUM = """\ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et lectus lacinia enim dictum posuere. Quisque nunc tellus, luctus quis eleifend a, placerat maximus ipsum. Nam egestas, nisi in varius tempus, enim tortor consectetur eros, ac pretium urna ipsum at orci. Praesent ut dui eu lectus efficitur ultrices. In vehicula leo faucibus tempor posuere. Nam et est in nisi iaculis rhoncus eu et nibh. Aliquam eget risus lacus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.""" class Editor(tk.Frame): def __init__(self, *args: Any, **kwargs: Any): tk.Frame.__init__(self, *args, **kwargs) self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(1, weight=1) self.line_num = tk.Text( self, width=3, yscrollcommand=self.scroll_update, cursor="arrow", ) self.line_num.tag_configure("rjust", justify="right") self.line_num.insert("1.0", "1", "rjust") # disable selection self.line_num.bindtags((str(self.line_num), str(self), "all")) self.line_num.grid(row=1, column=0, sticky="ns") self.text = tk.Text( self, yscrollcommand=self.scroll_update, wrap="none", ) self.text.bind("", lambda _: self.update_lines()) self.text.grid(row=1, column=1, sticky="nesw") self.editor_v_sbr = tk.Scrollbar(self, command=self.editor_scroll) self.editor_v_sbr.grid(row=1, column=2, sticky="ns") self.editor_h_sbr = tk.Scrollbar( self, command=self.text.xview, orient="horizontal" # type:ignore ) self.editor_h_sbr.grid(row=2, column=0, columnspan=2, sticky="ew") self.text.config(xscrollcommand=self.editor_h_sbr.set) def editor_scroll(self, _: Any, position: float): self.line_num.yview_moveto(position) self.text.yview_moveto(position) def scroll_update(self, first: float, last: float): self.text.yview_moveto(first) self.line_num.yview_moveto(first) self.editor_v_sbr.set(first, last) def update_lines(self, new_text: str | None = None): if not new_text: new_text = self.text.get("1.0", "end") self.line_num.config(state="normal") self.line_num.delete("1.0", "end") num_lines = len(new_text.splitlines(True)) if num_lines >= 1000: new_width = int(math.log10(num_lines)) + 1 self.line_num.config(width=new_width) self.line_num.insert( "1.0", "\n".join([str(x + 1) for x in range(num_lines)]), "rjust", ) self.line_num.config(state="disabled") def view_file(self): self.text_content = LIPSUM self.update_lines(self.text_content) self.text.delete("1.0", "end") self.text.insert("1.0", self.text_content) def goto(self, start: tuple[int, int], end: tuple[int, int]): pos: Callable[[tuple[int, int]], str] = lambda x: f"{x[0]}.{x[1]-1}" self.text.focus_set() self.text.see(pos(start)) self.text.mark_set("insert", pos(start)) self.text.tag_remove("sel", "1.0", "end") self.text.tag_add("sel", pos(start), pos(end)) class Results(tk.LabelFrame): def __init__( self, master: tk.Tk, goto: Callable[[tuple[int, int], tuple[int, int]], None], *args: Any, **kwargs: Any, ): tk.LabelFrame.__init__(self, master, *args, text="Results", **kwargs) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.text = tk.Text( self, wrap="none", ) self.text.insert("end", "Lorem ipsum dolor sit amet\n") self.text.insert("end", "View in editor", "link") def callback(): self.goto((1, 1), (1, 27)) return "break" self.text.tag_bind("link", "", lambda _: callback()) self.link_font = Font(self, "TkDefaultFont") self.link_font.configure(underline=True) self.text.tag_configure("link", font=self.link_font, foreground="SlateBlue3") self.text.configure(state="disabled") self.text.tag_bind("link", "", self.link_enter) self.text.tag_bind("link", "", self.link_leave) self.text.grid(row=0, column=0, sticky="nesw", padx=(10, 0), pady=(10, 0)) self.y_sbr = tk.Scrollbar(self, command=self.text.yview) # type:ignore self.y_sbr.grid(row=0, column=1, sticky="ns", padx=(0, 10), pady=(10, 0)) self.x_sbr = tk.Scrollbar( self, command=self.text.xview, orient="horizontal" # type:ignore ) self.x_sbr.grid(row=1, column=0, sticky="ew", pady=(0, 10), padx=(10, 0)) self.text.configure(yscrollcommand=self.y_sbr.set) self.text.configure(xscrollcommand=self.x_sbr.set) self.goto = goto def link_enter(self, _: Any): self.text.config(cursor="hand2") def link_leave(self, _: Any): self.text.config(cursor="") class App(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.editor = Editor(self) self.editor.grid(row=0, column=1, sticky="nesw", padx=10, pady=10) self.results = Results(self, self.editor.goto) self.results.grid(row=0, column=2, sticky="nesw", padx=10, pady=10) self.editor.text.focus() self.editor.view_file() if __name__ == "__main__": app = App() app.mainloop() [/code]