Почему обработчик события вызывается с разными параметрами при добавлении в Glade и в коде?

Ниже 4 файла:

Случай 1: example1.py с использованием example1.glade.

Случай 2: example2.py с использованием example2.glade.

Чтобы увидеть результат в обоих случаях, шаги одинаковы для каждого случая. Просто нажмите на многострочную метку или на кнопку ссылки после открытия одной из этих программ, и вывод будет показан в терминале.

Скриншот, одинаковый для обоих случаев

Скриншот для обоих случаев

1-й случай

пример1.py

# coding=utf-8

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk


def box_clicked(*args):
    print(args)
    return True


b = Gtk.Builder()
b.add_from_file("example1.glade")
w = b.get_object("window1")
lb = b.get_object("linkButton")
eb = b.get_object("eventbox1")
eb.connect("button-release-event", box_clicked, lb)

w.connect("delete-event", Gtk.main_quit)
w.show_all()
Gtk.main()

пример1.поляна

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkAspectFrame">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label_xalign">0</property>
        <child>
          <object class="GtkEventBox" id="eventbox1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="above_child">True</property>
            <child>
              <object class="GtkBox" id="box1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkLinkButton" id="linkButton">
                    <property name="label" translatable="yes">button</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">True</property>
                    <property name="relief">none</property>
                    <property name="uri">http://www.google.com</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkLabel" id="multilineLabel">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">this
is
a
multiline
label</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

Сигнал и обработчик были связаны вручную из кода.

Пример аргументов, передаваемых обработчику сигнала, напечатанных с помощью print(args):

(<Gtk.EventBox object at 0x02bc4b6c (GtkEventBox at 0x02b9e290)>, <Gdk.EventButt
on object at 0x02bc4c34 (void at 0x02e691c8)>, <Gtk.LinkButton object at 0x02668
914 (GtkLinkButton at 0x02e37120)>)

Красивый принт:

  1. Gtk.EventBox
  2. Gtk.EventButton
  3. Gtk.LinkButton

2-й случай

пример2.py

# coding=utf-8

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk


class Builder(Gtk.Builder):
    def __init__(self):
        Gtk.Builder.__init__(self)
        self.add_from_file("example2.glade")
        self.connect_signals(self)
        self.win = self.get_object("window1")

    def box_clicked(self, *args):
        print(args)
        return True


win = Builder().win
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

пример2.поляна

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkAspectFrame">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label_xalign">0</property>
        <child>
          <object class="GtkEventBox" id="eventbox1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="above_child">True</property>
            <signal name="button-release-event" handler="box_clicked" object="linkButton" swapped="no"/>
            <child>
              <object class="GtkBox" id="box1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkLinkButton" id="linkButton">
                    <property name="label" translatable="yes">button</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="receives_default">True</property>
                    <property name="relief">none</property>
                    <property name="uri">http://www.google.com</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkLabel" id="multilineLabel">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">this
is
a
multiline
label</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

Обработчик событий был подключен к сигналу в Glade.

Пример аргументов, передаваемых обработчику сигнала, напечатанных с помощью print(args):

(<Gtk.LinkButton object at 0x02c68554 (GtkLinkButton at 0x02e96118)>, <Gdk.Event
Button object at 0x02c6b5f4 (void at 0x02d56a60)>)

Красивый принт

  1. Gtk.LinkButton
  2. Gdk.EventButton

Красивое сравнение принтов

Аргументы для 1-го случая:

  1. Gtk.EventBox
  2. Gtk.EventButton
  3. Gtk.LinkButton

Аргументы для 2-го случая:

  1. Gtk.LinkButton
  2. Gdk.EventButton

Я хочу понять причины различий между выходными данными в этих двух случаях.

Я использую Python 2.7.13 и GTK+ 3.22 на MSYS2 в Windows 10. И на MSYS2, и на Windows установлены все доступные обновления.


person silviubogan    schedule 22.08.2017    source источник


Ответы (1)


Второй файл Glade имеет атрибут object для элемента signal, что эквивалентно использованию g_signal_connect_object() вместо g_signal_connect() в C. Он передает данный объект (кнопку ссылки) в качестве первого параметра обработчику сигнала.

person ptomato    schedule 23.08.2017
comment
Как g_signal_connect_object связан с < a href="https://developer.gnome.org/gobject/stable/gobject-Signals.html#g-signal-connect-swapped" rel="nofollow noreferrer">g_signal_connect_swapped? - person silviubogan; 23.08.2017
comment
Он ведет себя аналогично, если вы используете G_CONNECT_SWAPPED в аргументе g_signal_connect_object GConnectFlags. - person José Fonte; 23.08.2017