MacOS错误与Tkinter代码导致分段错误(SIGSEGV)

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

MacOS error with Tkinter code causing segmentation fault (SIGSEGV)

问题

我理解你需要翻译英文代码段。以下是你提供的Python代码的翻译:

我正在开发一个Python脚本使用Tkinter的Text小部件来显示文本并查找隐藏字符当我在MacOS上运行我的脚本时它会崩溃并显示分段错误

我已经将问题缩小到Extension类的find_and_mark方法具体来说崩溃发生在这一行:`self.locations_and_markers[index].place(x=x, y=y, anchor="nw")`。

在调试时代码显示在崩溃之前成功运行了三次当去除place方法时代码可以正常运行但没有它的话其他代码就没有意义了

这是我一直在测试的最小可重现示例
```python
from __future__ import annotations

from tkinter import Event, Label
from tkinter import Tk, Text

root = Tk()

text = Text(root)
text.pack(fill="both", expand=True)

# 插入带有隐藏字符的文本
text.insert("1.0", "Hello\u00a0 World")

class Marker(Label):
    """用于表示隐藏字符的标记"""

    def __init__(self, master: Text) -> None:
        # 创建标签
        self.text = master
        super().__init__(master)

    def __repr__(self) -> str:
        return f"Marker-{self._w}"

class Extension:
    """隐藏字符查找器"""

    def __init__(self, master: Tk) -> None:
        # 设置主窗口和主应用程序
        self.master = master

        # 设置其他变量
        self.locations_and_markers: dict[str, Marker] = {}

        # 绑定事件
        self.master.bind("<Configure>", self.find_and_mark)

    def find_and_mark(self, _: Event | None = None) -> None:
        """查找所有隐藏字符并标记它们"""

        del _

        # 获取文本小部件

        # 查找所有隐藏字符
        hidden_char_indexes: list[str] = [text.search(
            "\u00a0", "1.0", "end", regexp=True, nocase=True
        )]

        # 移除所有标记
        for marker in self.locations_and_markers.values():
            marker.destroy()
        self.locations_and_markers = {}

        if hidden_char_indexes == [""]:
            return

        # 添加标记
        for index in hidden_char_indexes:
            # 创建标记
            self.locations_and_markers[index] = Marker(text)

            # 获取字符的坐标
            bbox = text.bbox(index)

            # 检查bbox不为None
            if bbox is None:
                continue

            # 检查字符是否可见并在视图中
            start: str = text.index("@0,0")
            end: str = text.index(f"@{text.winfo_width()},{text.winfo_height()}")
            in_view: bool = text.compare(start, "<=", index) and text.compare(
                index, "<=", end
            )
            if not in_view:
                continue

            # 获取字符的坐标
            x: int = bbox[0]
            y: int = bbox[1]

            # 放置标记
            self.locations_and_markers[index].place(x=x, y=y, anchor="nw")

Extension(root)

root.mainloop()

希望这可以帮助你找出导致分段错误的原因并解决问题。谢谢!

英文:

I am working on a Python script that uses the Tkinter Text widget to display text and find hidden characters. When I run my script on MacOS, it crashes with a segmentation fault.

I have narrowed down the issue to the find_and_mark method of the Extension class. Specifically, the crash occurs on this line: self.locations_and_markers[index].place(x=x, y=y, anchor=&quot;nw&quot;).

The code, when debugging, is shown to tun thrice successfully before crashing. The code runs fine when the place is removed but there's no point to any of the other code without it.

Here is the minimum reproducible example I've been testing with:

from __future__ import annotations

from tkinter import Event, Label
from tkinter import Tk, Text

root = Tk()

text = Text(root)
text.pack(fill=&quot;both&quot;, expand=True)

# Insert text with hidden characters
text.insert(&quot;1.0&quot;, &quot;Hello\u00a0 World&quot;)

class Marker(Label):
    &quot;&quot;&quot;A marker for a hidden character&quot;&quot;&quot;

    def __init__(self, master: Text) -&gt; None:
        # Make the label
        self.text = master
        super().__init__(master)

    def __repr__(self) -&gt; str:
        return f&quot;Marker-{self._w}&quot;

class Extension:
    &quot;&quot;&quot;Hidden character finder&quot;&quot;&quot;

    def __init__(self, master: Tk) -&gt; None:
        # Set master and mainapp
        self.master = master

        # Set other variables
        self.locations_and_markers: dict[str, Marker] = {}

        # Make binds
        self.master.bind(&quot;&lt;Configure&gt;&quot;, self.find_and_mark)


    def find_and_mark(self, _: Event | None = None) -&gt; None:
        &quot;&quot;&quot;Finds all hidden characters and marks them&quot;&quot;&quot;

        del _

        # Get the text widget

        # Find all hidden characters
        hidden_char_indexes: list[str] = [text.search(
            &quot;\u00a0&quot;, &quot;1.0&quot;, &quot;end&quot;, regexp=True, nocase=True
        )]

        # Remove all markers
        for marker in self.locations_and_markers.values():
            marker.destroy()
        self.locations_and_markers = {}

        if hidden_char_indexes == [&quot;&quot;]:
            return

        # Add markers
        for index in hidden_char_indexes:
            # Create the marker
            self.locations_and_markers[index] = Marker(text)

            # Get the coordinates of the character
            bbox = text.bbox(index)

            # Check that the bbox is not None
            if bbox is None:
                continue

            # Check that the character is visible and in view
            start: str = text.index(&quot;@0,0&quot;)
            end: str = text.index(f&quot;@{text.winfo_width()},{text.winfo_height()}&quot;)
            in_view: bool = text.compare(start, &quot;&lt;=&quot;, index) and text.compare(
                index, &quot;&lt;=&quot;, end
            )
            if not in_view:
                continue

            # Get the coordinates of the character
            x: int = bbox[0]
            y: int = bbox[1]

            # Place the marker
            self.locations_and_markers[index].place(x=x, y=y, anchor=&quot;nw&quot;)

Extension(root)

root.mainloop()

Can anyone help me figure out what is causing this segmentation fault and how to fix it? Thank you!

答案1

得分: 1

请小心绑定根或顶级窗口。事件处理程序将处理报告给子窗口的事件。

所以,请这样过滤事件。

...
    def find_and_mark(self, e: Event) -> None:
        if e.widget != self.master:
            return
        ...

不管怎样,段错误似乎是Tkinter的一个错误。在我的Linux系统中,它会导致X11 BadWindow错误。关于报告这个问题,您可以在这里报告它。

英文:

You should be careful when binding a root or top level window. The event handler will be called for events which were reported to child widgets.

So, filter events like this.

...
def find_and_mark(self, e: Event) -&gt; None:
if e.widget != self.master:
return
...

Anyway, the segmentation fault seems to be a bug of Tkinter. In my Linux box, it causes an X11 BadWindow error. What about reporting it here?

答案2

得分: 0

奇怪的是,它只是在没有after_idle()时进行投诉。添加后修复了它。

英文:

Oddly enough, it was simply complaining over no after_idle() in the bind. Adding that fixed it.

huangapple
  • 本文由 发表于 2023年5月15日 03:45:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76249393.html
匿名

发表评论

匿名网友

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

确定