Как мне проверить, что класс Gjs уже определен?

Я пишу предпочтительный вид расширения оболочки GNOME и сталкиваюсь с проблемами при использовании функции imports.lang для написания приложения в объектно-ориентированной манере.

const Gtk = imports.gi.Gtk
const Lang = imports.lang
Gtk.init(null)
const MyWindow = new Lang.Class({...})

Открытие окна предпочтений в первый раз работает, но последующие выдают следующую ошибку: Error: Type name Gjs_MyWindow is already registered. При первом закрытии окна выдает ошибку: TypeError: prefsModule.init is not a function.

Работает следующий более императивный код:

const Gtk = imports.gi.Gtk
Gtk.init(null)
const window = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL })

Основываясь на выданных ошибках, я предполагаю, что класс переопределяется. Как я могу избежать переопределения и получить определенный класс в противном случае? (Есть ли какие-нибудь документы, на которые я могу сослаться?)


person kiyui    schedule 09.03.2017    source источник


Ответы (2)


Похоже, правильный ответ содержится в этом обсуждении.

Если вы расширяете класс GObject (что-нибудь из St, Clutter, Gtk и т. Д.), Вы регистрируете новый GType, а это невозможно для расширений.

...

Расширения - это динамические модули, их можно загружать и выгружать, но это совершенно невозможно для GTypes.

Итак, не расширяйте GTypes. Вместо этого используйте шаблон делегата, который выглядит так.

const Class = new Lang.Class({
  Name: "Class",

  _init: function() {
    this.actor = new St.Button();
  }
)};

При этом, если вы посмотрите на расширения, установленные в вашей системе, и сделаете что-то вроде grep -rn 'Extends: Gtk' /usr/share/gnome-shell/extensions/, вы увидите, что некоторые расширения все еще расширяют GTypes, и это не вызывает никаких ошибок. Но вы заметите, что это никогда не делается в extension.js файле ...

Не спрашивайте здесь подробностей, это все, что я знаю на сегодняшний день!

person elboulangero    schedule 17.11.2017

Если вам нужно подробное изложение классов GObject / Gtk в GJS, проверьте testGObjectClass.js и testGtk .js (на самом деле весь каталог просто золотой).

Если это для prefs.js, вам нужна функция с именем buildPrefsWidget(), которая должна возвращать экземпляр виджета, который нужно добавить в окно, а не экземпляр Gtk.Window. В противном случае вы должны определить свой класс:

const MyWindow = new Lang.Class({
    Name: "MyWindow",
    Extends: Gtk.Window,

    _init: function (params) {
        this.parent(params);

        ...
    }
});

Затем после определения создайте экземпляр и используйте его:

Gtk.init(null);
let window = new MyWindow({ type: Gtk.WindowType.TOPLEVEL });
window.show_all();
Gtk.main();
person andy.holmes    schedule 26.06.2017