Tkinter在使用文本小部件时出现问题。

huangapple go评论52阅读模式
英文:

Tkinter problem while using the text widget

问题

我有这段代码来使每个文本小部件(Text() widget)可点击,该文本小部件使用了tkinter。
然而,当我运行程序并单击文本时,我会收到每个相应文本行的错误消息:

_tkinter.TclError: bad text index "This is the first string."
_tkinter.TclError: bad text index "This is the second string."
_tkinter.TclError: bad text index "This is the third string."

如果有人知道解决此问题的方法,请告诉我,我将永远感激不尽。以下是完整的代码:

import tkinter as tk

def text_click(event):
    index = text_widget.tag_names(tk.CURRENT)[0]
    clicked_text = text_widget.get(index)
    print(clicked_text)

# 创建主窗口
window = tk.Tk()

# 创建一个Text小部件
text_widget = tk.Text(window, wrap="word")
text_widget.pack()

# 字符串列表
texto = ["This is the first string.", "This is the second string.", "This is the third string."]

# 插入列表中的每个字符串
for string in texto:
    text_widget.insert(tk.END, string + "\n")

    # 为每个插入的字符串应用一个标签
    tag_start = f"{text_widget.index(tk.END)}-{len(string) - 1}c"
    tag_end = f"{text_widget.index(tk.END)}-1c"
    text_widget.tag_add(string, tag_start, tag_end)

    # 将点击事件绑定到标签
    text_widget.tag_bind(string, "<Button-1>", text_click)

# 使文本小部件为只读
text_widget.configure(state="disabled")

# 启动tkinter事件循环
window.mainloop()

我期望在单击每行文本时打印每行的文本。

英文:

I have this code to make each text "clickleable", from the Text() widget that has tkinter.
However, when I run the program and click over one text I get this error message witch each corresponding
text line:

_tkinter.TclError: bad text index &quot;This is the first string.&quot;
_tkinter.TclError: bad text index &quot;This is the second string.&quot;
_tkinter.TclError: bad text index &quot;This is the third string.&quot;

If anyone may now a way to solve the issue, I be forever grateful. Here is the complete code:

import tkinter as tk

def text_click(event):
    index = text_widget.tag_names(tk.CURRENT)[0]
    clicked_text = text_widget.get(index)
    print(clicked_text)

# Create the main window
window = tk.Tk()

# Create a Text widget
text_widget = tk.Text(window, wrap=&quot;word&quot;)
text_widget.pack()

# List of strings
texto = [&quot;This is the first string.&quot;, &quot;This is the second string.&quot;, &quot;This is the third string.&quot;]

# Insert each string from the list
for string in texto:
    text_widget.insert(tk.END, string + &quot;\n&quot;)

    # Apply a tag to each inserted string
    tag_start = f&quot;{text_widget.index(tk.END)}-{len(string) - 1}c&quot;
    tag_end = f&quot;{text_widget.index(tk.END)}-1c&quot;
    text_widget.tag_add(string, tag_start, tag_end)

    # Bind the click event to the tag
    text_widget.tag_bind(string, &quot;&lt;Button-1&gt;&quot;, text_click)

# Make the text widget read-only
text_widget.configure(state=&quot;disabled&quot;)

# Start the tkinter event loop
window.mainloop()

I am expecting to print the text of each line when clicked over it.

答案1

得分: 2

If you print out index, you'll see it's the string in the error: &quot;This is the first string.&quot;. That is not a valid index. An index needs to be something like line.character or @x,y, and a few other special strings (eg: &quot;end&quot;, &quot;current&quot;, etc).

> I am expecting to print the text of each line when clicked over it.

You can use an index of the form @x,y, and you can use the x and y attributes of the event to create that index. Another alternative is to use the index &quot;current&quot; which represents the character closest to the mouse.

You can use &quot;linestart&quot; and &quot;lineend&quot; to translate that index to the start and end of the line.

Example:

def text_click(event):
    start_index = text_widget.index(f&quot;@{event.x},{event.y} linestart&quot;)
    end_index = text_widget.index(f&quot;@{event.x},{event.y} lineend&quot;)
    clicked_text = text_widget.get(start_index, end_index)
    print(clicked_text)
英文:

If you print out index, you'll see it's the string in the error: &quot;This is the first string.&quot;. That is not a valid index. An index needs to be something like line.character or @x,y, and a few other special strings (eg: &quot;end&quot;, &quot;current&quot;, etc).

> I am expecting to print the text of each line when clicked over it.

You can use an index of the form @x,y, and you can use the x and y attributes of the event to create that index. Another alternative is to use the index &quot;current&quot; which represents the character closest to the mouse.

You can use &quot;linestart&quot; and &quot;lineend&quot; to translate that index to the start and end of the line.

Example:

def text_click(event):
    start_index = text_widget.index(f&quot;@{event.x},{event.y} linestart&quot;)
    end_index = text_widget.index(f&quot;@{event.x},{event.y} lineend&quot;)
    clicked_text = text_widget.get(start_index, end_index)
    print(clicked_text)

答案2

得分: 0

你可以像这样修改你的 text_click 函数:

def text_click(event):
    index = text_widget.index(tk.CURRENT)
    clicked_text = text_widget.get(index + " linestart", index + " lineend")
    print(clicked_text)

这会使用 text_widget.index(tk.CURRENT) 获取被点击文本的索引,然后通过添加适当的 linestartlineend 修饰符来检索实际文本。

英文:

You can modify your text_click function like this:

def text_click(event):
    index = text_widget.index(tk.CURRENT)
    clicked_text = text_widget.get(index + &quot; linestart&quot;, index + &quot; lineend&quot;)
    print(clicked_text)

This retrieves the index of the clicked text using text_widget.index(tk.CURRENT), then it uses that index to retrieve the actual text by adding the appropriate linestart and lineend modifiers to the index.

huangapple
  • 本文由 发表于 2023年5月26日 12:16:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76337630.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定