2017-03-09 128 views
1

我使用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 }) 

基础上所产生的错误,我的猜测是,该类正在被重新定义。我怎样才能避免重新定义并以其他方式接收定义的类? (有没有我可以参考的文档?)

回答

1

貌似正确的答案是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文件中完成...

不要问这里的更多细节,这就是我所知道的今天!

0

如果你想要GJS中的GObject/Gtk类的一个稳固破败,结账testGObjectClass.jstestGtk.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();