Question

Je veux faire un programme PyQt4 qui prend en charge les plugins. Fondamentalement, je veux que l'utilisateur soit capable d'écrire dans les sous-classes QWidget PyQt4 et ajouter / supprimer les de la fenêtre principale de l'application via une interface graphique. Comment puis-je faire, en particulier le mécanisme de plug-in?

Était-ce utile?

La solution

Tout d'abord, utilisez un QFileDialog ou plus commodément la fonction statique QFileDialog.getOpenFileName pour laisser la utilisateur choisir le fichier .py qu'ils veulent « bouchon dans » votre interface graphique.

Ensuite, si vous souhaitez autoriser l'importation du plug-in de sur le disque (par opposition à, de répertoires spécifiques précédemment ajoutés à votre sys.path, par exemple via le PYTHONPATH variable d'environnement), vous pouvez " faire droit »(une quantité de travail non négligeable), via le diablotin module la bibliothèque standard Python), ou vous pouvez « coins coupés » comme suit (en supposant filepath est le QString avec le chemin du fichier et que vous utilisez un système de fichiers / plate-forme avec natif Unicode noms de fichiers - sinon vous devrez ajouter ce .encode votre plate-forme et système de fichiers ont besoin) ...:

import sys, os

def importfrom(filepath):
    ufp = unicode(filepath)
    thedir, thefile = os.path.split(ufp)
    if sys.path[0] != thedir:
      sys.path.insert(0, thedir)
    themodule, theext = os.path.splitext(thefile)
    return __import__(themodule)

Ceci est thread-safe car elle peut avoir un effet secondaire sur sys.path, ce qui est la raison pour laquelle je l'ai dit de « coins de coupe » ... mais, ce qui rend les importations de fil de sécurité (et les importations « propres » de « nulle part « ) est vraiment travail (une autre question probablement utile si vous avez besoin, car il a vraiment pas grand-chose à voir avec l'essentiel de celui-ci, ou PyQt, etc.).

Une fois que vous avez l'objet du module (le résultat de importfrom ci-dessus), je suggère:

from PyQt4 import QtGui 
import inspect

def is_widget(w):
    return inspect.isclass(w) and issubclass(w, QtGui.QWidget)

def all_widget_classes(amodule):
    return [v for n, v in inspect.getmembers(amodule, is_widget)]

Cette fonction renvoie une liste avec tous le widget cours (le cas échéant) défini (au niveau supérieur) dans le module amodule.

Qu'est-ce que vous voulez faire ensuite est à vous, bien sûr. Peut-être que vous voulez donner une sorte de messages d'erreur si la liste est vide (ou peut-être si elle a plus d'un article? Ou bien comment décidez quelle classe widget à utiliser?) Ou bien instancier la classe widget (combien de fois? A quel coordonnées et ainsi de suite -. les questions que vous pouvez répondre) et montrer le widget résultant (s) dans l'endroit approprié (s) sur la fenêtre

Autres conseils

Avoir un répertoire pour les plug-ins, définir une interface pour les plug-ins, et marcher le répertoire de les importer.

Je ne l'ai jamais fait cela en Python, mais en C la façon dont je l'ai fait était de définir un certain nombre de fonctions que le plugin nécessaire pour mettre en œuvre. Les éléments clés de base qui sont nécessaires est le nom des choses dans le plug-in (de sorte que vous pouvez les afficher dans votre interface utilisateur afin que l'utilisateur puisse les instancier) et une usine pour créer réellement les choses. Je suppose en Python, il serait assez trivial de faire exactement ceux que l'un dict que vous pouvez revenir à partir du module.

par exemple. déclarent que tous les plugins doivent auteur d'une fonction appelée GetPluginInfo () qui retourne un dictionnaire de nom:. mappings de classes

En fait, maintenant que je pense à ce sujet, vous pouvez probablement importer le fichier et rechercher des classes qui sont sous-classes de tout ce que vous aimez et ne nécessitent aucune mise en œuvre API explicite. Je ne l'ai pas fait beaucoup de cela, mais essentiellement vous feriez marcher dir du module () et test pour voir si chaque chose est une sous-classe de QWidget (par exemple).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top