2009-08-04 9 views
5

Pregunta bastante simple. Lo he visto mencionado en muchos lugares que el uso de propiedades en una clase antigua no debería funcionar, pero aparentemente las clases Qt (a través de PyQt4) no son de estilo nuevo y hay algunas propiedades en algunas de ellas en el código I Estoy trabajando con (y por lo que sé que el código no muestra ningún tipo de problema)El uso de propiedades en una clase python antigua causa problemas

Me encontré con una función pyqtProperty, pero parece que no puedo encontrar ninguna documentación al respecto. ¿Sería una buena alternativa en este caso?

Respuesta

4

La propiedad funciona porque QObject tiene una metaclase que se ocupa de ellos. Sea testigo de esta pequeña variación en el código de @ quark ...:

from PyQt4.QtCore import QObject 

def makec(base): 
    class X(base): 
     def __init__(self): 
      self.__x = 10 
     def get_x(self): 
      print 'getting', 
      return self.__x 
     def set_x(self, x): 
      print 'setting', x 
      self.__x = x 
     x = property(get_x, set_x) 

    print 'made class of mcl', type(X), issubclass(type(X), type) 
    return X 

class old: pass 
for base in (QObject, old): 
    X = makec(base) 
    x = X() 
    print x.x # Should be 10 
    x.x = 30 
    print x.x # Should be 30 

ejecutar este emite:

made class of mcl <type 'PyQt4.QtCore.pyqtWrapperType'> True 
getting 10 
setting 30 
getting 30 
made class of mcl <type 'classobj'> False 
getting 10 
30 

ver la diferencia? En la clase que es realmente una clase heredada (antigua), la que se creó por segunda vez, la metaclase es classobj (que NO ES una subclase de tipo) y las propiedades no funcionan bien (la asignación de x.x omite la propiedad y luego que al obtener x.x ya no ve la propiedad tampoco). Pero en el primer caso, el caso Qt, hay una metaclase diferente, y ES una subclase de tipo (por lo que no es correcto decir que la clase "no es de estilo nuevo") y, por lo tanto, las cosas SI funcionan correctamente.

3

Las propiedades de la clase de Python funcionan, en mi experiencia, muy bien en objetos PyQt4. No sé si están respaldados explícitamente por PyQt4 o no, o si hay algunos errores ocultos, pero nunca los he visto portarse mal. Aquí está un ejemplo usando PyQt 4.4 y Python 2.5:

from PyQt4.QtCore import QObject 

class X(QObject): 

    def __init__(self): 
     self.__x = 10 

    def get_x(self): 
     return self.__x 

    def set_x(self, x): 
     self.__x = x 

    x = property(get_x, set_x) 

x = X() 
print x.x # Should be 10 
x.x = 30 
print x.x # Should be 30 

pyqtProperty es permitir el uso de Qt's property system que no es el mismo que Python de. Las propiedades de Qt son introspectivas dentro de las clases de C++ de Qt (las propiedades de Python sin procesar no lo son), y Qt las usa para cosas como su editor de formularios Qt Designer y Qt Creator IDE. Permiten mucho del tipo de introspección de en tiempo de ejecución que usted tiene en Python y falla en C++. En general, Qt proporciona algunas de las características de los lenguajes dinámicos a C++, y esta no es la única área donde PyQt proporciona más de una forma de hacer lo mismo (considere también cadenas, diccionarios, archivos de E/S, etc.). Con la mayoría de esas opciones, el principal consejo que tengo es simplemente escoger uno u otro lado y atenerme a él, solo para evitar la posibilidad de una incompatibilidad desagradable. Tiendo a preferir la versión de Python sobre la versión de Qt porque Python es más importante para mi trabajo que Qt. Si piensa volver a portar cualquier cosa, desde PyQt a C++ Qt, entonces puede que prefiera la versión Qt de una función en lugar de Python.

1

Al menos en PyQt4.5, clases de Qt duda son nuevos objetos de estilo, como se ve desde su orden de resolución de métodos:

from PyQt4 import QtGui 
print QtGui.QWidget.__mro__ 
(<class 'PyQt4.QtGui.QWidget'>, <class 'PyQt4.QtCore.QObject'>, <type 'sip.wrapper'>, <class 'PyQt4.QtGui.QPaintDevice'>, <type 'sip.simplewrapper'>, <type 'object'>) 
+0

extraño, tal vez la herramienta que estamos utilizando para comprobar el código está entendiendo mal ... –

+0

De acuerdo con los documentos de PyQt "En las versiones de PyQt anteriores a la v4.5, existían restricciones sobre el uso de super con las clases de PyQt. Estas restricciones ya no se aplican con v4.5 y posterior". Si está utilizando una versión anterior a la 4.5, ¿tal vez ese sea el problema? Si no, ¡estoy perdido! (fuente: http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#super-and-pyqt-classes) –

+0

Corrí la misma prueba en la mía y me dice lo mismo , Voy a seguir adelante y asumir que la herramienta que estamos utilizando es simplemente confusa. Gracias –

Cuestiones relacionadas