index.lxp@lxpwrap=x2765_252ehtm.htm
来自「GUI Programming with Python」· HTM 代码 · 共 765 行 · 第 1/2 页
HTM
765 行
<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™</div> </div> </td></tr></table> <div align="center" class="author"> <a href="../products.lxp">Products</a> | <a href="../wheretobuy.lxp">Where to buy</a> | <a href="../bookstore.lxp">Retailers</a> | <a href="../faq.lxp">FAQ</a> | <a href="../writeforus.lxp">Write for Us.</a> | <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>Widget foundations: QWidget</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 Class Hierarchy"HREF="c2591.htm"><LINKREL="PREVIOUS"TITLE="Application classes"HREF="x2693.htm"><LINKREL="NEXT"TITLE="Basic widgets"HREF="x2976.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=x2693_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 10. Qt Class Hierarchy</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x2976_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">Widget foundations: QWidget</A></H1><P>All Qt widgets and all visible components are founded upon <TTCLASS="CLASSNAME">QWidget</TT> — this monster class provides all event handling, all style handling and countless other chores. To help with the handling of these tasks, there are other classes, such as <TTCLASS="CLASSNAME">QPixmap</TT>, <TTCLASS="CLASSNAME">QColor</TT>, <TTCLASS="CLASSNAME">QFont</TT> or <TTCLASS="CLASSNAME">QStyle</TT>.</P><P><TTCLASS="CLASSNAME">QWidget</TT> can be useful to build your own widgets on, provided you are prepared to do all your own painting — this includes buffering in case your widget gets a <TTCLASS="FUNCTION">paintEvent</TT> call! Consider the next snippet, which is an extension of the event1.py example:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 10-4. event2.py - using QWidget to create a custom, double-buffered drawing widget.</B></P><PRECLASS="PROGRAMLISTING">## event2.py#from qt import *import sysclass Painting(QWidget): def __init__(self, *args): apply(QWidget.__init__,(self, ) + args) self.buffer = QPixmap() def paintEvent(self, ev): # blit the pixmap bitBlt(self, 0, 0, self.buffer) def mouseMoveEvent(self, ev): self.p = QPainter() self.p.begin(self.buffer) self.p.drawLine(self.currentPos, ev.pos()) self.currentPos=QPoint(ev.pos()) self.p.flush() self.p.end() bitBlt(self, 0, 0, self.buffer) def mousePressEvent(self, ev): self.p = QPainter() self.p.begin(self.buffer) self.p.drawPoint(ev.pos()) self.currentPos=QPoint(ev.pos()) self.p.flush() self.p.end() bitBlt(self, 0, 0, self.buffer) def resizeEvent(self, ev): tmp = QPixmap(self.buffer.size()) bitBlt(tmp, 0, 0, self.buffer) self.buffer.resize(ev.size()) self.buffer.fill() bitBlt(self.buffer, 0, 0, tmp) class MainWindow(QMainWindow): def __init__(self, *args): apply(QMainWindow.__init__, (self,) + args) self.painting=Painting(self) self.setCentralWidget(self.painting) 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><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>event2.py - persistent drawing</P></DIV></P></DIV><P>By drawing to <TTCLASS="CLASSNAME">QPixmap</TT> instead of to <TTCLASS="CLASSNAME">QWidget</TT>, and <SPAN><ICLASS="EMPHASIS">blitting</I></SPAN> the contents of that pixmap to the widget, the drawing will be kept. Note also how much smoother the drawing feels, despite the extra work the script has to do. This technique is called double buffering, and is the alpha and the omega of graphics programming. Of course, there's still a small problem with resizing... In fact, if you want to build your own widgets from the ground up using QWidget, you're always in for more work than you reckoned with.</P><DIVCLASS="SECT2"><H2CLASS="SECT2">QColor</A></H2><P>The <TTCLASS="CLASSNAME">QColor</TT> class represents any color that can be used in PyQt. You can instantiate a new color either by using an RGB (red-green-blue) value, an HSV (hue-saturation-value) value, or a name. The X11 system used on Unix provides a database full of rather poetic color names like ‘Old Lace', ‘Royal Blue' and ‘Peach Puff' —you can use these names instead of hexadecimal numbers. The Windows version of PyQt has a copy of this database, so it's quite portable. If you replace the <TTCLASS="FUNCTION">resizeEvent()</TT> in the event2.py example with the following code, you'll see the effect:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 10-5. snippet from event3.py - a peach puff drawing board</B></P><PRECLASS="PROGRAMLISTING">... def resizeEvent(self, ev): tmp = QPixmap(self.buffer.size()) bitBlt(tmp, 0, 0, self.buffer) self.buffer.resize(ev.size()) self.buffer.fill(QColor("peachpuff")) bitBlt(self.buffer, 0, 0, tmp)... </PRE></DIV><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>event3.py</P></DIV></P></DIV><P>A final note on colors: the way you set the colors of a widget have been changed between Qt2 and Qt3. Where you first used <TTCLASS="FUNCTION">setBackgroundColor()</TT>, you'd now use <TTCLASS="FUNCTION">setEraseColor()</TT>. Yes, there is a logic behind this change of name, but it is very specious, and the change broke almost all my code. The erase color is the color that Qt uses to clear away, or erase, all the pixels that had been painted just before they are painted again in a paint event.</P><P>When you're designing complex widgets, you will want to investigate <TTCLASS="FUNCTION">setBackgroundMode</TT> and the <TTCLASS="VARNAME">BackgroundMode</TT> flags.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2">QPixmap, QBitmap and QImage</A></H2><P>We have already been using a <TTCLASS="CLASSNAME">QPixMap</TT> to double buffer the scribblings in the previous two examples. <TTCLASS="CLASSNAME">QPixmap</TT> is not the only image class PyQt offers: there's also <TTCLASS="CLASSNAME">QBitmap</TT>, which is just like <TTCLASS="CLASSNAME">QPixmap</TT>, but for black and white images only, and <TTCLASS="CLASSNAME">QImage</TT>. Where <TTCLASS="CLASSNAME">QPixmap</TT> and <TTCLASS="CLASSNAME">QBitmap</TT> are optimized for drawing (and then showing on screen or on a printer), <TTCLASS="CLASSNAME">QImage</TT> is optimized for reading and writing (together with the <TT
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?