⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.lxp@lxpwrap=x2420_252ehtm.htm

📁 GUI Programming with Python
💻 HTM
📖 第 1 页 / 共 2 页
字号:
CLASS="FUNCTION">children</TT> on QObject. Sip      is clever enough to return the Python wrapper object associated with that      instance (rather than the actual C++ object instance).</P><DIVCLASS="EXAMPLE"></A><P><B>Example 9-7. children.py - getting the children from a single        parent</B></P><PRECLASS="PROGRAMLISTING">## children.py#import sysfrom qt import *def printChildren(obj, indent):    children=obj.children()    if children==None:        return    for child in children:        print indent, child.name(), child.__class__        printChildren(child, indent + "  ")class PyPushButton(QPushButton): passclass MainWindow(QMainWindow):    def __init__(self, *args):        apply(QMainWindow.__init__, (self, ) + args)        mainwidget=QWidget(self, "mainwidget")        layout=QVBoxLayout(mainwidget, 2, 2, "layout")        button1=QPushButton("button1", mainwidget, "button1")        button2=PyPushButton("button2", mainwidget, "button2")        layout.addWidget(button1)        layout.addWidget(button2)        self.setCentralWidget(mainwidget)        printChildren(self, "  ")def main(args):    app=QApplication(args)    win=MainWindow()    win.show()    app.connect(app, SIGNAL("lastWindowClosed()")                , app                , SLOT("quit()")                )    app.exec_loop()if __name__=="__main__":        main(sys.argv)        </PRE></DIV><P>Running children.py will give the following output:</P><PRECLASS="SCREEN">boudewijn@maldar:~/doc/opendoc &#62; python children.py   hide-dock qt.QObject   mainwidget qt.QWidget     layout qt.QVBoxLayout     button1 qt.QPushButton     button2 __main__.PyPushButton   unnamed qt.QObject     unnamed qt.QObject     unnamed qt.QObject       unnamed qt.QObject       unnamed qt.QObject     unnamed qt.QObject</PRE><P>What you cannot see here is the parallel structure of      <TTCLASS="CLASSNAME">QLayoutItems</TT> that proxy for the widgets.      For that you need to use the      <TTCLASS="CLASSNAME">QLayoutIterator</TT> that is provided by the      <TTCLASS="FUNCTION">iterator()</TT> method of      <TTCLASS="CLASSNAME">QListViewItem</TT>. Here,      <TTCLASS="FUNCTION">next()</TT>, both returns the next item, and      moves the iterator onwards.</P><DIVCLASS="EXAMPLE"></A><P><B>Example 9-8. Iterating over children</B></P><PRECLASS="PROGRAMLISTING">## children.py#import sysfrom qt import *def printChildren(obj, indent):    iter = obj.iterator()    while iter.current():        print "current:", iter.current()        print "next:", iter.next()class PyPushButton(QPushButton): passclass MainWindow(QMainWindow):    def __init__(self, *args):        apply(QMainWindow.__init__, (self, ) + args)        mainwidget=QWidget(self, "mainwidget")        layout=QVBoxLayout(mainwidget, 2, 2, "layout")        button1=QPushButton("button1", mainwidget, "button1")        button2=PyPushButton("button2", mainwidget, "button2")        button3=PyPushButton("button3", mainwidget, "button3")        layout.addWidget(button1)        layout.addWidget(button2)        layout.addWidget(button3)                self.setCentralWidget(mainwidget)        printChildren(layout, "  ")        def main(args):    app=QApplication(args)    win=MainWindow()    win.show()    app.connect(app, SIGNAL("lastWindowClosed()")                , app                , SLOT("quit()")                )    app.exec_loop()  if __name__=="__main__":        main(sys.argv)      </PRE></DIV><PRECLASS="SCREEN">boud@calcifer:~/doc/pyqt/src/qt2/ch3 &#62; python layoutchildren.pycurrent: &#60;qt.QLayoutItem instance at 0x82ba8b4&#62; next: &#60;qt.QLayoutItem instance at 0x82ba9dc&#62;current: &#60;qt.QLayoutItem instance at 0x82ba9dc&#62; next: &#60;qt.QLayoutItem instance at 0x82baa8c&#62;current: &#60;qt.QLayoutItem instance at 0x82baa8c&#62; next: None    </PRE><P>Finally, let's test the ownership rules of      Qt and Python objects using the interactive Python interpreter.      In the following example, we create an object      <TTCLASS="VARNAME">self.o</TT>, owned by PyQt, and then a child      object is created, not owned by the instance of class      <TTCLASS="CLASSNAME">A</TT>, but as a Qt child of object      <TTCLASS="VARNAME">self.o</TT>. Thus, PyQt owns <TTCLASS="VARNAME">a</TT>      and <TTCLASS="VARNAME">self.o</TT>, and Qt owns      <TTCLASS="VARNAME">child</TT>, and <TTCLASS="VARNAME">child</TT> doesn't      get deleted, even when the Python reference goes out of      scope.</P><PRECLASS="SCREEN">&#62;&#62;&#62; from qt import QObject&#62;&#62;&#62; class A:...     def __init__(self):...             self.o=QObject()...             child = QObject(self.o)... &#62;&#62;&#62; a=A()&#62;&#62;&#62; print a&#60;__main__.A instance at 0x821cdac&#62;&#62;&#62;&#62; print a.o&#60;qt.QObject instance at 0x821ce04&#62;&#62;&#62;&#62; print a.o.children()[&#60;qt.QObject instance at 0x821cf54&#62;]&#62;&#62;&#62;     </PRE><P>On the other hand, the following won't      work, because as soon as the execution flow leaves the      constructor, <TTCLASS="VARNAME">o</TT> is garbage collected, and      <TTCLASS="VARNAME">child</TT>, is then garbage-collected, too, since      it isn't owned by a Qt object, and Python doesn't have a      reference to it anymore, either.</P><PRECLASS="SCREEN"> &#62;&#62;&#62; class B:...        def ___init__(self):...             o=QObject()...             child = QObject(o)... &#62;&#62;&#62; b=B()&#62;&#62;&#62; b.oTraceback (most recent call last):  File "&#60;stdin&#62;", line 1, in ?AttributeError: o    </PRE><P>On the other hand, it isn't necessary to      keep a Python reference to all created objects: as long as the      ultimate parent object is owned by PyQt, everything will go      well:</P><PRECLASS="SCREEN">&#62;&#62;&#62; class C:...        def __init__(self):...             self.o = QObject()...             self.child = QObject(self.o)... &#62;&#62;&#62; c = C()&#62;&#62;&#62; c.o&#60;qt.QObject instance at 0x8263f54&#62;&#62;&#62;&#62; c.o.children()[&#60;qt.QObject instance at 0x821d334&#62;]&#62;&#62;&#62; c.child&#60;qt.QObject instance at 0x821d334&#62;&#62;&#62;&#62; </PRE><P>As you see, it isn't necessary to keep a reference to      <TTCLASS="VARNAME">child</TT>,- because PyQt is the owner of the      first object (because it has no Qt parent but a reference to a      Python object) but Qt is the owner of the second widget (because      it <SPAN><ICLASS="EMPHASIS">does</I></SPAN> have a parent) and so the C++      instance (qt.QObject instance at 0x821d334) is not deleted when      the corresponding Python object goes out of scope.</P><P>What if your Python class were a subclass of      <TTCLASS="CLASSNAME">QObject</TT>?:</P><PRECLASS="SCREEN">&#62;&#62;&#62; class D(QObject):...        def __init__(self):...             QObject.__init__(self)...             o=QObject(self)...             child = QObject(o)... &#62;&#62;&#62; d=D()&#62;&#62;&#62; d.children()[&#60;qt.QObject instance at 0x821d614&#62;]&#62;&#62;&#62; d.children()[0].children()[&#60;qt.QObject instance at 0x821d7c4&#62;]&#62;&#62;&#62;     </PRE><P>As you can see, <TTCLASS="VARNAME">o</TT> doesn't get deleted,      nor <TTCLASS="VARNAME">child</TT> - both are owned by Qt and will be      deleted as soon as object <TTCLASS="VARNAME">d</TT> is deleted. You      can still reach these objects by using the      <TTCLASS="FUNCTION">children()</TT> function      <TTCLASS="CLASSNAME">QObject</TT> provides.</P><P>This layer between Python and Qt is implemented in the      <SPAN><ICLASS="EMPHASIS">sip</I></SPAN> library &#8212; sip not only generates      the wrapper code, but is a library in its own right, containing      functionality for the passing of object references between C++      and Python.</P><P>Sip is also responsible for the reference counting      mechanisms. In most cases, Sip is clever enough to closely      simulate Python behavior for C++ Qt objects. As you saw in the previous example,      contrary to what happens in C++, when you remove the last      reference to a C++ object, it will be automatically deleted by      Sip.</P></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><A accesskey="P" href="index.lxp@lxpwrap=x2393_252ehtm.htm">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="H" href="index.lxp@lxpwrap=book1_252ehtm">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><A accesskey="N" href="index.lxp@lxpwrap=x2540_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Qt objects, Python objects and shadow objects</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c2341_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Other C++ objects</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -