如何检查 Gjs class 是否已定义?
How do I check that a Gjs class has already been defined?
我正在编写首选项视图 GNOME shell 扩展和使用 imports.lang
函数以面向对象的方式编写应用程序时面临的问题。
const Gtk = imports.gi.Gtk
const Lang = imports.lang
Gtk.init(null)
const MyWindow = new Lang.Class({...})
第一次打开首选项 window 有效,但后续的会抛出以下错误:Error: Type name Gjs_MyWindow is already registered
。第一次关闭 window 时,我收到此错误:TypeError: prefsModule.init is not a function
.
以下命令式代码有效:
const Gtk = imports.gi.Gtk
Gtk.init(null)
const window = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL })
根据抛出的错误,我的猜测是 class 正在被重新定义。否则如何避免重新定义并接收定义的 class ? (有什么文档可以参考吗?)
如果你想在 GJS 中详细了解 GObject/Gtk classes,请查看 testGObjectClass.js and testGtk.js(实际上整个目录都是黄金目录)。
如果这是 prefs.js
,您需要一个名为 buildPrefsWidget()
的函数,它应该 return 一个要添加到 window 的小部件实例,而不是 Gtk.Window实例。否则,您应该定义 class:
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();
看起来正确答案在 this discussion.
中
If you extend a GObject class (anything from St, Clutter, Gtk, etc.), you're registering a new GType, and that's not possible for extensions.
...
Extensions are dynamic modules, and they can be loaded and unloaded - but that's not at all possible for GTypes.
所以,不要扩展 GType。相反,使用看起来像那样的“委托模式”。
const Class = new Lang.Class({
Name: "Class",
_init: function() {
this.actor = new St.Button();
}
)};
也就是说,如果您查看系统上安装的扩展并执行类似 grep -rn 'Extends: Gtk' /usr/share/gnome-shell/extensions/
的操作,您会发现某些扩展仍然扩展 GType,并且不会导致任何错误。但是您会注意到它从未在 extension.js
文件中完成...
不要在这里询问更多细节,这就是我今天所知道的!
我正在编写首选项视图 GNOME shell 扩展和使用 imports.lang
函数以面向对象的方式编写应用程序时面临的问题。
const Gtk = imports.gi.Gtk
const Lang = imports.lang
Gtk.init(null)
const MyWindow = new Lang.Class({...})
第一次打开首选项 window 有效,但后续的会抛出以下错误:Error: Type name Gjs_MyWindow is already registered
。第一次关闭 window 时,我收到此错误:TypeError: prefsModule.init is not a function
.
以下命令式代码有效:
const Gtk = imports.gi.Gtk
Gtk.init(null)
const window = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL })
根据抛出的错误,我的猜测是 class 正在被重新定义。否则如何避免重新定义并接收定义的 class ? (有什么文档可以参考吗?)
如果你想在 GJS 中详细了解 GObject/Gtk classes,请查看 testGObjectClass.js and testGtk.js(实际上整个目录都是黄金目录)。
如果这是 prefs.js
,您需要一个名为 buildPrefsWidget()
的函数,它应该 return 一个要添加到 window 的小部件实例,而不是 Gtk.Window实例。否则,您应该定义 class:
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();
看起来正确答案在 this discussion.
中If you extend a GObject class (anything from St, Clutter, Gtk, etc.), you're registering a new GType, and that's not possible for extensions.
...
Extensions are dynamic modules, and they can be loaded and unloaded - but that's not at all possible for GTypes.
所以,不要扩展 GType。相反,使用看起来像那样的“委托模式”。
const Class = new Lang.Class({
Name: "Class",
_init: function() {
this.actor = new St.Button();
}
)};
也就是说,如果您查看系统上安装的扩展并执行类似 grep -rn 'Extends: Gtk' /usr/share/gnome-shell/extensions/
的操作,您会发现某些扩展仍然扩展 GType,并且不会导致任何错误。但是您会注意到它从未在 extension.js
文件中完成...
不要在这里询问更多细节,这就是我今天所知道的!