使用GtkBuilder自动连接信号时对话框中断,但在手动连接信号时有效

dum*_*ter 6 python gtk pygtk gtkbuilder pygobject

我想要一个对话窗口,其中一些按钮关闭对话框而其他按钮则不关闭.我这样做的方法是使用response来自对话框的Gtk.Dialog调用信号emit_stop_by_name('response').(如果有人知道这样做的更好方法,那么可能会抢占这个问题的其余部分.)

这在我使用PyGTK时起作用了.我现在正在转向PyGObject ..似乎这种技术只有在我手动连接到响应信号而不是使用时才能工作Gtk.Builder.connect_signals().

但是不要相信我的话.这是我的问题的最小例子:

from gi.repository import Gtk

xml = """<interface>
  <object class="GtkDialog" id="dialog1">
    <signal name="response" handler="on_response"/>
    <child internal-child="vbox">
      <object class="GtkBox" id="dialog-vbox1">
        <child internal-child="action_area">
          <object class="GtkButtonBox" id="dialog-action_area1">
            <child>
              <object class="GtkButton" id="button1">
                <property name="label">Don't Close Dialog</property>
                <property name="visible">True</property>
              </object>
            </child>
            <child>
              <object class="GtkButton" id="button2">
                <property name="label">Close Dialog</property>
                <property name="visible">True</property>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
    <action-widgets>
      <action-widget response="0">button1</action-widget>
      <action-widget response="-6">button2</action-widget>
    </action-widgets>
  </object>
</interface>
"""

def on_button_clicked(widget):
    d = DummyDialog()
    d.dialog1.run()
    d.dialog1.destroy()

class DummyDialog:
    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_string(xml)
        self.dialog1 = self.builder.get_object('dialog1')
        self.builder.connect_signals(self)

    def on_response(self, widget, response, data=None):
        print 'response:', response
        if response >= 0:
            widget.emit_stop_by_name('response')

w = Gtk.Window()
w.connect('destroy', Gtk.main_quit)
b = Gtk.Button('Open Dialog')
b.connect('clicked', on_button_clicked)
w.add(b)

w.show_all()

Gtk.main()
Run Code Online (Sandbox Code Playgroud)

当你运行它时,你会得到一个带有单个按钮的窗口.单击该按钮时,会弹出一个对话框,其中包含两个按钮,一个标记为"不关闭对话框",另一个标记为"关闭对话框".运行上面的代码时,两个按钮都会关闭对话框.

但是,如果您从使用更改为Gtk.Builder.connect_signals()通过替换手动连接信号

        self.builder.connect_signals(self)
Run Code Online (Sandbox Code Playgroud)

        self.dialog1.connect('response', self.on_response)
Run Code Online (Sandbox Code Playgroud)

然后它按设计开始工作("不关闭对话框"按钮不关闭对话框).

在这种情况下,这两行不应该在功能上完全相同吗?有没有办法弄清楚这两种情况之间有什么不同?

我可以告诉两种情况下信号仍然连接,因为文本仍然打印到CLI DummyDialog.on_response.但是widget.emit_stop_by_name('response')当我使用GtkBuilder时,它似乎停止工作.

更令人费解的是,如果你把这个确切的代码和PyGTK的运行(其他城市from gi.repository import Gtkimport gtk as Gtk),那么它(使用正常工作两个场景self.builder.connect_signals(self)self.dialog1.connect('response', self.on_response)).

Tim*_*imo 2

我会做得有点不同。删除dialog1.destroy()按钮中单击的回调并将回调更改on_response为:

    def on_response(self, widget, response, data=None):
        print 'response:', response
        if response < 0:
            self.dialog1.destroy()
Run Code Online (Sandbox Code Playgroud)