2009-08-04 48 views
5

很簡單的問題。我曾經在很多地方看到過,在舊式類中使用屬​​性不應該起作用,但顯然Qt類(通過PyQt4)不是新式的,並且在代碼I中有一些屬性(和據我所知代碼沒有顯示任何問題)對舊式python類使用屬性會導致問題

我沒有運行pyqtProperty函數,但我似乎無法找到任何有關它的文檔。在這種情況下它會是一個好的選擇嗎?

回答

4

屬性工作,因爲QObject有一個元類來照顧他們。一同見證@夸克代碼這個小變化...:

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 

運行此發出:

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 

看到區別?在類是一個傳統(舊類)的類中,第二個類是元類,元類是classobj(它不是類型的子類)並且屬性不起作用(分配x.x繞過屬性,並且在即x.x不會再看到該屬性)。但在第一種情況下,Qt的情況下,有一個不同的元類,它是一個類型的子類(所以說這個類「不是新風格」是不正確的!),因此事情正常工作。

3

根據我的經驗,Python排序工作的屬性在PyQt4對象上很好。我不知道他們是否被PyQt4明確支持,或者是否有一些隱藏的陷阱,但我從來沒有看到他們錯誤。下面是使用的PyQt 4.4和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是允許使用Qt's property system這是不一樣的Python的。 Qt的屬性在Qt的C++類(不是原始的Python屬性)中是內省的,並且被Qt用於諸如它們的Qt Designer表單編輯器和Qt Creator IDE之類的東西。他們允許很多類似運行時的內省狀態,你已經在Python中並且錯過了C++。總的來說,Qt爲C++提供了動態語言的一些特性,並且這不是PyQt提供多種方式來做同樣事情(考慮字符串,字典,文件I/O等等)的唯一區域。在大多數選擇中,我所提出的主要建議只是選擇一方或另一方並堅持使用,以避免出現不愉快的不兼容性。我傾向於選擇Python版本而不是Qt版本,因爲Python對我的工作來說比Qt更重要。如果您打算考慮將任何從PyQt移植回C++ Qt,那麼您可能更喜歡Qt版本的Python特性。

1

至少在PyQt4.5,Qt類肯定是新的樣式對象,從他們的方法解析順序看出:

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

奇怪,也許我們正在使用來檢查代碼的工具是理解錯了... – 2009-08-05 15:40:06

相關問題