如何检查Gjs类是否已被定义?
我使用imports.lang
函数以面向对象的方式编写应用程序时,正在编写首选项视图以及GNOME外壳扩展和面临的问题。如何检查Gjs类是否已被定义?
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 })
基础上所产生的错误,我的猜测是,该类正在被重新定义。我怎样才能避免重新定义并以其他方式接收定义的类? (有没有我可以参考的文档?)
貌似正确的答案是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.
所以,不要扩展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
文件中完成...
不要问这里的更多细节,这就是我所知道的今天!
如果你想要GJS中的GObject/Gtk类的一个稳固破败,结账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();