Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GtkSourceView/缓冲区崩溃:Gtk错误:字节索引超出了行的末尾_Python_Gtk3_Gtksourceview - Fatal编程技术网

Python GtkSourceView/缓冲区崩溃:Gtk错误:字节索引超出了行的末尾

Python GtkSourceView/缓冲区崩溃:Gtk错误:字节索引超出了行的末尾,python,gtk3,gtksourceview,Python,Gtk3,Gtksourceview,我一直在为写故事而编写文本编辑器。我正在使用Python、GTK+3和GtkSourceView 3。编辑器的要点是折叠某些区域。虽然没有-还没有由于内置了对GTK TextView/SourceView中折叠的支持,我一直在使用不可见=True的标记和SourceView的源代码标记来实现该功能 此处提供的源代码: 核心编辑器(SourceBuffer和SourceView)位于以下位置: 出于测试目的,您可以克隆回购协议,并使用以下工具运行应用程序: mawe$ ./mawe.py tes

我一直在为写故事而编写文本编辑器。我正在使用Python、GTK+3和GtkSourceView 3。编辑器的要点是折叠某些区域。虽然没有-还没有由于内置了对GTK TextView/SourceView中折叠的支持,我一直在使用不可见=True的标记和SourceView的源代码标记来实现该功能

此处提供的源代码:

核心编辑器(SourceBuffer和SourceView)位于以下位置:

出于测试目的,您可以克隆回购协议,并使用以下工具运行应用程序:

mawe$ ./mawe.py test/test.txt
现在,应用程序经常随机崩溃,出现如下错误:

(mawe.py:10556): Gtk-WARNING **: /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtktextbtree.c:4034: byte index off the end of the line
(mawe.py:10556): Gtk-ERROR **: Byte index 1362 is off the end of the line
Trace/breakpoint trap
def filter_event(widget, event, *args):
    # Allow these
    if event.type == Gdk.EventType.KEY_PRESS: return False
    if event.type == Gdk.EventType.KEY_RELEASE: return False

    # Block these
    if event.type == Gdk.EventType.LEAVE_NOTIFY: return True
    if event.type == Gdk.EventType.MOTION_NOTIFY: return True

    # Print & allow the rest
    print(event)
    return False

self.text.connect("event", filter_event)

<mark 1><at>Scene 1 heading<eol>
Line
Line
<mark 2>Scene 2 heading
没有其他错误或警告日志。我一直在用谷歌搜索错误,但没有成功

其他症状似乎是:

  • 即使编辑器处于空闲状态,也会发生崩溃

  • 今天我发现,奇怪的是,我可以通过将鼠标移到隐藏的部分上很快得到崩溃:o

我不能100%肯定,但我认为这与不可见区域有关

问:有人知道这是否是已知的bug吗

问:有人有什么想法可以让我寻找可能的解决方案吗?有什么想法可以导致这次崩溃,我可以更深入地探索什么


更新:我用标签做了一些更广泛的测试。似乎没有其他属性对鼠标移动做出反应,但当打开“不可见性”时,鼠标在整个区域的移动会使应用程序崩溃。我一直在搜索导致gtktextbtree崩溃的鼠标事件报告,但迄今为止没有成功。看起来这适用于几个v3.x GTK版本


更新:我想我几乎找到了一个解决方法:从GtkSource中过滤掉运动通知事件。视图似乎工作正常,如下所示:

(mawe.py:10556): Gtk-WARNING **: /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtktextbtree.c:4034: byte index off the end of the line
(mawe.py:10556): Gtk-ERROR **: Byte index 1362 is off the end of the line
Trace/breakpoint trap
def filter_event(widget, event, *args):
    # Allow these
    if event.type == Gdk.EventType.KEY_PRESS: return False
    if event.type == Gdk.EventType.KEY_RELEASE: return False

    # Block these
    if event.type == Gdk.EventType.LEAVE_NOTIFY: return True
    if event.type == Gdk.EventType.MOTION_NOTIFY: return True

    # Print & allow the rest
    print(event)
    return False

self.text.connect("event", filter_event)

<mark 1><at>Scene 1 heading<eol>
Line
Line
<mark 2>Scene 2 heading
如果在隐藏线附近按下鼠标按钮,应用程序仍然会崩溃,但看起来它不再因鼠标移动而崩溃


