2017-03-09 5 views
1

J'écris la vue de préférence une extension de shell GNOME et un problème de face lors de l'utilisation de la fonction imports.lang pour écrire l'application de manière orientée objet.Comment vérifier qu'une classe Gjs a déjà été définie?

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

Ouverture de la fenêtre de préférence la première fois fonctionne, mais les suivantes jeter l'erreur suivante: Error: Type name Gjs_MyWindow is already registered. Lors de la fermeture de la fenêtre pour la première fois, je reçois cette erreur: TypeError: prefsModule.init is not a function.

Le code suivant plus impératif fonctionne:

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

D'après les erreurs lancées, je suppose que la classe est en cours de redéfinition. Comment puis-je éviter la redéfinition et recevoir la classe définie autrement? (Y a-t-il des documents auxquels je peux me référer?)

Répondre

1

On dirait que la bonne réponse est 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.

Donc, ne pas étendre les GTypes. Au lieu de cela, utilisez le "modèle de délégué", qui ressemble à cela.

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

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

Cela dit, si vous avez un regard sur les extensions installées sur votre système et de faire quelque chose comme grep -rn 'Extends: Gtk' /usr/share/gnome-shell/extensions/, vous verrez que certaines extensions étendent encore GTypes, et il ne provoque aucune erreur. Mais vous remarquerez que ce n'est jamais fait dans le fichier extension.js ...

Ne demandez pas plus de détails ici, c'est tout ce que je sais aujourd'hui!

0

Si vous voulez un bon aperçu des classes GObject/Gtk dans GJS, consultez testGObjectClass.js et testGtk.js (ce répertoire est en fait en or).

S'il s'agit de prefs.js, vous avez besoin d'une fonction appelée buildPrefsWidget() qui doit renvoyer une instance de widget à ajouter à la fenêtre, et non une instance de Gtk.Window. Dans le cas contraire, vous devez définir votre classe:

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

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

     ... 
    } 
}); 

Puis, après défini, créez une instance et l'utiliser:

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