Pregunta

Quiero hacer un programa PyQt4 que soporta plug-ins. Básicamente quiero que el usuario sea capaz de escribir subclases QWidget en PyQt4 y añadir / eliminar desde la ventana principal de la aplicación a través de una interfaz gráfica de usuario. ¿Cómo iba a hacer eso, especialmente el mecanismo de plugin?

¿Fue útil?

Solución

En primer lugar, utilizar un QFileDialog o más convenientemente la función estática QFileDialog.getOpenFileName para dejar que el usuario elegir el archivo .py quieren "enchufe en" su interfaz gráfica de usuario.

A continuación, si desea permitir la importación el plugin de en cualquier lugar en el disco (en oposición a, desde directorios específicos añadido previamente a su sys.path, por ejemplo, a través de la variable de entorno PYTHONPATH), puede " hacerlo bien"(una cantidad no despreciable de trabajo), a través de la imp módulo en la biblioteca estándar de Python), o puede "cortar las esquinas" de la siguiente manera (suponiendo filepath es el QString con la ruta de acceso al archivo, y que está utilizando un sistema de ficheros / plataforma con nombres de archivo Unicode nativa - de lo contrario tendrá que añadir lo .encode su plataforma y sistema de archivos requieren) ...:

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)

Esto no es apta para subprocesos, ya que puede tener un efecto adverso sobre sys.path, por lo que me ha dicho que es "tomar atajos" ... pero entonces, por lo que las importaciones compatibles con el proceso (e importaciones "limpios" de "en cualquier parte ") es realmente el trabajo duro (probablemente vale la pena una pregunta por separado si es necesario, ya que realmente no tiene mucho que ver con la esencia de éste, o PyQt, etc.).

Una vez que tienen el objeto de módulo (el resultado de importfrom arriba), sugiero:

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)]

Esto devuelve una lista con todos el widget clases (si lo hay) definido (en el nivel superior) en amodule módulo.

Lo que se quiere hacer a continuación es de usted, por supuesto. Tal vez usted quiere dar algún tipo de mensaje de error si la lista está vacía (o también si tiene más de un artículo? O de lo contrario ¿cómo decidir qué widget de clase que se utiliza?) O instantiate demás de la clase Widget (¿cuántas veces? ¿a qué coordenadas y así sucesivamente -. preguntas sólo puede responder) y mostrar los resultantes Widget (s) en el punto apropiado (s) en la ventana

Otros consejos

tiene un directorio de los plugins, definir una interfaz para los plugins, y caminar el directorio de importarlos.

Nunca he hecho esto en Python, pero en C de la manera que lo hice fue para definir un número de funciones que el plugin necesario para poner en práctica. Los elementos claves básicas que son necesarias es el nombre de las cosas en el plug-in (de modo que pueda verlas en su interfaz de usuario para que el usuario puede crear instancias de ellos) y una fábrica para crear realmente las cosas. Supongo que en Python que sería bastante trivial para simplemente hacer los dict como uno que puede volver desde el módulo.

por ejemplo. declaran que todos los plugins deben autor una función llamada GetPluginInfo () que devuelve un diccionario del nombre:. asignaciones de clase

En realidad, ahora que lo pienso que probablemente podría simplemente importar el archivo y la mirada para las clases que son subclases de todo lo que te importa y no requiere ser implementado cualquier API explícita. No he hecho mucho de eso, pero básicamente le gustaría caminar dir del módulo () y prueba para ver si cada cosa es una subclase de QWidget (por ejemplo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top