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

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?

5
Cole Anagnost 5 ago. 2009 a las 03:14

3 respuestas

La mejor respuesta

La propiedad funciona porque QObject tiene una metaclase que se encarga 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

Ejecutando esto 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 (tipo antiguo), la que se realizó por segunda vez, la metaclase es classobj (que NO ES una subclase de tipo) y las propiedades no funcionan correctamente (asignando {{X1 }} omite la propiedad, y después de eso obtener x.x ya no ve la propiedad). Pero en el primer caso, el caso Qt, hay una metaclase diferente, y ES una subclase de tipo (¡así que no es realmente correcto decir que la clase "no es de estilo nuevo"!), Y las cosas, por lo tanto, funcionan correctamente.

4
Alex Martelli 5 ago. 2009 a las 02:04

Las propiedades del tipo Python funcionan, en mi experiencia, muy bien en los objetos PyQt4. No sé si PyQt4 los admite explícitamente o no, o si hay algunos trucos ocultos, pero nunca los he visto portarse mal. Aquí hay 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 sistema de propiedad de Qt que no es el igual que el de Python. Las propiedades de Qt son introspectables desde las clases de C ++ de Qt (que no son las propiedades de Python sin procesar), y Qt las utiliza para cosas como su editor de formularios Qt Designer, y Qt Creator IDE. Permiten gran parte del tipo de introspección del estado run-time que tienes en Python y fallas 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 en la que PyQt proporciona más de una forma de hacer lo mismo (considere también cadenas, diccionarios, E / S de archivos, etc.). Con la mayoría de esas opciones, el principal consejo que tengo es elegir un lado u otro y mantenerlo, solo para evitar la posibilidad de alguna incompatibilidad desagradable. Tiendo a preferir la versión de Python sobre la versión de Qt porque Python es más esencial para mi trabajo que Qt. Si iba a considerar la posibilidad de transferir cualquier cosa, desde PyQt a C ++ Qt, entonces podría preferir la versión Qt de una característica sobre la de Python.

3
ekhumoro 20 ene. 2017 a las 20:34

Al menos en PyQt4.5, las clases Qt ciertamente SON nuevos objetos de estilo, como se ve en su orden de resolución de método:

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'>)
1
Nicolas Lefebvre 5 ago. 2009 a las 09:46