index.lxp@lxpwrap=x1149_252ehtm.htm

来自「GUI Programming with Python」· HTM 代码 · 共 470 行

HTM
470
字号
    <table border="0" cellspacing="0" cellpadding="3" width="100%"><tr><td>    <div align="center" id="bldcontent">      <a href="../default.htm"><img src="../images/opendocs.png" width="63" height="76" border="0"></a>      <br>      <div class="symbol">Your OpenSource Publisher&#153;</div>    </div>      </td></tr></table>    <div align="center" class="author">      	<a href="../products.lxp">Products</a>	&nbsp;|&nbsp;	<a href="../wheretobuy.lxp">Where to buy</a>	&nbsp;|&nbsp;	<a href="../bookstore.lxp">Retailers</a>	&nbsp;|&nbsp;	<a href="../faq.lxp">FAQ</a>	&nbsp;|&nbsp;        <a href="../writeforus.lxp">Write for Us.</a>        &nbsp;|&nbsp;        <a href="#contact">Contact Us.</a>  </div>    <table border="0" cellspacing="3" cellpadding="0" width="100%"><tr><td width="100%">      <div class="content">        <table border="0" cellspacing="2" cellpadding="0" width="100%"><tr><td width="100%">          <div align="center"><H4 CLASS="AUTHOR"><A NAME="AEN5">Boudewijn Rempt</A><br><a href="../../https@secure.linuxports.com/opendocs/default.htm"><img src=odpyqt125.png></a><br>ISBN: 0-97003300-4-4<br><a href="../../https@secure.linuxports.com/opendocs/default.htm">Available from bookstores everywhere or you can order it here.</a><p>You can download the source files for the book <a href="pyqtsrc.tgz">(code / eps) here.</a><hr></div>                    <HTML><HEAD><TITLE>      A better Hello World    </TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.72"><LINKREL="HOME"TITLE="GUI Programming with Python: QT Edition"HREF="book1.htm"><LINKREL="UP"TITLE="Qt Concepts"HREF="c1036.htm"><LINKREL="PREVIOUS"TITLE="      As simple as they come    "HREF="x1067.htm"><LINKREL="NEXT"TITLE="Designing forms"HREF="x1214.htm"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GUI Programming with Python: QT Edition</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><A accesskey="P" href="index.lxp@lxpwrap=x1067_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 6. Qt Concepts</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x1214_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">A better Hello World</A></H1><P>Of course, you will never write a script      like the previous one in earnest. While it works, it doesn't      even show the correct way of setting up a PyQt application. A      far superior structure is as follows:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 6-2. hello2.py &#8212; a better hello world</B></P><PRECLASS="PROGRAMLISTING">import sysfrom qt import *class HelloButton(QPushButton):    def __init__(self, *args):        apply(QPushButton.__init__, (self,) + args)        self.setText("Hello World")class HelloWindow(QMainWindow):    def __init__(self, *args):        apply(QMainWindow.__init__, (self,) + args)        self.button=HelloButton(self)        self.setCentralWidget(self.button)def main(args):    app=QApplication(args)    win=HelloWindow()    win.show()    app.connect(app, SIGNAL("lastWindowClosed()"),                app, SLOT("quit()"))    app.exec_loop()if __name__=="__main__":    main(sys.argv)      </PRE></DIV><P>This is more like it! While still boring      and trivial, this small program shows several important aspects      of programming with Python and Qt: the subclassing of Qt classes      in Python, the use of windows and widgets, and the use of      signals and slots.</P><P>In most PyQt applications you will create a      custom main window class, based on QMainWindow, and at least one      custom main view widget, based on any Qt widget &#8212; it could      be a listview, an editor window or a canvas, or, as in this      case, a simple button. Although PyQt allows you to subclass      almost any Qt class, you can't base a Python class on more than      one Qt class at a time.</P><P>That is, multiple inheritance of Qt classes      is not supported. This is seldom (if ever) a problem&#8212;try      to imagine what a widget that looks like a checkbox and a      radiobutton at the same time. Using two widgets in one custom      widgets is another matter, called delegation, and is fully      supported.</P><P>In this script we have subclassed      <TTCLASS="CLASSNAME">QMainWindow</TT> to create a custom window      that contains a pushbutton as its central widget. Almost always,      a window will have the usual frills around the borders &#8212;      menus, toolbars and statusbars. This is what QMainWindow is      designed for. We didn't define any menu items, so the window is      still a bit bare.</P><P>The central part of a window&#8212;the      letterbox, so to speak&#8212;is where the application-specific      functionality appears. This is, of course, our button.      <TTCLASS="CLASSNAME">QMainWindow</TT> manages the resizing of its      central widget automatically, as you might have noticed when      dragging the borders of the window. Also, note the difference in      geometry between this version of Hello World and the previous      one: this is caused by the automatic layout handling that      <TTCLASS="CLASSNAME">QMainWindow</TT> provides.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>A better hello world</P></DIV></P></DIV><P>You set the central part of the window with the      setCentralWidget() method:</P><PRECLASS="PROGRAMLISTING">self.setCentralWidget(self.button)    </PRE><P>An application can have zero, one, or more      windows &#8212; and an application shouldn't close down until      the last window is closed. <TTCLASS="CLASSNAME">QApplication</TT>      keeps count of the number of windows still open and will try to      notify the world when the last one is closed. This is done      through the signals/slots system. While this system will be      discussed in depth in a later chapter, it's sufficiently      important to warrant some consideration here.</P><P>Basically, objects can register an interest in each other,      and when something interesting happens, all interested objects      are notified. In this case, the QApplication object wants to      know when the last window is closed, so it can quit.</P><PRECLASS="PROGRAMLISTING">app.connect(app, SIGNAL("lastWindowClosed()"),            app, SLOT("quit()"))    </PRE><P>Let's analyze this line: the      <TTCLASS="VARNAME">app</TT> object makes a connection between a      signal <TTCLASS="FUNCTION">lastWindowClosed()</TT> (which is sent by      the application object itself), and its own      <TTCLASS="FUNCTION">quit()</TT> function. Using signals and slots      from Python is extremely convenient, both for gui work and in      more abstract situations where a decoupling between objects is      desirable.</P><P>Another example of using signals and slots is in the        following rewrite of the HelloWindow class:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 6-3. fragment from hello3.py</B></P><PRECLASS="PROGRAMLISTING">...class HelloWindow(QMainWindow):    def __init__(self, *args):        apply(QMainWindow.__init__, (self,) + args)        self.button=HelloButton(self)        self.setCentralWidget(self.button)        self.connect(self.button, SIGNAL("clicked()"),                     self, SLOT("close()"))      </PRE></DIV><P>We have added a line where the      <TTCLASS="FUNCTION">clicked()</TT> signal, which is emitted by the      <TTCLASS="CLASSNAME">QPushButton</TT> when it is clicked, is      connected to the <TTCLASS="FUNCTION">close()</TT> slot of the      <TTCLASS="CLASSNAME">HelloWindow</TT> class. Since      <TTCLASS="CLASSNAME">HelloWindow</TT> inherits      <TTCLASS="CLASSNAME">QMainWindow</TT>, it also inherits all its      slot functions.</P><P>Now, if you click on the button, the      window closes&#8212;and we have our first interactive PyQt      application!</P><P>An interesting exercise is to create more      than one window by rewriting the main function:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 6-4. Fragment from hello5.py</B></P><PRECLASS="PROGRAMLISTING">...def main(args):    app=QApplication(args)    winlist=[]    for i in range(10):        win=HelloWindow()        win.show()        winlist.append(win)    app.connect(app, SIGNAL("lastWindowClosed()"),                app, SLOT("quit()"))    app.exec_loop()...      </PRE></DIV><P>If you run this version of the script, ten windows will      rapidly pop up on your desktop. You can close each window by      pressing either the button or using the window controls &#8212;      the application will only stop when the last one is      closed.</P><P>Try commenting out the line      <TTCLASS="LITERAL">winlist.append(win)</TT>:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 6-5. Fragment from hello4.py</B></P><PRECLASS="PROGRAMLISTING">...def main(args):    app=QApplication(args)    winlist=[]    for i in range(10):        win=HelloWindow()        win.show()        #winlist.append(win)    app.connect(app, SIGNAL("lastWindowClosed()"),                app, SLOT("quit()"))    app.exec_loop()...      </PRE></DIV><P>and see what happens...</P><P>This is one of the interesting features in      Python: in contrast to C++, Python has a garbage collector.      (Actually, you can choose between a garbage collector and a      reference counter, but I don't want to get      <SPAN><ICLASS="EMPHASIS">that</I></SPAN> technical yet). This virtual      garbage-man will remove unreferenced objects as soon as      possible. That means that any object that doesn't have a Python      variable name associated with it will disappear. (Unless the      object is the child of a <TTCLASS="CLASSNAME">QObject</TT>; see      <A href="index.lxp@lxpwrap=c2341_252ehtm.htm">Chapter 9</A> for all the details). If you were to try      this trick in C++, keeping references would make no difference,      as C++ does not delete unused objects for you, which can easily      lead to nasty memory leaks.</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=x1067_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=x1214_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">As simple as they come</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c1036_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Designing forms</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

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