更新:更多调查。虽然阻止鼠标事件可以防止崩溃,但也会导致一些怪癖,例如无法使用鼠标放置光标、选择区域、DnD等。。。此外,鼠标光标可能会消失,因为它不是每次都正确更新。我敢肯定,将鼠标/窗口坐标转换为缓冲区位置(当文本中有较大的隐藏块时)的算法中存在缺陷,因此任何鼠标事件都可能导致应用程序崩溃


更新:我一直在尝试为主题创建简单的测试用例。好事情:隐藏似乎起作用了。坏事情:还不能重现问题。可以在此处找到测试脚本:


更新:试图找出它-测试用例工作,编辑器不工作。和测试用例的区别至少在于编辑器在事件循环(*)中放置了隐藏标记。试着做一个测试案例

(*)使用当前Gtk SourceView/TextView实现折叠肯定有许多不同的解决方案。我选择了使用“标记”语言并在编辑时应用折叠的方法,因为它与undo/redo一起工作。我也尝试过其他解决方案,如:

  • 剪切折叠的场景&在文本缓冲区中插入一个小部件,其中包含文本本身。想法:“文本[选择用于折叠的部分]文本”->“文本[锚定+带有剪切文本的小部件]文本”-遗憾的是,它不适用于撤消/重做

  • 剪切文本,给它一个ID,然后在缓冲区中放置一个包含ID的特定标记部分。“文本[选择用于折叠的部分]文本”->“文本[ID w/隐藏+受保护的标记]文本”-不起作用,因为剪切粘贴或撤消/重做不应用标记,因此用户可以销毁标记

  • 普通标记:用折叠指示器保持标记是难以置信的困难。你需要像“[char][mark][char]”这样带有受保护标签的东西,以确保你不会在某处丢失标记

  • 无论如何,我会继续调查的



    更新:仍然无法在我的测试脚本中重现该问题,但发现了一些可能有趣的问题:折叠最后一个场景不会导致崩溃-仅当折叠另一个场景之后的场景时(折叠或不折叠)。

    我已修复该问题。我只是不明白为什么它能工作,为什么我不能用测试脚本重现这个问题。下面是执行折叠的代码段:

    fold_start = at.copy()
    fold_start.forward_to_line_end()
    fold_start.forward_char() # Comment this line -> crash
    fold_end = self.scene_end_iter(end)
    self.apply_tag(self.tag_fold_hide, fold_start, fold_end)
    
    at
    在insert text或delete range回调时派生,并指向行的开始
    fold_end
    是指向下一个场景标记或文件结尾的文本。如果我们查看缓冲区内容,它是这样的:

    (mawe.py:10556): Gtk-WARNING **: /build/gtk+3.0-2Ut_nl/gtk+3.0-3.18.9/./gtk/gtktextbtree.c:4034: byte index off the end of the line
    (mawe.py:10556): Gtk-ERROR **: Byte index 1362 is off the end of the line
    Trace/breakpoint trap
    
    def filter_event(widget, event, *args):
        # Allow these
        if event.type == Gdk.EventType.KEY_PRESS: return False
        if event.type == Gdk.EventType.KEY_RELEASE: return False
    
        # Block these
        if event.type == Gdk.EventType.LEAVE_NOTIFY: return True
        if event.type == Gdk.EventType.MOTION_NOTIFY: return True
    
        # Print & allow the rest
        print(event)
        return False
    
    self.text.connect("event", filter_event)
    
    
    <mark 1><at>Scene 1 heading<eol>
    Line
    Line
    <mark 2>Scene 2 heading
    
    场景1标题
    线
    线
    场景2标题
    
    将隐藏标记从
    应用到
    会导致崩溃。将标记从
    应用到
    可以正常工作。如果折叠到文件的末尾(
    ==buffer.get\u end\u iter()
    ),则可以进行折叠。在某些情况下,如果只需要隐藏换行符,它也可以工作,但不是在所有情况下都可以


    如前所述,我不明白为什么这样做,为什么我不能用更简单的脚本重现问题,但我一直在进行更多的研究,尽管现在有了修复,这并不是那么紧迫。

    好的,昨天我这样做了,可见和不可见部分都使用类似的字体描述进行格式化。我仍然不能用简单的测试脚本重现这个问题,但似乎如果可见和隐藏部分离它们太远,偏移量计算就会出错。到目前为止,我知道:

    • 错误消息(如
      字节索引1362)不在该行末尾
      跟踪/断点陷阱
      与隐藏部分的长度相差约5-7字节

    • 当可见部分和不可见部分在字体大小、填充和重量方面彼此“足够接近”时,不会出现错误。在我的工作示例中,我使用完全相同的字体、重量、大小等格式化不可见的部分,程序会这样做