Domanda

Domanda abbastanza semplice. L'ho visto menzionato in molti punti che l'uso di proprietà su una classe di vecchio stile non dovrebbe funzionare, ma apparentemente le classi Qt (attraverso PyQt4) non sono di nuovo stile e ci sono proprietà su alcune di esse nel codice I sto lavorando con (e per quanto ne so il codice non mostra alcun tipo di problema)

Mi sono imbattuto in una funzione pyqtProperty, ma non riesco a trovare alcuna documentazione al riguardo. Sarebbe una buona alternativa in questo caso?

È stato utile?

Soluzione

La proprietà

funziona perché QObject ha una metaclasse che si prende cura di loro. Prova questa piccola variazione sul codice di @ 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

eseguendo questo emette:

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

vedi la differenza? Nella classe che è davvero una classe legacy (vecchio tipo), quella creata la seconda volta, la metaclasse è classobj (che NON è una sottoclasse di tipo) e le proprietà non funzionano correttamente (assegnando xx ignora la proprietà e successivamente ottenere xx non vede più la proprietà). Ma nel primo caso, il caso Qt, esiste una metaclasse diversa, ed è una sottoclasse di tipo (quindi non è proprio corretto dire che la classe "non è di nuovo stile"!) E le cose quindi funzionano correttamente .

Altri suggerimenti

Le proprietà dell'ordinamento Python funzionano, secondo la mia esperienza, su oggetti PyQt4. Non so se sono esplicitamente supportati da PyQt4 o no o se ci sono alcuni gotcha nascosti, ma non li ho mai visti comportarsi male. Ecco un esempio usando PyQt 4.4 e 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 è consentire l'utilizzo di Sistema di proprietà di Qt che non è lo stesso di Python. Le proprietà Qt sono introspettibili all'interno delle classi C ++ di Qt (che non sono le proprietà Python non elaborate) e sono utilizzate da Qt per cose come Qt Designer editor di moduli e Qt Creator IDE. Consentono molto il tipo di introspezione dello stato runtime presente in Python e mancante in C ++. In generale Qt fornisce alcune funzionalità dei linguaggi dinamici in C ++, e questa non è l'unica area in cui PyQt fornisce più di un modo per fare la stessa cosa (considerare anche stringhe, dizionari, I / O di file e così via). Con la maggior parte di queste scelte, il consiglio principale che ho è di scegliere da una parte o dall'altra e attenerci, solo per evitare la possibilità di una spiacevole incompatibilità. Tendo a preferire la versione di Python rispetto alla versione di Qt perché Python è più centrale nel mio lavoro rispetto a Qt. Se hai intenzione di prendere in considerazione il porting di qualcosa da PyQt a C ++ Qt, allora potresti preferire la versione Qt di una funzionalità rispetto a quella di Python.

Almeno in PyQt4.5, le classi Qt SONO certamente nuovi oggetti di stile, visti dal loro ordine di risoluzione del metodo:

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'>)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top