标记文本标签中带有信号 "activate link" 的 PyGtk 分段
PyGtk Segmentation with signal "activate link" in a markup-text label
下面的 MWE 只是创建一个带有超文本的标签。大多数时候(但不是每次)当我点击 link.
时它会导致分段错误
我假设我对 PyGtk 有一些错误的理解并且我使用它的方式不对?
也就是错误输出:
Window._on_activate_link()
Fatal Python error: Segmentation fault
Current thread 0x00007fa2718a7740 (most recent call first):
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 1641 in main
File "./window.py", line 45 in <module>
Speicherzugriffsfehler
这是关于我的系统和版本的信息
Linux-4.19.0-14-amd64-x86_64-with-debian-10.8
Python 3.7.3 CPython
Gtk 3.0
GIO 3.30.4
Cairo 1.16.2
这是MWE
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import faulthandler; faulthandler.enable()
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class FeedybusWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
hbox = Gtk.Box(spacing=5)
self.add(hbox)
self._feed_label = Gtk.Label(label='')
self._feed_label.set_use_markup(True)
self._feed_label.set_markup('<a href="renamelabel">Click me</a>')
self._feed_label.connect('activate-link', self._on_activate_link)
hbox.pack_start(self._feed_label, True, True, 20)
# EVENT: destroy
self.connect('delete-event', self._on_delete_event)
self.connect('destroy', self._on_destroy)
def _on_activate_link(self, label, uri):
print('Window._on_activate_link()')
if uri == 'renamelabel':
self._feed_label.set_markup('<a href="renamelabel">Click me AGAIN</a>')
return True
return False
def _on_delete_event(self, window, event=None):
self.destroy()
def _on_destroy(self, caller):
Gtk.main_quit()
if __name__ == '__main__':
window = FeedybusWindow()
window.show_all()
Gtk.main()
编辑:当然我可以使用其他 GUI 元素代替 Gtk.Label
。但这将是一种解决方法而不是解决方案。 我的问题的重点是我是否以错误的方式使用 Gtk 包或者 Gtk 中可能存在我应该报告的错误。
这一定是一个错误(可能是:https://gitlab.gnome.org/GNOME/gtk/-/issues/1498)。我看不出你的代码有任何问题,我也可以在我的 Ubuntu 20.04 系统上重现崩溃。
似乎在 activate-link 处理程序中设置标签是问题所在。
FWIW:解决方法是将其设置在处理程序之外,如下所示:
def _on_activate_link(self, label, uri):
print('Window._on_activate_link()')
if uri == 'renamelabel':
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self._rename)
return False
def _rename(self):
self._feed_label.set_markup('<a href="renamelabel">Click me AGAIN</a>')
下面的 MWE 只是创建一个带有超文本的标签。大多数时候(但不是每次)当我点击 link.
时它会导致分段错误我假设我对 PyGtk 有一些错误的理解并且我使用它的方式不对?
也就是错误输出:
Window._on_activate_link()
Fatal Python error: Segmentation fault
Current thread 0x00007fa2718a7740 (most recent call first):
File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 1641 in main
File "./window.py", line 45 in <module>
Speicherzugriffsfehler
这是关于我的系统和版本的信息
Linux-4.19.0-14-amd64-x86_64-with-debian-10.8
Python 3.7.3 CPython
Gtk 3.0
GIO 3.30.4
Cairo 1.16.2
这是MWE
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import faulthandler; faulthandler.enable()
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class FeedybusWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
hbox = Gtk.Box(spacing=5)
self.add(hbox)
self._feed_label = Gtk.Label(label='')
self._feed_label.set_use_markup(True)
self._feed_label.set_markup('<a href="renamelabel">Click me</a>')
self._feed_label.connect('activate-link', self._on_activate_link)
hbox.pack_start(self._feed_label, True, True, 20)
# EVENT: destroy
self.connect('delete-event', self._on_delete_event)
self.connect('destroy', self._on_destroy)
def _on_activate_link(self, label, uri):
print('Window._on_activate_link()')
if uri == 'renamelabel':
self._feed_label.set_markup('<a href="renamelabel">Click me AGAIN</a>')
return True
return False
def _on_delete_event(self, window, event=None):
self.destroy()
def _on_destroy(self, caller):
Gtk.main_quit()
if __name__ == '__main__':
window = FeedybusWindow()
window.show_all()
Gtk.main()
编辑:当然我可以使用其他 GUI 元素代替 Gtk.Label
。但这将是一种解决方法而不是解决方案。 我的问题的重点是我是否以错误的方式使用 Gtk 包或者 Gtk 中可能存在我应该报告的错误。
这一定是一个错误(可能是:https://gitlab.gnome.org/GNOME/gtk/-/issues/1498)。我看不出你的代码有任何问题,我也可以在我的 Ubuntu 20.04 系统上重现崩溃。 似乎在 activate-link 处理程序中设置标签是问题所在。
FWIW:解决方法是将其设置在处理程序之外,如下所示:
def _on_activate_link(self, label, uri):
print('Window._on_activate_link()')
if uri == 'renamelabel':
Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self._rename)
return False
def _rename(self):
self._feed_label.set_markup('<a href="renamelabel">Click me AGAIN</a>')