Gtk3:动态添加和移除EventBox中的按钮:按钮无法接收鼠标按压信号

1 投票
1 回答
1790 浏览
提问于 2025-04-17 18:17

我在这里使用的是Python和PyGObjects(一个用于Gtk 3的库)。

看看下面的代码:

from gi.repository import Gtk

class InternalWidget(Gtk.Button):
    def __init__(self):
        super(InternalWidget, self).__init__()
        self.set_size_request(100,100)
        self.connect("button-press-event", self.on_press)

    def on_press(self, *args):
        print "The Internal Widget was clicked."


class ExternalEventBox(Gtk.EventBox):
    def __init__(self):
        super(ExternalEventBox, self).__init__()
        self.fixed = Gtk.Fixed()
        self.add(self.fixed)
        self.internal_widget = InternalWidget()
        self.set_size_request(200, 200)
        self.connect("button-press-event", self.on_press)
        self.connect("enter-notify-event", self.on_enter)
        self.connect("leave-notify-event", self.on_leave)

    def on_enter(self, *args):
        self.fixed.put(self.internal_widget, 50,50)
        self.show_all()

    def on_leave(self, *args):
        self.fixed.remove(self.internal_widget)

    def on_press(self,*args):
        print "The External Event Box was clicked."

w = Gtk.Window(Gtk.WindowType.TOPLEVEL)
w.connect("delete-event", Gtk.main_quit)
w.add(ExternalEventBox())
w.show_all()
Gtk.main()

在上面的代码中,每当鼠标进入ExternalEventBox时,就会把一个按钮(InternalWidget)作为子元素添加到里面。当鼠标离开ExternalEventBox时,这个按钮又会被移除。

现在,如果你运行这段代码(你可以试试),按钮会正常出现和消失。但是,点击这个按钮时,和预期的不一样,它只会向包含它的ExternalEventBox发送信号,而按钮本身却没有收到任何信号。

有趣的是,当这个按钮不是动态添加和移除,而是在事件框的构造函数中一次性添加并且不再移除时,点击按钮的行为就正常了。

这算是个bug吗,还是我漏掉了什么?

补充说明:简单来说,我只收到“外部事件框被点击了。”,却从来没有收到“内部小部件被点击了。”。

更新:我提交了一个bug报告

1 个回答

0

你需要把事件框(EventBox)的事件窗口设置在它的子元素下面,可以用 .set_above_child(false) 来实现。

这里有相关的文档:GtkEventBox

如果窗口在上面,事件框里的所有事件都会被事件框接收。如果窗口在下面,子元素窗口里的事件会先传给那个子元素,然后再传给它的父元素。

撰写回答