﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-mirguest-随笔分类-Python</title><link>http://www.cppblog.com/mirguest/category/15952.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 16 Feb 2012 03:11:02 GMT</lastBuildDate><pubDate>Thu, 16 Feb 2012 03:11:02 GMT</pubDate><ttl>60</ttl><item><title>[Python][PyQt4]PyQt4 中的俄罗斯方块</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165392.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:18:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165392.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165392.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165392.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165392.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165392.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: PyQt4 中的俄罗斯方块&#182;创建一个电脑游戏是很具挑战性的。迟早程序员想创建一个电脑游戏。事实上，很多人对编程感兴趣，是因为它们玩了游戏，然后想创建自己的游戏。创建一个游戏会提升你的编程技能。俄罗斯方块&#182;俄罗斯方块从创建开始就成为很流行的游戏之一。游戏最开始是由俄罗斯程序员 Alexey Pajitnov 设计和编写的。从那时开始几乎在所有的计算机平台运行。甚至...&nbsp;&nbsp;<a href='http://www.cppblog.com/mirguest/archive/2012/02/12/165392.html'>阅读全文</a><img src ="http://www.cppblog.com/mirguest/aggbug/165392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:18 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]在 PyQt4 中定制组件</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165391.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:17:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165391.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165391.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165391.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165391.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165391.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4">
<h1>在 PyQt4 中定制组件<a class="headerlink" href="#pyqt4" title="Permalink to this headline">&#182;</a></h1>
<p>PyQt4 有丰富的组件。但是不可能提供所有的组件。PyQt4 中仅仅提供最常用的组件，像按钮，文本框，滑块等。如果我们需要特殊的组件，我们必须要自己创建。</p>
<p>自定制组件可以使用工具包画制工具创建。有两种可能，一个程序员可以修改或提升一个已存在的工具，或是从零开始创建。</p>
<div class="section" id="burning-widget">
<h2>Burning widget<a class="headerlink" href="#burning-widget" title="Permalink to this headline">&#182;</a></h2>
<p>这是一个组件，我们可以在 Nero，K3B 或其它 CD/DVD 刻录软件。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we create a custom widget.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Communicate</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">QObject</span><span class="p">):</span>
    <span class="n">updateBW</span> <span class="o">=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">pyqtSignal</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">BurningWidget</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">BurningWidget</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setMinimumSize</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="mi">75</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">num</span> <span class="o">=</span> <span class="p">[</span><span class="mi">75</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span> <span class="mi">225</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">375</span><span class="p">,</span> <span class="mi">450</span><span class="p">,</span> <span class="mi">525</span><span class="p">,</span> <span class="mi">600</span><span class="p">,</span> <span class="mi">675</span><span class="p">]</span>
    <span class="k">def</span> <span class="nf">setValue</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
    <span class="k">def</span> <span class="nf">paintEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="n">qp</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPainter</span><span class="p">()</span>
        <span class="n">qp</span><span class="o">.</span><span class="n">begin</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">drawWidget</span><span class="p">(</span><span class="n">qp</span><span class="p">)</span>
        <span class="n">qp</span><span class="o">.</span><span class="n">end</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">drawWidget</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">qp</span><span class="p">):</span>
        <span class="n">font</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFont</span><span class="p">(</span><span class="s">&#39;Serif&#39;</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFont</span><span class="o">.</span><span class="n">Light</span><span class="p">)</span>
        <span class="n">qp</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">font</span><span class="p">)</span>
        <span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">()</span>
        <span class="n">w</span> <span class="o">=</span> <span class="n">size</span><span class="o">.</span><span class="n">width</span><span class="p">()</span>
        <span class="n">h</span> <span class="o">=</span> <span class="n">size</span><span class="o">.</span><span class="n">height</span><span class="p">()</span>
        <span class="n">step</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="n">w</span> <span class="o">/</span> <span class="mf">10.0</span><span class="p">))</span>
        <span class="n">till</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(((</span><span class="n">w</span> <span class="o">/</span> <span class="mf">750.0</span><span class="p">)</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">))</span>
        <span class="n">full</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(((</span><span class="n">w</span> <span class="o">/</span> <span class="mf">750.0</span><span class="p">)</span> <span class="o">*</span> <span class="mi">700</span><span class="p">))</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">&gt;=</span> <span class="mi">700</span><span class="p">:</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">setPen</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">setBrush</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">184</span><span class="p">))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">drawRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">full</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">setPen</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">175</span><span class="p">,</span> <span class="mi">175</span><span class="p">))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">setBrush</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">175</span><span class="p">,</span> <span class="mi">175</span><span class="p">))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">drawRect</span><span class="p">(</span><span class="n">full</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">till</span><span class="o">-</span><span class="n">full</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">setPen</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">setBrush</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">255</span><span class="p">,</span> <span class="mi">255</span><span class="p">,</span> <span class="mi">184</span><span class="p">))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">drawRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">till</span><span class="p">,</span> <span class="n">h</span><span class="p">)</span>
        <span class="n">pen</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPen</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span>
            <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">SolidLine</span><span class="p">)</span>
        <span class="n">qp</span><span class="o">.</span><span class="n">setPen</span><span class="p">(</span><span class="n">pen</span><span class="p">)</span>
        <span class="n">qp</span><span class="o">.</span><span class="n">setBrush</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">NoBrush</span><span class="p">)</span>
        <span class="n">qp</span><span class="o">.</span><span class="n">drawRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">w</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">h</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">step</span><span class="p">,</span> <span class="mi">10</span><span class="o">*</span><span class="n">step</span><span class="p">,</span> <span class="n">step</span><span class="p">):</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">drawLine</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
            <span class="n">metrics</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">fontMetrics</span><span class="p">()</span>
            <span class="n">fw</span> <span class="o">=</span> <span class="n">metrics</span><span class="o">.</span><span class="n">width</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
            <span class="n">qp</span><span class="o">.</span><span class="n">drawText</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="n">fw</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">h</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
            <span class="n">j</span> <span class="o">=</span> <span class="n">j</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">sld</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QSlider</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Horizontal</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">sld</span><span class="o">.</span><span class="n">setFocusPolicy</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">NoFocus</span><span class="p">)</span>
        <span class="n">sld</span><span class="o">.</span><span class="n">setRange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">750</span><span class="p">)</span>
        <span class="n">sld</span><span class="o">.</span><span class="n">setValue</span><span class="p">(</span><span class="mi">75</span><span class="p">)</span>
        <span class="n">sld</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">150</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="n">Communicate</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">wid</span> <span class="o">=</span> <span class="n">BurningWidget</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">updateBW</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">wid</span><span class="o">.</span><span class="n">setValue</span><span class="p">)</span>
        <span class="n">sld</span><span class="o">.</span><span class="n">valueChanged</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">changeValue</span><span class="p">)</span>
        <span class="n">hbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QHBoxLayout</span><span class="p">()</span>
        <span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">wid</span><span class="p">)</span>
        <span class="n">vbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QVBoxLayout</span><span class="p">()</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addStretch</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addLayout</span><span class="p">(</span><span class="n">hbox</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">vbox</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">390</span><span class="p">,</span> <span class="mi">210</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Burning widget&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">changeValue</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">updateBW</span><span class="o">.</span><span class="n">emit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">wid</span><span class="o">.</span><span class="n">repaint</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个例子中，我们有一个 <tt class="docutils literal"><span class="pre">QtGui.QSlider</span></tt> 和一个自定制组件。滑块控制了自定制组件。这个组件显示一个媒介总的容量以及剩余的容量。这里最小的值是 1，最大是 750 。如果我们到达 700 ，我们开始画红色。这是用于指示过度烧制。</p>
<p>组件放在窗口的底部。这通过一个 <tt class="docutils literal"><span class="pre">QtGui.QHBoxLayout</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QVBoxLayout</span></tt> 实现。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">BurningWidget</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">BurningWidget</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
</pre></div>
</div>
<p>这个组件基于 <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 组件。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">setMinimumSize</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span>
</pre></div>
</div>
<p>我们更改了组件最小的大小（高度）。默认的值是一点点小。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">font</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFont</span><span class="p">(</span><span class="s">&#39;Serif&#39;</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFont</span><span class="o">.</span><span class="n">Light</span><span class="p">)</span>
<span class="n">qp</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">font</span><span class="p">)</span>
</pre></div>
</div>
<p>我们用小于默认的字体。这适合于我们的需要。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">()</span>
<span class="n">w</span> <span class="o">=</span> <span class="n">size</span><span class="o">.</span><span class="n">width</span><span class="p">()</span>
<span class="n">h</span> <span class="o">=</span> <span class="n">size</span><span class="o">.</span><span class="n">height</span><span class="p">()</span>
<span class="n">step</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="n">w</span> <span class="o">/</span> <span class="mf">10.0</span><span class="p">))</span>
<span class="n">till</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(((</span><span class="n">w</span> <span class="o">/</span> <span class="mf">750.0</span><span class="p">)</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">))</span>
<span class="n">full</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(((</span><span class="n">w</span> <span class="o">/</span> <span class="mf">750.0</span><span class="p">)</span> <span class="o">*</span> <span class="mi">700</span><span class="p">))</span>
</pre></div>
</div>
<p>我们动态地绘制组件。窗口越大，组件会越大。反之亦然。这就是为何我们要计算组件的大小。参数 till 决定了要画多少。此值来自于滑块组件。这是整个区域的部分值。参数 full 决定了什么时候开始绘制红色部分。注意，此处使用了浮点运算，是为更高的精度。</p>
<p>真正绘制时包含三个部分。我们先绘制黄色或红色和黄色的矩形。然后绘制垂直的线，主要用于分割组件。最后是绘制数字，用于指示媒介的大小。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">metrics</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">fontMetrics</span><span class="p">()</span>
<span class="n">fw</span> <span class="o">=</span> <span class="n">metrics</span><span class="o">.</span><span class="n">width</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
<span class="n">qp</span><span class="o">.</span><span class="n">drawText</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="n">fw</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="n">h</span><span class="o">/</span><span class="mi">2</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">num</span><span class="p">[</span><span class="n">j</span><span class="p">]))</span>
</pre></div>
</div>
<p>我们使用字体度量来绘制文本。我们必须要知道文本的宽度来居中绘制。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">changeValue</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">updateBW</span><span class="o">.</span><span class="n">emit</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">wid</span><span class="o">.</span><span class="n">repaint</span><span class="p">()</span>
</pre></div>
</div>
<p>我们移动滑块时， <tt class="docutils literal"><span class="pre">changeValue()</span></tt> 方法就被调用了。在此方法内部，我们发送了自定义的 updateBW 信号，并且带了一个参数。这个参数是当前滑块的值。这个值用于计算在 Burning 这个组件中要绘制多少。自定义的组件然后被重绘。</p>
<hr class="docutils" />
<p>本部分，我们创建了自己的组件。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/165391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:17 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]在 PyQt4 中绘图</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165390.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:16:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165390.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165390.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165390.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165390.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165390.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在 PyQt4 中绘图&#182;绘图常用于，当我们想改变一个已存在的组件，或者是我们希望自己创建组件。为了实现绘图，我们可以使用 PyQt4 中提供的 API 。绘制一般由 paintEvent() 方法处理。绘制的代码放置于 QtGui.QPainter 对象的 begin() 与 end() 之间。绘制文本&#182;我们可以把一些 Unicode 文本绘制到屏幕上。...&nbsp;&nbsp;<a href='http://www.cppblog.com/mirguest/archive/2012/02/12/165390.html'>阅读全文</a><img src ="http://www.cppblog.com/mirguest/aggbug/165390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:16 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]在 PyQt4 中 drag 和 drop</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165389.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:14:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165389.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165389.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165389.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165389.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165389.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4-drag-drop">
<h1>在 PyQt4 中 drag 和 drop<a class="headerlink" href="#pyqt4-drag-drop" title="Permalink to this headline">&#182;</a></h1>
<p>本部分，我们将讨论 drag 和 drop 操作。</p>
<p>在计算机中的图形界面中， drag-and-drop 是例如点击到一个虚拟对象并把它拖到另外的位置上的行为。一般来说，这可以用于很多行为，或创建两个对象间的关联。（Wikipedia）</p>
<p>drag 和 drop 的功能是 GUI 最有用的功能之一。它可以是用户处理复杂的工作。</p>
<p>一般来说，我们可以 drag 和 drop 两种东西，数据或图形对象。如果我们吧一幅图像从一个应用拖到另一个应用，我们处理的是二进制数据。如果我们在 Firefox 中拖动了一个标签，我们拖的则是一个图形组件。</p>
<div class="section" id="drag-drop">
<h2>简单的 Drag 和 Drop<a class="headerlink" href="#drag-drop" title="Permalink to this headline">&#182;</a></h2>
<p>第一个例子，我们将有一个 <tt class="docutils literal"><span class="pre">QtGui.QLineEdit</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 。我们将从行编辑区拖动文本到按钮上。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This is a simple drag and</span>
<span class="sd">drop example.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: December 2010</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Button</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Button</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setAcceptDrops</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">dragEnterEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">mimeData</span><span class="p">()</span><span class="o">.</span><span class="n">hasFormat</span><span class="p">(</span><span class="s">&#39;text/plain&#39;</span><span class="p">):</span>
            <span class="n">e</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">e</span><span class="o">.</span><span class="n">ignore</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">dropEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">mimeData</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">())</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">edit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">edit</span><span class="o">.</span><span class="n">setDragEnabled</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
        <span class="n">edit</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">65</span><span class="p">)</span>
        <span class="n">button</span> <span class="o">=</span> <span class="n">Button</span><span class="p">(</span><span class="s">&quot;Button&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">button</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">190</span><span class="p">,</span> <span class="mi">65</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Simple Drag &amp; Drop&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">ex</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">()</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>简单的拖拽操作。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Button</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Button</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">)</span>
</pre></div>
</div>
<p>为了可以把文字拖到 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 组件上，我们必需要重新实现一些方法。所以我们创建了我们自己的按钮类。它从 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 派生。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">setAcceptDrops</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<p>我们开启允许接受拖入的事件。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">dragEnterEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">mimeDate</span><span class="p">()</span><span class="o">.</span><span class="n">hasFormat</span><span class="p">(</span><span class="s">&#39;text/plain&#39;</span><span class="p">):</span>
        <span class="n">e</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">e</span><span class="o">.</span><span class="n">ignore</span><span class="p">()</span>
</pre></div>
</div>
<p>首先，我们重新实现了 <tt class="docutils literal"><span class="pre">drageEnterEvent()</span></tt> 方法。我们将接受特定的数据类型，此处是纯文本。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">dropEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">mimeDate</span><span class="p">()</span><span class="o">.</span><span class="n">text</span><span class="p">())</span>
</pre></div>
</div>
<p>通过重新实现 <tt class="docutils literal"><span class="pre">dropEvent()</span></tt> 方法，我们定义了放下后处理的事件。我们在这里是改变了按钮中的显示文本。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">edit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="n">edit</span><span class="o">.</span><span class="n">setDragEnabled</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">QtGui.QLineEdit</span></tt> 组件有内置的拖拽操作。我们只需要调用 <tt class="docutils literal"><span class="pre">setDragEnabled()</span></tt> 激活它就可以了。</p>
</div>
<div class="section" id="id1">
<h2>拖拽一个按钮组件<a class="headerlink" href="#id1" title="Permalink to this headline">&#182;</a></h2>
<p>下面的例子，我们将介绍如何拖拽一个按钮对象。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this program, we can press</span>
<span class="sd">on a button with a left mouse</span>
<span class="sd">click or drag and drop the button</span>
<span class="sd">with  the right mouse click.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: December 2010</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Button</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Button</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">mouseMoveEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">buttons</span><span class="p">()</span> <span class="o">!=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">RightButton</span><span class="p">:</span>
            <span class="k">return</span>
        <span class="n">mimeData</span> <span class="o">=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">QMimeData</span><span class="p">()</span>
        <span class="n">drag</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QDrag</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">drag</span><span class="o">.</span><span class="n">setMimeData</span><span class="p">(</span><span class="n">mimeData</span><span class="p">)</span>
        <span class="n">drag</span><span class="o">.</span><span class="n">setHotSpot</span><span class="p">(</span><span class="n">e</span><span class="o">.</span><span class="n">pos</span><span class="p">()</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">rect</span><span class="p">()</span><span class="o">.</span><span class="n">topLeft</span><span class="p">())</span>
        <span class="n">dropAction</span> <span class="o">=</span> <span class="n">drag</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">MoveAction</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">mousePressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="o">.</span><span class="n">mousePressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">button</span><span class="p">()</span> <span class="o">==</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">LeftButton</span><span class="p">:</span>
            <span class="k">print</span> <span class="s">&#39;press&#39;</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setAcceptDrops</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">button</span> <span class="o">=</span> <span class="n">Button</span><span class="p">(</span><span class="s">&#39;Button&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">button</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">65</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Click or Move&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">280</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">dragEnterEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="n">e</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">dropEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="n">position</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">pos</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">button</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">position</span><span class="p">)</span>
        <span class="n">e</span><span class="o">.</span><span class="n">setDropAction</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">MoveAction</span><span class="p">)</span>
        <span class="n">e</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">ex</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">()</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个例子中，我们有一个 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 在窗口上。如果我们点击按钮，将在控制台上输出 &#8216;press&#8217; 。而如果右击按钮并且移动，我们就可以拖拽这个按钮组件。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Button</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Button</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="n">parent</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了一个派生自 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 的按钮类。我们还重新实现了 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 中的两个方法， <tt class="docutils literal"><span class="pre">mouseMoveEvent()</span></tt> 和 <tt class="docutils literal"><span class="pre">mousePressEvent()</span></tt> 。其中， <tt class="docutils literal"><span class="pre">mouseMoveEvent()</span></tt> 方法是开始拖拽处发生的地方。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">event</span><span class="o">.</span><span class="n">buttons</span><span class="p">()</span> <span class="o">!=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">RightButton</span><span class="p">:</span>
    <span class="k">return</span>
</pre></div>
</div>
<p>我们决定只用鼠标右击进行拖拽。左击用于点击按钮。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">mimeData</span> <span class="o">=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">QMimeData</span><span class="p">()</span>
<span class="n">drag</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QDrag</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">drag</span><span class="o">.</span><span class="n">setMimeData</span><span class="p">(</span><span class="n">mimeData</span><span class="p">)</span>
<span class="n">drag</span><span class="o">.</span><span class="n">setHotSpot</span><span class="p">(</span><span class="n">event</span><span class="o">.</span><span class="n">pos</span><span class="p">()</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">rect</span><span class="p">()</span><span class="o">.</span><span class="n">topLeft</span><span class="p">())</span>
</pre></div>
</div>
<p>我们创建了一个 <tt class="docutils literal"><span class="pre">QDrag</span></tt> 对象。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">dropAction</span> <span class="o">=</span> <span class="n">drag</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">MoveAction</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">start()</span></tt> 方法开始拖拽操作。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">mousePressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
    <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="o">.</span><span class="n">mousePressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">button</span><span class="p">()</span> <span class="o">==</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">LeftButton</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&#39;press&#39;</span>
</pre></div>
</div>
<p>如果点击了鼠标左键，我们在控制台上打印 &#8216;press&#8217; 。注意，我们还调用了父类的 <tt class="docutils literal"><span class="pre">mousePressEvent()</span></tt> 方法。否则，我们将不会看到按钮被按下。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">position</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">pos</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">button</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">position</span><span class="p">)</span>
</pre></div>
</div>
<p>在 <tt class="docutils literal"><span class="pre">dropEvent()</span></tt> 方法中，定义了当我们松开鼠标按钮停止拖拽的行为。我们找到鼠标当前的位置，并把按钮移到合适的位置。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">e</span><span class="o">.</span><span class="n">setDropAction</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">MoveAction</span><span class="p">)</span>
<span class="n">e</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
</pre></div>
</div>
<p>我们指定了拖拽的类型。在此处是移动的行为。</p>
<hr class="docutils" />
<p>本部分我们讨论了拖拽。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/165389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:14 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]PyQt4 Widget II</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165388.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:13:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165388.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165388.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165388.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165388.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165388.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4-widget-ii">
<h1>PyQt4 Widget II<a class="headerlink" href="#pyqt4-widget-ii" title="Permalink to this headline">&#182;</a></h1>
<p>这里我们将继续介绍 PyQt4 组件。我们将涉及 <tt class="docutils literal"><span class="pre">QtGui.QPixmap</span></tt> ， <tt class="docutils literal"><span class="pre">QtGui.QLineEdit</span></tt> ， <tt class="docutils literal"><span class="pre">QtGui.QSplitter</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QComboBox</span></tt> 。</p>
<div class="section" id="qtgui-qpixmap">
<h2><tt class="docutils literal"><span class="pre">QtGui.QPixmap</span></tt><a class="headerlink" href="#qtgui-qpixmap" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QPixmap</span></tt> 是可以处理图片的组件之一。它对显示图片进行了优化。在我们的例子中，我们会用 <tt class="docutils literal"><span class="pre">QtGui.QPixmap</span></tt> 来显示图片。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we dispay an image</span>
<span class="sd">on the window.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: September 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">hbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QHBoxLayout</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">pixmap</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPixmap</span><span class="p">(</span><span class="s">&quot;redrock.png&quot;</span><span class="p">)</span>
        <span class="n">lbl</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">lbl</span><span class="o">.</span><span class="n">setPixmap</span><span class="p">(</span><span class="n">pixmap</span><span class="p">)</span>
        <span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">lbl</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">hbox</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Red Rock&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个例子里，我们显示了一幅图片。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">pixmap</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPixmap</span><span class="p">(</span><span class="s">&quot;redrock.png&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了一个 <tt class="docutils literal"><span class="pre">QtGui.QPixmap</span></tt> 对象。它接受文件名作为参数。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">lbl</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">lbl</span><span class="o">.</span><span class="n">setPixmap</span><span class="p">(</span><span class="n">pixmap</span><span class="p">)</span>
</pre></div>
</div>
<p>我们把 pixmap 放到了 <tt class="docutils literal"><span class="pre">QtGui.QLabel</span></tt> 中。</p>
</div>
<div class="section" id="qtgui-qlineedit">
<h2><tt class="docutils literal"><span class="pre">QtGui.QLineEdit</span></tt><a class="headerlink" href="#qtgui-qlineedit" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QLineEdit</span></tt> 是一个允许输入和编辑一行纯文本。这个组件中可以撤销/恢复，剪切/粘贴以及拖拉。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This example shows text which</span>
<span class="sd">is entered in a QtGui.QLineEdit</span>
<span class="sd">in a QtGui.QLabel widget.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: August 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">qle</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">qle</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">60</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">60</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
        <span class="n">qle</span><span class="o">.</span><span class="n">textChanged</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">onChanged</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">280</span><span class="p">,</span> <span class="mi">170</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;QtGui.QLineEdit&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">onChanged</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">adjustSize</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子显示一个行编辑区和一个标签。我们输入的就会立即在标签中显示。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">qle</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
</pre></div>
</div>
<p>创建了 <tt class="docutils literal"><span class="pre">QtGui.QLineEdit</span></tt> 组件。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">qle</span><span class="o">.</span><span class="n">textChanged</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">onChanged</span><span class="p">)</span>
</pre></div>
</div>
<p>如果文本区的文本改变了，我们就调用 <tt class="docutils literal"><span class="pre">onChanged()</span></tt> 方法。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">onChanged</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">adjustSize</span><span class="p">()</span>
</pre></div>
</div>
<p>在 <tt class="docutils literal"><span class="pre">onChanged()</span></tt> 方法中，我们把输入的文本放到了标签中。通过调用 <tt class="docutils literal"><span class="pre">adjustSize()</span></tt> 方法，我们把标签设置到文本的长度。</p>
</div>
<div class="section" id="qtgui-qsplitter">
<h2><tt class="docutils literal"><span class="pre">QtGui.QSplitter</span></tt><a class="headerlink" href="#qtgui-qsplitter" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QSplitter</span></tt> 可以让用户控制子组件的大小，通过拖动子组件的大小。在我们的例子中，我们的三个 <tt class="docutils literal"><span class="pre">QtGui.QFrame</span></tt> 将由两个 splitter 分割。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This example shows</span>
<span class="sd">how to use QtGui.QSplitter widget.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: September 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">hbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QHBoxLayout</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">topleft</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">topleft</span><span class="o">.</span><span class="n">setFrameShape</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="o">.</span><span class="n">StyledPanel</span><span class="p">)</span>
        <span class="n">topright</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">topright</span><span class="o">.</span><span class="n">setFrameShape</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="o">.</span><span class="n">StyledPanel</span><span class="p">)</span>
        <span class="n">bottom</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">bottom</span><span class="o">.</span><span class="n">setFrameShape</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="o">.</span><span class="n">StyledPanel</span><span class="p">)</span>
        <span class="n">splitter1</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QSplitter</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Horizontal</span><span class="p">)</span>
        <span class="n">splitter1</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">topleft</span><span class="p">)</span>
        <span class="n">splitter1</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">topright</span><span class="p">)</span>
        <span class="n">splitter2</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QSplitter</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Vertical</span><span class="p">)</span>
        <span class="n">splitter2</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">splitter1</span><span class="p">)</span>
        <span class="n">splitter2</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">bottom</span><span class="p">)</span>
        <span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">splitter2</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">hbox</span><span class="p">)</span>
        <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="o">.</span><span class="n">setStyle</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QStyleFactory</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="s">&#39;Cleanlooks&#39;</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;QtGui.QSplitter&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个例子中，有三个框架组件，两个分割条。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">topleft</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">topleft</span><span class="o">.</span><span class="n">setFrameShape</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="o">.</span><span class="n">StyledPanel</span><span class="p">)</span>
</pre></div>
</div>
<p>我们使用了有样式的框架，主要用于看到边框。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">splitter1</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QSplitter</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Horizontal</span><span class="p">)</span>
<span class="n">splitter1</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">topleft</span><span class="p">)</span>
<span class="n">splitter1</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">topright</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了一个 <tt class="docutils literal"><span class="pre">QtGui.QSplitter</span></tt> 组件，并添加到两个框架。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">splitter2</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QSplitter</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Vertical</span><span class="p">)</span>
<span class="n">splitter2</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">splitter1</span><span class="p">)</span>
</pre></div>
</div>
<p>我们也可以把一个 splitter 添加到 splitter 中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="o">.</span><span class="n">setStyle</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QStyleFactory</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="s">&#39;Cleanlooks&#39;</span><span class="p">))</span>
</pre></div>
</div>
<p>我们使用一个简洁的样式。在有些样式中，框架是不可见的。</p>
</div>
<div class="section" id="qtgui-qcombobox">
<h2><tt class="docutils literal"><span class="pre">QtGui.QComboBox</span></tt><a class="headerlink" href="#qtgui-qcombobox" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QComboBox</span></tt> 允许用户从一组选项中选取一个。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This example shows</span>
<span class="sd">how to use QtGui.QComboBox widget.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: September 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&quot;Ubuntu&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">combo</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QComboBox</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Ubuntu&quot;</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Mandriva&quot;</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Fedora&quot;</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Red Hat&quot;</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Gentoo&quot;</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="n">combo</span><span class="o">.</span><span class="n">activated</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">onActivated</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;QtGui.QComboBox&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">onActivated</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">adjustSize</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子中有一个 <tt class="docutils literal"><span class="pre">QtGui.QComboBox</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QLable</span></tt> 。这里有五个选项。它们是 Linux 的发行版。标签中就会显示选中的项目。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">combo</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QComboBox</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Ubuntu&quot;</span><span class="p">)</span>
<span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Mandriva&quot;</span><span class="p">)</span>
<span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Fedora&quot;</span><span class="p">)</span>
<span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Red Hat&quot;</span><span class="p">)</span>
<span class="n">combo</span><span class="o">.</span><span class="n">addItem</span><span class="p">(</span><span class="s">&quot;Gentoo&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建一个 <tt class="docutils literal"><span class="pre">QtGui.QComboBox</span></tt> 组件并增加了五个选项。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">combo</span><span class="o">.</span><span class="n">activated</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">onActivated</span><span class="p">)</span>
</pre></div>
</div>
<p>当选择一个选项后，我们调用了 <tt class="docutils literal"><span class="pre">onActivated()</span></tt> 方法。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">onActivated</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">text</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">adjustSize</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个方法中，我们把选中的选项的文本放到标签中。我们还调整标签的大小。</p>
<hr class="docutils" />
<p>在本部分，我们涉及了另外四个 PyQt4 组件。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/165388.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:13 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165388.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]PyQt4 Widget</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165387.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:11:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165387.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165387.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165387.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165387.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: PyQt4 Widget&#182;组件（Widget）是一个应用最基本的构件。PyQt4 中有大量的组件。按钮，选择框，滑块，列表等等。任何一个程序员都会需要这些组件。这篇中，我们将介绍一些有用的组件， QtGui.QCheckBox ， ToggleButton ， QtGui.QSlider , QtGui.QProcessBar 和 QtGui.QCalendarWidget 。...&nbsp;&nbsp;<a href='http://www.cppblog.com/mirguest/archive/2012/02/12/165387.html'>阅读全文</a><img src ="http://www.cppblog.com/mirguest/aggbug/165387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:11 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]PyQt4 中的 Dialog</title><link>http://www.cppblog.com/mirguest/archive/2012/02/12/165386.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 12 Feb 2012 02:06:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/12/165386.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/165386.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/12/165386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/165386.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/165386.html</trackback:ping><description><![CDATA[<div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4-dialog">
<h1>PyQt4 中的 Dialog<a class="headerlink" href="#pyqt4-dialog" title="Permalink to this headline">&#182;</a></h1>
<p>Dialog 窗口或 dialog 是现代 GUI 应用必不可少的一部分。一个 dialog 定义为两人或更多人间的会话。在计算机应用中，dialog 就是一个和应用说话的窗口。dialog 可以用于输入数据，修改数据，更改应用的设置等等。对话框在用户和计算机的通信间是重要的手段。</p>
<div class="section" id="qtgui-qinputdialog">
<h2><tt class="docutils literal"><span class="pre">QtGui.QInputDialog</span></tt><a class="headerlink" href="#qtgui-qinputdialog" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QInputDialog</span></tt> 提供了一个简单方便的对话框，用于获取用户输入的一个值。输入值可以是字符串，数字，或者一个列表中的一项。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we receive data from</span>
<span class="sd">a QtGui.QInputDialog dialog.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">btn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Dialog&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">btn</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">btn</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">showDialog</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">le</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">le</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">130</span><span class="p">,</span> <span class="mi">22</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">290</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Input dialog&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">showDialog</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">text</span><span class="p">,</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QInputDialog</span><span class="o">.</span><span class="n">getText</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;Input Dialog&#39;</span><span class="p">,</span>
            <span class="s">&#39;Enter your name:&#39;</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">ok</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">le</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子中用到了一个按钮和一个行编辑组件。按钮会显示一个输入对话框用于得到文本。而输入的文本将在行编辑组件中显示。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">text</span><span class="p">,</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QInputDialog</span><span class="o">.</span><span class="n">getText</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;Input Dialog&#39;</span><span class="p">,</span>
    <span class="s">&#39;Enter your name:&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>这一行显示了输入对话框。第一个字符串是对话框的标题，第二个字符串则是对话框中的消息。对话框将返回输入的文本和一个布尔值。如果点击了 ok 按钮，则布尔值为 <tt class="docutils literal"><span class="pre">true</span></tt> ，否则为 <tt class="docutils literal"><span class="pre">false</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">ok</span><span class="p">:</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">le</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">))</span>
</pre></div>
</div>
<p>从对话框中接收到的文本就被设置到行编辑组件中。</p>
</div>
<div class="section" id="qtgui-qcolordialog">
<h2><tt class="docutils literal"><span class="pre">QtGui.QColorDialog</span></tt><a class="headerlink" href="#qtgui-qcolordialog" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QColorDialog</span></tt> 用于选取颜色值。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we select a color value</span>
<span class="sd">from the QtGui.QColorDialog and change the background</span>
<span class="sd">color of a QtGui.QFrame widget.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">col</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">btn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Dialog&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">btn</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">btn</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">showDialog</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">frm</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFrame</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">frm</span><span class="o">.</span><span class="n">setStyleSheet</span><span class="p">(</span><span class="s">&quot;QWidget { background-color: </span><span class="si">%s</span><span class="s"> }&quot;</span>
            <span class="o">%</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span><span class="p">())</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">frm</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">130</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">180</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Color dialog&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">showDialog</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">col</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QColorDialog</span><span class="o">.</span><span class="n">getColor</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">col</span><span class="o">.</span><span class="n">isValid</span><span class="p">():</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">frm</span><span class="o">.</span><span class="n">setStyleSheet</span><span class="p">(</span><span class="s">&quot;QWidget { background-color: </span><span class="si">%s</span><span class="s"> }&quot;</span>
                <span class="o">%</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子显示一个按钮和一个 <tt class="docutils literal"><span class="pre">QtGui.QFrame</span></tt> 。这个组件的背景被设为黑色。使用 <tt class="docutils literal"><span class="pre">QtGui.QColorDialog</span></tt> 可以改变其背景。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">col</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QColor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</pre></div>
</div>
<p>这个是 <tt class="docutils literal"><span class="pre">QtGui.QFrame</span></tt> 的初始颜色。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">col</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QColorDialog</span><span class="o">.</span><span class="n">getColor</span><span class="p">()</span>
</pre></div>
</div>
<p>这一行将弹出 <tt class="docutils literal"><span class="pre">QtGui.QColorDialog</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">col</span><span class="o">.</span><span class="n">isValid</span><span class="p">():</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">frm</span><span class="o">.</span><span class="n">setStyleSheet</span><span class="p">(</span><span class="s">&quot;QWidget { background-color: </span><span class="si">%s</span><span class="s"> }&quot;</span>
        <span class="o">%</span> <span class="n">col</span><span class="o">.</span><span class="n">name</span><span class="p">())</span>
</pre></div>
</div>
<p>我们检查颜色是否合法。如果点击了取消按钮，返回的就不是合法值。如果颜色合法，我们就用样式表更改背景颜色。</p>
</div>
<div class="section" id="qtgui-qfontdialog">
<h2><tt class="docutils literal"><span class="pre">QtGui.QFontDialog</span></tt><a class="headerlink" href="#qtgui-qfontdialog" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QFontDialog</span></tt> 用于选取字体。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we select a font name</span>
<span class="sd">and change the font of a label.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">vbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QVBoxLayout</span><span class="p">()</span>
        <span class="n">btn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Dialog&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">btn</span><span class="o">.</span><span class="n">setSizePolicy</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QSizePolicy</span><span class="o">.</span><span class="n">Fixed</span><span class="p">,</span>
            <span class="n">QtGui</span><span class="o">.</span><span class="n">QSizePolicy</span><span class="o">.</span><span class="n">Fixed</span><span class="p">)</span>
        <span class="n">btn</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">btn</span><span class="p">)</span>
        <span class="n">btn</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">showDialog</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;Knowledge only matters&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">130</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">vbox</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">180</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Font dialog&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">showDialog</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">font</span><span class="p">,</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFontDialog</span><span class="o">.</span><span class="n">getFont</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">ok</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">lbl</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">font</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在我们的例子中，我们有一个按钮和一个标签。通过 <tt class="docutils literal"><span class="pre">QtGui.QFontDialog</span></tt> 我们可以改变标签的字体。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">font</span><span class="p">,</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFontDialog</span><span class="o">.</span><span class="n">getFont</span><span class="p">()</span>
</pre></div>
</div>
<p>我们弹出一个字体对话框。 <tt class="docutils literal"><span class="pre">getFont()</span></tt> 方法将返回字体的名称和 ok 参数。如果用户点击了 OK 那么就是 <tt class="docutils literal"><span class="pre">True</span></tt> ，否则为 <tt class="docutils literal"><span class="pre">False</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">ok</span><span class="p">:</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">font</span><span class="p">)</span>
</pre></div>
</div>
<p>如果我们点击了 ok，标签的字体就可能改变。</p>
</div>
<div class="section" id="qtgui-qfiledialog">
<h2><tt class="docutils literal"><span class="pre">QtGui.QFileDialog</span></tt><a class="headerlink" href="#qtgui-qfiledialog" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QFileDialog</span></tt> 是允许用户选择文件或目录的对话框。文件可以用于打开或保存。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we select a file with a</span>
<span class="sd">QtGui.QFileDialog and display its contents</span>
<span class="sd">in a QtGui.QTextEdit.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">textEdit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QTextEdit</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setCentralWidget</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">textEdit</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span>
        <span class="n">openFile</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QAction</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;open.png&#39;</span><span class="p">),</span> <span class="s">&#39;Open&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">openFile</span><span class="o">.</span><span class="n">setShortcut</span><span class="p">(</span><span class="s">&#39;Ctrl+O&#39;</span><span class="p">)</span>
        <span class="n">openFile</span><span class="o">.</span><span class="n">setStatusTip</span><span class="p">(</span><span class="s">&#39;Open new File&#39;</span><span class="p">)</span>
        <span class="n">openFile</span><span class="o">.</span><span class="n">triggered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">showDialog</span><span class="p">)</span>
        <span class="n">menubar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">menuBar</span><span class="p">()</span>
        <span class="n">fileMenu</span> <span class="o">=</span> <span class="n">menubar</span><span class="o">.</span><span class="n">addMenu</span><span class="p">(</span><span class="s">&#39;&amp;File&#39;</span><span class="p">)</span>
        <span class="n">fileMenu</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">openFile</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">350</span><span class="p">,</span> <span class="mi">300</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;File dialog&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">showDialog</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">fname</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFileDialog</span><span class="o">.</span><span class="n">getOpenFileName</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;Open file&#39;</span><span class="p">,</span>
                <span class="s">&#39;/home&#39;</span><span class="p">)</span>
        <span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span>
        <span class="k">with</span> <span class="n">f</span><span class="p">:</span>
            <span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">textEdit</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子中有菜单栏，文本编辑区以及状态栏。菜单中的选项显示 <tt class="docutils literal"><span class="pre">QtGui.QFileDialog</span></tt> 用于选择文件。而文件的内容则载入到文本编辑区。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子是基于 <tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 组件，因为我们要在中心设置文本编辑区。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">fname</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QFileDialog</span><span class="o">.</span><span class="n">getOpenFileName</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;Open file&#39;</span><span class="p">,</span>
    <span class="s">&#39;/home&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>我们弹出 <tt class="docutils literal"><span class="pre">QtGui.QFileDialog</span></tt> 。在 <tt class="docutils literal"><span class="pre">getOpenFileName()</span></tt> 方法中第一个字符串是标题。第二个则是指定对话框的工作目录。默认情况下，文件过滤为所有文件（ <tt class="docutils literal"><span class="pre">*</span></tt> ）。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span>
<span class="k">with</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">textEdit</span><span class="o">.</span><span class="n">setText</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</pre></div>
</div>
<p>选择的文件将被读取，并且其文件内容设置到文本编辑区。</p>
<hr class="docutils" />
<p>这个部分，我们讨论了对话框。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/165386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-12 10:06 <a href="http://www.cppblog.com/mirguest/archive/2012/02/12/165386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]PyQt4 中的事件和信号</title><link>http://www.cppblog.com/mirguest/archive/2012/02/05/164984.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 05 Feb 2012 02:05:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/05/164984.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164984.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/05/164984.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164984.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164984.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4">
<h1>PyQt4 中的事件和信号<a class="headerlink" href="#pyqt4" title="Permalink to this headline">&#182;</a></h1>
<p>在本部分，我们将会探讨事件和信号。</p>
<div class="section" id="id1">
<h2>事件<a class="headerlink" href="#id1" title="Permalink to this headline">&#182;</a></h2>
<p>在任何的 GUI 程序中，事件是很重要的部分。事件是由用户或操作系统产生的。当我们调用应用的 <tt class="docutils literal"><span class="pre">exec_()</span></tt> 时，应用就进入了主循环。主循环会接受事件并且把它们发送给对象。Trolltech 引入了一个独特的信号和槽机制。</p>
<p>事件是任何 GUI 程序中很重要的部分。所有 GUI 应用都是事件驱动的。一个应用对其生命期产生的不同的事件类型做出反应。事件是主要由应用的用户产生。但是，也可以通过其他方法产生，比如，网络通信，窗口的管理者，计时器。在事件模型中，有三个参与者：</p>
<ul class="simple">
<li>事件源（event source）</li>
<li>事件对象（event object）</li>
<li>事件目标（event target）</li>
</ul>
<p><strong>event source</strong> 是那些状态改变的对象。它产生事件。而 <strong>event object</strong> （Event）封装了事件源的状态改变。而 <strong>event target</strong> 则是需要被通知的。事件源把处理事件的任务委托给了事件目标。</p>
<p>当我们调用了应用的 <tt class="docutils literal"><span class="pre">exec_()</span></tt> 方法，应用就进入主循环了。主循环接受事件然后把他们发送给对象。信号和槽用于对象间的通信。当特定的事件发生时 <strong>信号</strong> 就被发送了。而 <strong>槽</strong> 则是任何 Python 中可调用的。当信号发送给了这个槽，槽就被调用了。</p>
</div>
<div class="section" id="api">
<h2>新的 API<a class="headerlink" href="#api" title="Permalink to this headline">&#182;</a></h2>
<p>PyQt 4.5 引入了新的 API 用于信号和槽。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">QtCore</span><span class="o">.</span><span class="n">QObject</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">button</span><span class="p">,</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">SIGNAL</span><span class="p">(</span><span class="s">&#39;clicked()&#39;</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">onClicked</span><span class="p">)</span>
</pre></div>
</div>
<p>这是旧式的 API 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">button</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">onClicked</span><span class="p">)</span>
</pre></div>
</div>
<p>新式的更接近 Python 的标准。</p>
</div>
<div class="section" id="id2">
<h2>信号与槽<a class="headerlink" href="#id2" title="Permalink to this headline">&#182;</a></h2>
<p>这是一个简单的例子，描述 PyQt4 中的信号和槽。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we connect a signal</span>
<span class="sd">of a QtGui.QSlider to a slot</span>
<span class="sd">of a QtGui.QLCDNumber.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">lcd</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLCDNumber</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="n">sld</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QSlider</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Horizontal</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">vbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QVBoxLayout</span><span class="p">()</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">lcd</span><span class="p">)</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">sld</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">vbox</span><span class="p">)</span>
        <span class="n">sld</span><span class="o">.</span><span class="n">valueChanged</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">lcd</span><span class="o">.</span><span class="n">display</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Signal &amp; slot&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在我们的例子中，我们显示了 <tt class="docutils literal"><span class="pre">QtGui.QLCDNumber</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QSlider</span></tt> 。通过拖拽滑块，我们就可以更改 lcd 的数字。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">sld</span><span class="o">.</span><span class="n">valueChanged</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">lcd</span><span class="o">.</span><span class="n">display</span><span class="p">)</span>
</pre></div>
</div>
<p>此处，我们把 slider 的信号 <tt class="docutils literal"><span class="pre">valueChanged</span></tt> 和 lcd 的槽 <tt class="docutils literal"><span class="pre">display</span></tt> 连接了起来。</p>
<p><strong>sender</strong> 是发送信号的对象。 <strong>receiver</strong> 是接受信号的对象。而 <strong>slot</strong> 是回馈信号的方法。</p>
</div>
<div class="section" id="id3">
<h2>重新实现事件处理句柄<a class="headerlink" href="#id3" title="Permalink to this headline">&#182;</a></h2>
<p>在 PyQt4 中事件的处理一般通过重新实现事件的句柄。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we reimplement an</span>
<span class="sd">event handler.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Event handler&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">keyPressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">key</span><span class="p">()</span> <span class="o">==</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Key_Escape</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在我们的例子中，我们重新实现了 <tt class="docutils literal"><span class="pre">keyPressEvent()</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">keyPressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">key</span><span class="p">()</span> <span class="o">==</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">Qt</span><span class="o">.</span><span class="n">Key_Escape</span><span class="p">:</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>如果我们按 escape 键，那么应用就将终止。</p>
</div>
<div class="section" id="id4">
<h2>事件发送者<a class="headerlink" href="#id4" title="Permalink to this headline">&#182;</a></h2>
<p>有些时候，知道信号的发送者是很方便的。因此，PyQt4 有个 <tt class="docutils literal"><span class="pre">sender()</span></tt> 方法。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we determine the event sender</span>
<span class="sd">object.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">btn1</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&quot;Button 1&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">btn1</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
        <span class="n">btn2</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&quot;Button 2&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">btn2</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">150</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
        <span class="n">btn1</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">buttonClicked</span><span class="p">)</span>
        <span class="n">btn2</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">buttonClicked</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">290</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Event sender&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">buttonClicked</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">sender</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sender</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span><span class="o">.</span><span class="n">showMessage</span><span class="p">(</span><span class="n">sender</span><span class="o">.</span><span class="n">text</span><span class="p">()</span> <span class="o">+</span> <span class="s">&#39; was pressed&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这个例子中有两个按钮。在 <tt class="docutils literal"><span class="pre">buttonClicked()</span></tt> 方法中，我们通过调用 <tt class="docutils literal"><span class="pre">sender()</span></tt> 方法知道了哪个按钮被点击了。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">btn1</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">buttonClicked</span><span class="p">)</span>
<span class="n">btn2</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">buttonClicked</span><span class="p">)</span>
</pre></div>
</div>
<p>两个按钮都连接到相同的槽中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">buttonClicked</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
    <span class="n">sender</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sender</span><span class="p">()</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span><span class="o">.</span><span class="n">showMessange</span><span class="p">(</span><span class="n">sender</span><span class="o">.</span><span class="n">text</span><span class="p">()</span> <span class="o">+</span> <span class="s">&quot; was pressed&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>我们通过调用 <tt class="docutils literal"><span class="pre">sender()</span></tt> 方法知道了消息源。在状态栏中，我们显示了被按的按钮的标签。</p>
</div>
<div class="section" id="id5">
<h2>发送信号<a class="headerlink" href="#id5" title="Permalink to this headline">&#182;</a></h2>
<p>由 <tt class="docutils literal"><span class="pre">QtCore.QObject</span></tt> 创建的对象可以发送信号。如果我们点击按钮，一个 <tt class="docutils literal"><span class="pre">clicked()</span></tt> 信号就被生成。在下面的例子中我们将看到如何发送信号。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we show how to emit a</span>
<span class="sd">custom signal.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Communicate</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">QObject</span><span class="p">):</span>
    <span class="n">closeApp</span> <span class="o">=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">pyqtSignal</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="n">Communicate</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">closeApp</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">290</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Emit signal&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">mousePressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">closeApp</span><span class="o">.</span><span class="n">emit</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>我们创建了一个新的信号称为 closeApp 。这个信号在鼠标点击时将被发送。而这个信号又和 <tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 的 <tt class="docutils literal"><span class="pre">close()</span></tt> 槽相连接。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Communicate</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">QObject</span><span class="p">):</span>
    <span class="n">closeApp</span> <span class="o">=</span> <span class="n">QtCore</span><span class="o">.</span><span class="n">pyqtSignal</span><span class="p">()</span>
</pre></div>
</div>
<p>我们创建了基于 <tt class="docutils literal"><span class="pre">QtCore.QObject</span></tt> 的类。当它被实例化后就创建了一个 closeApp 信号。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="n">Communicate</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">closeApp</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">)</span>
</pre></div>
</div>
<p>类 <tt class="docutils literal"><span class="pre">Communicate</span></tt> 的实例就被创建了。我们把 <tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 的 <tt class="docutils literal"><span class="pre">close()</span></tt> 槽连接到信号 closeApp 上。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">mousePressEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="o">.</span><span class="n">closeApp</span><span class="o">.</span><span class="n">emit</span><span class="p">()</span>
</pre></div>
</div>
<p>当鼠标指针在窗口中点击，信号 closeApp 就被发送了。</p>
<hr class="docutils" />
<p>在这个部分，我们涉及了信号与槽。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/164984.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-05 10:05 <a href="http://www.cppblog.com/mirguest/archive/2012/02/05/164984.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]PyQt4的 layout 管理</title><link>http://www.cppblog.com/mirguest/archive/2012/02/05/164983.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 05 Feb 2012 02:04:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/05/164983.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164983.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/05/164983.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164983.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164983.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4-layout">
<h1>PyQt4的 layout 管理<a class="headerlink" href="#pyqt4-layout" title="Permalink to this headline">&#182;</a></h1>
<p>在编程中一个重要的事情就是 layout 的管理。layout 管理就是在窗口中布置 widget。管理有两种方式。我们可以使用 <em>绝对定位</em> 或者 <em>layout 类</em> 。</p>
<div class="section" id="id1">
<h2>绝对定位<a class="headerlink" href="#id1" title="Permalink to this headline">&#182;</a></h2>
<p>程序员可以指定每个 widget 的位置和大小。当你使用绝对定位时，你需要理解一些事情。</p>
<ul class="simple">
<li>如果你改变了窗口的大小，widget 的大小和位置是不会改变的。</li>
<li>在不同平台上应用可能看起来不太一样。</li>
<li>在你的应用中改变字体会毁掉你的 layout。</li>
<li>如果你决定改变你的 layout，那么你必须要重新设计你的 layout，这意味着麻烦及耗时。</li>
</ul>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This example shows three labels on a window</span>
<span class="sd">using absolute positioning.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">lbl1</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;Zetcode&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">lbl1</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">15</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
        <span class="n">lbl2</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;tutorials&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">lbl2</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">35</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
        <span class="n">lbl3</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;for programmers&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">lbl3</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">55</span><span class="p">,</span> <span class="mi">70</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Absolute&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>我们简单地调用 <tt class="docutils literal"><span class="pre">move()</span></tt> 方法来定位我们的 widget 。在我们这个情况下，这些 widget 是标签。我们通过给定 x 和 y 坐标进行定位。坐标系统是从左上角开始。x 的值从左到右增加。y 则是从上到下。</p>
</div>
<div class="section" id="box-layout">
<h2>Box Layout<a class="headerlink" href="#box-layout" title="Permalink to this headline">&#182;</a></h2>
<p>通过 layout 类管理会更加灵活和实用。这是优先考虑的方法。基本的 layout 类是 <tt class="docutils literal"><span class="pre">QtGui.QHBoxLayout</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QVBoxLayout</span></tt> 。它们分别以水平和垂直方式对 widget 进行布局。</p>
<p>假设我们想把两个按钮放置在右下角。为了创建这样的 layout，我们可以使用一个水平的和垂直的盒子。为了创建必要的空间，我们将会增加一个 <em>缩放比例</em> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we position two push</span>
<span class="sd">buttons in the bottom-right corner</span>
<span class="sd">of the window.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">okButton</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&quot;OK&quot;</span><span class="p">)</span>
        <span class="n">cancelButton</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&quot;Cancel&quot;</span><span class="p">)</span>
        <span class="n">hbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QHBoxLayout</span><span class="p">()</span>
        <span class="n">hbox</span><span class="o">.</span><span class="n">addStretch</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">okButton</span><span class="p">)</span>
        <span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">cancelButton</span><span class="p">)</span>
        <span class="n">vbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QVBoxLayout</span><span class="p">()</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addStretch</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">vbox</span><span class="o">.</span><span class="n">addLayout</span><span class="p">(</span><span class="n">hbox</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">vbox</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Buttons&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这里在窗口的右下角放置了两个按钮。他们在窗口调整时，会保持处于那个位置。我们使用了 <tt class="docutils literal"><span class="pre">QtGui.HBoxLayout</span></tt> 和 <tt class="docutils literal"><span class="pre">QtGui.QVBoxLayout</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">okButton</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&quot;OK&quot;</span><span class="p">)</span>
<span class="n">cancelButton</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&quot;Cancel&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>此处，我们创建了两个按钮。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">hbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QHBoxLayout</span><span class="p">()</span>
<span class="n">hbox</span><span class="o">.</span><span class="n">addStretch</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">okButton</span><span class="p">)</span>
<span class="n">hbox</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">cancelButton</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了一个水平的 layout 。增加了缩放比例和按钮。这个缩放在两个按钮前增加了合适的缩放空白。这就使得按钮在窗口的右边。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">vbox</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QVBoxLayout</span><span class="p">()</span>
<span class="n">vbox</span><span class="o">.</span><span class="n">addStretch</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">vbox</span><span class="o">.</span><span class="n">addLayout</span><span class="p">(</span><span class="n">hbox</span><span class="p">)</span>
</pre></div>
</div>
<p>为了创建必要的 layout，我们把水平的 layout 放置到垂直的 layout 中。而垂直盒子中的缩放因子使得水平的盒子处于窗口的底部。</p>
<p>最后，我们设置了窗口的 layout 。</p>
</div>
<div class="section" id="qtgui-qgridlayout">
<h2>QtGui.QGridLayout<a class="headerlink" href="#qtgui-qgridlayout" title="Permalink to this headline">&#182;</a></h2>
<p>最通用的 layout 类是网格 layout 。这个 layout 把空间分为行和列。为了创建一个网格的 layout，我们可以使用 <tt class="docutils literal"><span class="pre">QtGui.QGridLayout</span></tt> 类。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we create a skeleton</span>
<span class="sd">of a calculator using a QtGui.QGridLayout.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">names</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;Cls&#39;</span><span class="p">,</span> <span class="s">&#39;Bck&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;Close&#39;</span><span class="p">,</span> <span class="s">&#39;7&#39;</span><span class="p">,</span> <span class="s">&#39;8&#39;</span><span class="p">,</span> <span class="s">&#39;9&#39;</span><span class="p">,</span> <span class="s">&#39;/&#39;</span><span class="p">,</span>
                <span class="s">&#39;4&#39;</span><span class="p">,</span> <span class="s">&#39;5&#39;</span><span class="p">,</span> <span class="s">&#39;6&#39;</span><span class="p">,</span> <span class="s">&#39;*&#39;</span><span class="p">,</span> <span class="s">&#39;1&#39;</span><span class="p">,</span> <span class="s">&#39;2&#39;</span><span class="p">,</span> <span class="s">&#39;3&#39;</span><span class="p">,</span> <span class="s">&#39;-&#39;</span><span class="p">,</span>
                <span class="s">&#39;0&#39;</span><span class="p">,</span> <span class="s">&#39;.&#39;</span><span class="p">,</span> <span class="s">&#39;=&#39;</span><span class="p">,</span> <span class="s">&#39;+&#39;</span><span class="p">]</span>
        <span class="n">grid</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QGridLayout</span><span class="p">()</span>
        <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">pos</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span>
                <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span>
                <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span>
                <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span> <span class="p">),</span>
                <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">)]</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">names</span><span class="p">:</span>
            <span class="n">button</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">j</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
                <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span> <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">button</span><span class="p">,</span> <span class="n">pos</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">pos</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
            <span class="n">j</span> <span class="o">=</span> <span class="n">j</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">grid</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Calculator&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在我们的例子中，我们创建了一组按钮，并以网格放置。为了填补一个空格，我们增加了一个 <tt class="docutils literal"><span class="pre">QtGui.QLable</span></tt> 的 widget 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">grid</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QGridLayout</span><span class="p">()</span>
</pre></div>
</div>
<p>这里，我们创建了一个网格 layout 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">j</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
    <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QLable</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">button</span><span class="p">,</span> <span class="n">pos</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">pos</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>为了把一个 widget 增加到网格中，我们调用了 <tt class="docutils literal"><span class="pre">addWidget()</span></tt> 方法。参数是 widget，行和列的数字。</p>
</div>
<div class="section" id="id2">
<h2>再看例子<a class="headerlink" href="#id2" title="Permalink to this headline">&#182;</a></h2>
<p>在网格中，widget 可以跨多行或多列。下面的例子我们就将介绍这个。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we create a bit</span>
<span class="sd">more complicated window layout using</span>
<span class="sd">the QtGui.QGridLayout manager.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">title</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;Title&#39;</span><span class="p">)</span>
        <span class="n">author</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;Author&#39;</span><span class="p">)</span>
        <span class="n">review</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLabel</span><span class="p">(</span><span class="s">&#39;Review&#39;</span><span class="p">)</span>
        <span class="n">titleEdit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">()</span>
        <span class="n">authorEdit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QLineEdit</span><span class="p">()</span>
        <span class="n">reviewEdit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QTextEdit</span><span class="p">()</span>
        <span class="n">grid</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QGridLayout</span><span class="p">()</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">setSpacing</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">title</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">titleEdit</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">author</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">authorEdit</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">review</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
        <span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">reviewEdit</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setLayout</span><span class="p">(</span><span class="n">grid</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">350</span><span class="p">,</span> <span class="mi">300</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Review&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>我们创建了一个窗口，其中有三个标签，两个行编辑区及一个文本编辑区。layout 由 <tt class="docutils literal"><span class="pre">QtGui.QGridLayout</span></tt> 创建。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">grid</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QGridLayout</span><span class="p">()</span>
<span class="n">grid</span><span class="o">.</span><span class="n">setSpacing</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了网格 layout，并设置了 widget 间的间隔。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">grid</span><span class="o">.</span><span class="n">addWidget</span><span class="p">(</span><span class="n">reviewEdit</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<p>如果我们增加一个 widget 到网格中，我们可以提供行和列的跨度。我们使得 reviewEdit 的跨度为 5 。</p>
<hr class="docutils" />
<p>这个部分我们讲述了 layout 管理。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/164983.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-05 10:04 <a href="http://www.cppblog.com/mirguest/archive/2012/02/05/164983.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]在 PyQt4 中的菜单和工具栏</title><link>http://www.cppblog.com/mirguest/archive/2012/02/05/164982.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 05 Feb 2012 02:03:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/05/164982.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164982.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/05/164982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164982.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164982.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4">
<h1>在 PyQt4 中的菜单和工具栏<a class="headerlink" href="#pyqt4" title="Permalink to this headline">&#182;</a></h1>
<p>在本部分中，我们将要创建菜单和工具栏。菜单就是在菜单栏中的一组命令。工具栏就是一组常用命令的按钮。</p>
<div class="section" id="id1">
<h2>主窗口<a class="headerlink" href="#id1" title="Permalink to this headline">&#182;</a></h2>
<p><tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 类提供了一个应用的主窗口。这使得我们可以创建典型的应用框架，包括状态栏，工具栏和菜单。</p>
</div>
<div class="section" id="id2">
<h2>状态栏<a class="headerlink" href="#id2" title="Permalink to this headline">&#182;</a></h2>
<p>状态栏主要用于显示状态信息。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program creates a statusbar.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: September 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span><span class="o">.</span><span class="n">showMessage</span><span class="p">(</span><span class="s">&#39;Ready&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Statusbar&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>状态栏由 <tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 帮忙创建。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span><span class="o">.</span><span class="n">showMessage</span><span class="p">(</span><span class="s">&#39;Ready&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>为了得到状态栏，我们调用了 <tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 的 <tt class="docutils literal"><span class="pre">statusBar()</span></tt> 方法。第一次调用创建了状态栏，随后返回 statusbar 对象。接着我们调用 <tt class="docutils literal"><span class="pre">showMessage</span></tt> 在状态栏上显示了一条消息。</p>
</div>
<div class="section" id="id3">
<h2>菜单栏<a class="headerlink" href="#id3" title="Permalink to this headline">&#182;</a></h2>
<p>菜单栏是 GUI 应用中很常用的一部分。它是在多个菜单中命令的集合。在 console 应用中，我们需要记住命令和它们的选项。而这里，我们把很多命令按照逻辑进行分组。这就使得学习使用一个新的应用的时间可以减少。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program creates a menubar. The</span>
<span class="sd">menubar has one menu with an exit action.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: August 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">exitAction</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QAction</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;exit.png&#39;</span><span class="p">),</span> <span class="s">&#39;&amp;Exit&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">setShortcut</span><span class="p">(</span><span class="s">&#39;Ctrl+Q&#39;</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">setStatusTip</span><span class="p">(</span><span class="s">&#39;Exit application&#39;</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">triggered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">qApp</span><span class="o">.</span><span class="n">quit</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span>
        <span class="n">menubar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">menuBar</span><span class="p">()</span>
        <span class="n">fileMenu</span> <span class="o">=</span> <span class="n">menubar</span><span class="o">.</span><span class="n">addMenu</span><span class="p">(</span><span class="s">&#39;&amp;File&#39;</span><span class="p">)</span>
        <span class="n">fileMenu</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">exitAction</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Menubar&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在上面的例子中，我们创建了只有一个菜单的菜单栏。这个菜单中包含了一个 action ，如果选中后就会终止应用。我们还创建了一个状态栏。而且也可以用快捷键 <em>Ctrl + Q</em> 退出。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">exitAction</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QAction</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;exit.png&#39;</span><span class="p">))</span>
<span class="n">exitAction</span><span class="o">.</span><span class="n">setShortcut</span><span class="p">(</span><span class="s">&#39;Ctrl+Q&#39;</span><span class="p">)</span>
<span class="n">exitAction</span><span class="o">.</span><span class="n">setStatusTip</span><span class="p">(</span><span class="s">&#39;Exit application&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">QtGui.QAction</span></tt> 是一个 action 的抽象，包括菜单栏，工具栏或者是自定义的快捷键。在上面的三行，我们创建了一个 action ，有一个指定的图标以及 &#8216;Exit&#8217; 标签。而且，这个 action 定义了快捷键。第三行则是创建一个提示，当我们把鼠标指针移到菜单条目上，将在状态栏中显示相应的提示。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">exitAction</span><span class="o">.</span><span class="n">triggered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">qApp</span><span class="o">.</span><span class="n">quit</span><span class="p">)</span>
</pre></div>
</div>
<p>当我们选择了这个特定的 action ，触发的信号就被发送了。这个信号和 <tt class="docutils literal"><span class="pre">QtGui.QApplication</span></tt> 的 <tt class="docutils literal"><span class="pre">quit()</span></tt> 方法联系在一起。这就终止了应用。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">menubar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">menuBar</span><span class="p">()</span>
<span class="n">fileMenu</span> <span class="o">=</span> <span class="n">menubar</span><span class="o">.</span><span class="n">addMenu</span><span class="p">(</span><span class="s">&#39;&amp;File&#39;</span><span class="p">)</span>
<span class="n">fileMenu</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">exitAction</span><span class="p">)</span>
</pre></div>
</div>
<p>此处三行，创建了一个菜单栏。我们往菜单栏中添加了一个名为 File 的菜单，而且，我们把 <em>Alt + F</em> 设为了快捷方式。然后我们再把 exitAction 放到了 fileMenu 中。</p>
</div>
<div class="section" id="id4">
<h2>工具栏<a class="headerlink" href="#id4" title="Permalink to this headline">&#182;</a></h2>
<p>在一个应用中，菜单把所有的命令分组。而工具栏中则提供了常用命令的快捷方式。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program creates a toolbar.</span>
<span class="sd">The toolbar has one action, which</span>
<span class="sd">terminates the application, if triggered.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: September 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">exitAction</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QAction</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;exit24.png&#39;</span><span class="p">),</span> <span class="s">&#39;Exit&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">setShortcut</span><span class="p">(</span><span class="s">&#39;Ctrl+Q&#39;</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">triggered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">qApp</span><span class="o">.</span><span class="n">quit</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">toolbar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">addToolBar</span><span class="p">(</span><span class="s">&#39;Exit&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">toolbar</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">exitAction</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Toolbar&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在上面的例子中，我们创建了一个简单的工具栏。这个工具栏有一个退出的 action ，当触发时，就会终止应用。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">exitAction</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QAction</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;exit24.png&#39;</span><span class="p">),</span> <span class="s">&#39;Exit&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="n">exitAction</span><span class="o">.</span><span class="n">setShortcut</span><span class="p">(</span><span class="s">&#39;Ctrl+Q&#39;</span><span class="p">)</span>
<span class="n">exitAction</span><span class="o">.</span><span class="n">triggered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">qApp</span><span class="o">.</span><span class="n">quit</span><span class="p">)</span>
</pre></div>
</div>
<p>和前面菜单栏的例子一样，我们也创建了一个 action 对象。这个对象有一个标签，图标以及快捷方式。而且 <tt class="docutils literal"><span class="pre">QtGui.QMainWindow</span></tt> 的 <tt class="docutils literal"><span class="pre">quit()</span></tt> 方法和其触发信号关联了起来。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">toolbar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">addToolBar</span><span class="p">(</span><span class="s">&#39;Exit&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">toolbar</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">exitAction</span><span class="p">)</span>
</pre></div>
</div>
<p>这里，我们创建了工具栏，并把 action 对象放入。</p>
</div>
<div class="section" id="id5">
<h2>放到一起<a class="headerlink" href="#id5" title="Permalink to this headline">&#182;</a></h2>
<p>本节的最后，我们将创建菜单栏，工具栏和状态栏。而且也会创建一个居中的 widget 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program creates a skeleton of</span>
<span class="sd">a classic GUI application with a menubar,</span>
<span class="sd">toolbar, statusbar and a central widget.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: September 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QMainWindow</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">textEdit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QTextEdit</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setCentralWidget</span><span class="p">(</span><span class="n">textEdit</span><span class="p">)</span>
        <span class="n">exitAction</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QAction</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;exit24.png&#39;</span><span class="p">),</span> <span class="s">&#39;Exit&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">setShortcut</span><span class="p">(</span><span class="s">&#39;Ctrl+Q&#39;</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">setStatusTip</span><span class="p">(</span><span class="s">&#39;Exit application&#39;</span><span class="p">)</span>
        <span class="n">exitAction</span><span class="o">.</span><span class="n">triggered</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">close</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">statusBar</span><span class="p">()</span>
        <span class="n">menubar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">menuBar</span><span class="p">()</span>
        <span class="n">fileMenu</span> <span class="o">=</span> <span class="n">menubar</span><span class="o">.</span><span class="n">addMenu</span><span class="p">(</span><span class="s">&#39;&amp;File&#39;</span><span class="p">)</span>
        <span class="n">fileMenu</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">exitAction</span><span class="p">)</span>
        <span class="n">toolbar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">addToolBar</span><span class="p">(</span><span class="s">&#39;Exit&#39;</span><span class="p">)</span>
        <span class="n">toolbar</span><span class="o">.</span><span class="n">addAction</span><span class="p">(</span><span class="n">exitAction</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">350</span><span class="p">,</span> <span class="mi">250</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Main window&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>这段代码创建了一个有菜单栏，工具栏及状态栏典型的 GUI 应用。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">textEdit</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QTextEdit</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">setCentralWidget</span><span class="p">(</span><span class="n">textEdit</span><span class="p">)</span>
</pre></div>
</div>
<p>这里，我们创建了一个 text edit 的 widget 。我们把其设为 central widget。central widget会占用所有的空间。</p>
<hr class="docutils" />
<p>在本部分，我们学习了菜单，工具栏，状态栏和主应用窗口。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/164982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-05 10:03 <a href="http://www.cppblog.com/mirguest/archive/2012/02/05/164982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]第一个 PyQt4 的程序</title><link>http://www.cppblog.com/mirguest/archive/2012/02/05/164981.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 05 Feb 2012 02:00:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/05/164981.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164981.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/05/164981.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164981.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164981.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4">
<h1>第一个 PyQt4 的程序<a class="headerlink" href="#pyqt4" title="Permalink to this headline">&#182;</a></h1>
<p>本部分我们将学到一些基本的功能。</p>
<div class="section" id="id1">
<h2>简单的例子<a class="headerlink" href="#id1" title="Permalink to this headline">&#182;</a></h2>
<p>这里的代码非常简单。它仅仅显示一个小小的窗口。然后我们可以对这个窗口做很多事情。我们可以调正其大小，最大化，最小化。这个需要很多的代码。但某些人已经编写了这样的功能。因为在很多应用中重复出现了这样的代码，没有必要一再编写这样的代码。所以，对于程序员这样的代码就被隐藏了。PyQt4 是一个高层的工具。如果以更底层的开发，下面的例子可以要写上很多行。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">In this example, we create a simple</span>
<span class="sd">window in PyQt4.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">w</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">()</span>
    <span class="n">w</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
    <span class="n">w</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">)</span>
    <span class="n">w</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Simple&#39;</span><span class="p">)</span>
    <span class="n">w</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>上面的代码将会在屏幕上显示一个小窗口。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
</pre></div>
</div>
<p>这里我们提供一些必要的导入。最基本的 GUI widget 都在 QtGui 模块中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
</pre></div>
</div>
<p>每个 PyQt4 应用必须创建一个 application 对象。此 application 对象处于 QtGui 模块中。参数 <tt class="docutils literal"><span class="pre">sys.argv</span></tt> 是从命令行获取的参数列表。Python 脚本可以从 shell 中运行。这是一种控制启动我们脚本的方式。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">w</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">()</span>
</pre></div>
</div>
<p>在 PyQt4 中， <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 是所有用户接口对象的基类。我们提供了 <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 的默认构造函数。默认的构造函数没有父类。一个没有父类的 widget 称为一个窗口。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">w</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">resize()</span></tt> 方法调正了 widget 的大小。它宽 250px ，高 150px 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">w</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">)</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">move()</span></tt> 方法把 widget 移到屏幕坐标为 <tt class="docutils literal"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">300,</span> <span class="pre">y</span> <span class="pre">=</span> <span class="pre">300</span></tt> 的地方。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">w</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Simple&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>这里，我们设置了窗口的标题。标题在标题栏中显示。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">w</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</pre></div>
</div>
<p><tt class="docutils literal"><span class="pre">show()</span></tt> 方法把这个 widget 显示到屏幕上。一个 widget 最先在内存中创建，然后显示于屏幕上。</p>
<div class="highlight-python"><pre>sys.exit(app.exec())</pre>
</div>
<p>最后，我们进入程序的主循环。事件的处理就从此时开始。主循环接受从窗口系统发送的事例，并把它们发给应用的 widget 。如果我们调用了 <tt class="docutils literal"><span class="pre">exit()</span></tt> 或者主窗口被销毁，主循环就终止了。 <tt class="docutils literal"><span class="pre">sys.exit()</span></tt> 方法确保完全退出。整个环境将被通知应用如何终止。</p>
<p><tt class="docutils literal"><span class="pre">exec_()</span></tt> 方法有一个下划线。这是由于 exec 是 Python 中的关键字。因此使用了 <tt class="docutils literal"><span class="pre">exec_()</span></tt> 。</p>
</div>
<div class="section" id="id2">
<h2>一个应用的图标<a class="headerlink" href="#id2" title="Permalink to this headline">&#182;</a></h2>
<p>应用的图标就是一块小的图像，显示于标题栏的左上角。下面的例子讲说明在 PyQt4 中是怎么做的。我们也会接受一些新的方法。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This example shows an icon</span>
<span class="sd">in the titlebar of the window.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Icon&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowIcon</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;web.png&#39;</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>先前的例子是以过程式编写的。Python 支持过程式和面向对象式的编程。在 PyQt4 中编程就意味着以 OOP 编程。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
</pre></div>
</div>
<p>在面向对象编程中三个最重要的东西是类，数据及方法。这里，我们创建了一个新的类称为 <tt class="docutils literal"><span class="pre">Example</span></tt> 。这个类从 <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 派生。这就意味着我们必须调用两个构造器。第一个是 Example 这个类，第二个是被继承的类。 <tt class="docutils literal"><span class="pre">super()</span></tt> 方法就返回了 Example 的父对象，然后我们调用了其构造器。在 Python 中 <tt class="docutils literal"><span class="pre">__init__()</span></tt> 是构造器。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
</pre></div>
</div>
<p>GUI 的创建就委托给了 <tt class="docutils literal"><span class="pre">initUI()</span></tt> 这个方法。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Icon&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">setWindowIcon</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QIcon</span><span class="p">(</span><span class="s">&#39;web.png&#39;</span><span class="p">))</span>
</pre></div>
</div>
<p>这三个方法都是从类 <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 中继承下来的。 <tt class="docutils literal"><span class="pre">setGeometry()</span></tt> 做了两件事情。首先是定位，然后是设置窗口大小。
前两个参数是窗口的 x 和 y 。第三个参数是宽度，第四个是高度。事实上，它结合了 <tt class="docutils literal"><span class="pre">resize()</span></tt> 和 <tt class="docutils literal"><span class="pre">move()</span></tt> 。最后一个方法设置了应用的图标。为此，我们创建了 <tt class="docutils literal"><span class="pre">QtGui.QIcon</span></tt> 对象。 <tt class="docutils literal"><span class="pre">QtGui.QIcon</span></tt> 接受要显示图标的路径。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>启动代码放在了 <tt class="docutils literal"><span class="pre">main()</span></tt> 方法中。这是 Python 的惯用方式。</p>
</div>
<div class="section" id="id3">
<h2>显示提示<a class="headerlink" href="#id3" title="Permalink to this headline">&#182;</a></h2>
<p>我们可以给任何一个 widget 提供 balloon 式的提示。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This example shows a tooltip on</span>
<span class="sd">a window and a button</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">QtGui</span><span class="o">.</span><span class="n">QToolTip</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QFont</span><span class="p">(</span><span class="s">&#39;SansSerif&#39;</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setToolTip</span><span class="p">(</span><span class="s">&#39;This is a &lt;b&gt;QWidget&lt;/b&gt; widget&#39;</span><span class="p">)</span>
        <span class="n">btn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Button&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">btn</span><span class="o">.</span><span class="n">setToolTip</span><span class="p">(</span><span class="s">&#39;This is a &lt;b&gt;QPushButton&lt;/b&gt; widget&#39;</span><span class="p">)</span>
        <span class="n">btn</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="n">btn</span><span class="o">.</span><span class="n">sizeHint</span><span class="p">())</span>
        <span class="n">btn</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Tooltips&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个例子中，我们给 widget 都设置了 tooltip 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">QtGui</span><span class="o">.</span><span class="n">QToolTip</span><span class="o">.</span><span class="n">setFont</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QFont</span><span class="p">(</span><span class="s">&#39;SansSerif&#39;</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>
</pre></div>
</div>
<p>这个静态方法设置了 tooltip 的字体。我们使用 10px 的 SansSerif 字体。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">setToolTip</span><span class="p">(</span><span class="s">&#39;This is a &lt;b&gt;QWidget&lt;/b&gt; widget&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>为了创建 tooltip， 我们调用了 <tt class="docutils literal"><span class="pre">setTooltip()</span></tt> 方法。我们可以使用富文本格式（rich text formatting）。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">btn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Button&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
<span class="n">btn</span><span class="o">.</span><span class="n">setToolTip</span><span class="p">(</span><span class="s">&#39;This is a &lt;b&gt;QPushButton&lt;/b&gt; widget&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了一个按钮并为它设置了 tooltip 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">btn</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="n">btn</span><span class="o">.</span><span class="n">sizeHint</span><span class="p">())</span>
<span class="n">btn</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
</pre></div>
</div>
<p>这个按钮被重新设置大小并移到窗口相应的位置。 <tt class="docutils literal"><span class="pre">sizeHint()</span></tt> 方法给出一个推荐的大小。</p>
</div>
<div class="section" id="id4">
<h2>关闭窗口<a class="headerlink" href="#id4" title="Permalink to this headline">&#182;</a></h2>
<p>关闭窗口最直观的方式就是点击标题栏上的 <em>x</em> 。在后面的例子中，我们将会展示如何编程来关闭窗口。我们将会简单的接触信号（signal）和槽（slot）。</p>
<p>下面是 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 的构造器，我们将在例子中用到。</p>
<div class="highlight-python"><pre>QPushButton(string text, QWidget parent = None)</pre>
</div>
<p>参数中的 text 是将在按钮中显示的文字。而 parent 则是将要放置我们按钮的 widget 。在我们这个情况下则是 <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program creates a quit</span>
<span class="sd">button. When we press the button,</span>
<span class="sd">the application terminates.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">qbtn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Quit&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
        <span class="n">qbtn</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">QCoreApplication</span><span class="o">.</span><span class="n">instance</span><span class="p">()</span><span class="o">.</span><span class="n">quit</span><span class="p">)</span>
        <span class="n">qbtn</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="n">qbtn</span><span class="o">.</span><span class="n">sizeHint</span><span class="p">())</span>
        <span class="n">qbtn</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">50</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Quit button&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>在这个例子中，我们创建了一个退出按钮。按了这个后，应用就将结束。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span><span class="p">,</span> <span class="n">QtCore</span>
</pre></div>
</div>
<p>在这个例子中，我们用到了 QtCore 模块中的一个对象。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">qbtn</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QPushButton</span><span class="p">(</span><span class="s">&#39;Quit&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
</pre></div>
</div>
<p>我们创建了一个按钮。这个按钮是 <tt class="docutils literal"><span class="pre">QtGui.QPushButton</span></tt> 的实例。第一个参数是按钮的标签。第二个是父 widget 。此处的父 widget 是 Example 这个 widget。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">qbtn</span><span class="o">.</span><span class="n">clicked</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">QtCore</span><span class="o">.</span><span class="n">QCoreApplication</span><span class="o">.</span><span class="n">instance</span><span class="p">()</span><span class="o">.</span><span class="n">quit</span><span class="p">)</span>
</pre></div>
</div>
<p>在 PyQt4 中，事件系统（event processing system）建立于信号和槽机制。如果我们点击了一个按钮，点击的信号就被发送了。槽可以是 Qt 的槽或者任何 Python 可调用的。 <tt class="docutils literal"><span class="pre">QtCore.QCoreApplication</span></tt> 包含了事件的主循环。它处理所有的事件。 <tt class="docutils literal"><span class="pre">instance()</span></tt> 方法给我们它当前的实例。注意， <tt class="docutils literal"><span class="pre">QtCore.QCoreApplication</span></tt> 是和 <tt class="docutils literal"><span class="pre">QtGui.QApplication</span></tt> 一起创建的。点击的信号则和终止应用的 <tt class="docutils literal"><span class="pre">quit()</span></tt> 方法连接了起来。通信是在两个对象间完成。一个是发送者，也就是按钮，另一个是接受者，就是应用对象。</p>
</div>
<div class="section" id="id5">
<h2>消息框<a class="headerlink" href="#id5" title="Permalink to this headline">&#182;</a></h2>
<p>默认情况下，如果我们点击了关闭按钮， <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> 就被关闭了。有些时候我们需要修改默认的行为。例如，如果在编辑器中我们对某文件进行了修改。那么我们退出时就要弹出消息框进行确认。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program shows a confirmation</span>
<span class="sd">message box when we click on the close</span>
<span class="sd">button of the application window.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setGeometry</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">300</span><span class="p">,</span> <span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Message box&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">closeEvent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
        <span class="n">reply</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">question</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;Message&#39;</span><span class="p">,</span>
            <span class="s">&quot;Are you sure to quit?&quot;</span><span class="p">,</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">Yes</span> <span class="o">|</span>
            <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">No</span><span class="p">,</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">No</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">reply</span> <span class="o">==</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">Yes</span><span class="p">:</span>
            <span class="n">event</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">event</span><span class="o">.</span><span class="n">ignore</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>如果我们关闭 <tt class="docutils literal"><span class="pre">QtGui.QWidget</span></tt> ，就会产生 <tt class="docutils literal"><span class="pre">QtGui.QCloseEvent</span></tt> 。为了修改 widget 的行为，我们需要重新实现 <tt class="docutils literal"><span class="pre">closeEvent()</span></tt> 。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">reply</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">question</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;Message&#39;</span><span class="p">,</span>
    <span class="s">&quot;Are you sure to quit?&quot;</span><span class="p">,</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">Yes</span> <span class="o">|</span>
    <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">No</span><span class="p">,</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">No</span><span class="p">)</span>
</pre></div>
</div>
<p>我们的消息框中有两个按钮， <tt class="docutils literal"><span class="pre">Yes</span></tt> 和 <tt class="docutils literal"><span class="pre">No</span></tt> 。第一个字符串显示在标题栏上。第二个则是对话框中的消息。第三个参数指定了要显示的按钮。最后的则是默认的按钮。焦点是默认在这个按钮上。返回值存在 <tt class="docutils literal"><span class="pre">reply</span></tt> 变量中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">if</span> <span class="n">reply</span> <span class="o">==</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QMessageBox</span><span class="o">.</span><span class="n">Yes</span><span class="p">:</span>
    <span class="n">event</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
    <span class="n">event</span><span class="o">.</span><span class="n">ignore</span><span class="p">()</span>
</pre></div>
</div>
<p>这里，我们可以测试返回值。如果我们点击了 Yes 按钮，我们接受了关闭应用的事件。否则，忽略这个事件。</p>
</div>
<div class="section" id="id6">
<h2>居中窗口<a class="headerlink" href="#id6" title="Permalink to this headline">&#182;</a></h2>
<p>下面的脚本将会演示如何把窗口在屏幕中居中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr/bin/python</span>
<span class="c"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">ZetCode PyQt4 tutorial</span>
<span class="sd">This program centers a window</span>
<span class="sd">on the screen.</span>
<span class="sd">author: Jan Bodnar</span>
<span class="sd">website: zetcode.com</span>
<span class="sd">last edited: October 2011</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">QtGui</span>
<span class="k">class</span> <span class="nc">Example</span><span class="p">(</span><span class="n">QtGui</span><span class="o">.</span><span class="n">QWidget</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">Example</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">initUI</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">initUI</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">center</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">setWindowTitle</span><span class="p">(</span><span class="s">&#39;Center&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
    <span class="k">def</span> <span class="nf">center</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">qr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">frameGeometry</span><span class="p">()</span>
        <span class="n">cp</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QDesktopWidget</span><span class="p">()</span><span class="o">.</span><span class="n">availableGeometry</span><span class="p">()</span><span class="o">.</span><span class="n">center</span><span class="p">()</span>
        <span class="n">qr</span><span class="o">.</span><span class="n">moveCenter</span><span class="p">(</span><span class="n">cp</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">qr</span><span class="o">.</span><span class="n">topLeft</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">app</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
    <span class="n">ex</span> <span class="o">=</span> <span class="n">Example</span><span class="p">()</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">exec_</span><span class="p">())</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>
</div>
<p>将会把窗口居中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">center</span><span class="p">()</span>
</pre></div>
</div>
<p>把窗口居中的代码放在了自定制的 <tt class="docutils literal"><span class="pre">center()</span></tt> 方法中。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">qr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">frameGeometry</span><span class="p">()</span>
</pre></div>
</div>
<p>我们得到一个指定主窗口几何的矩形。这个包含任何窗口框架。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">cp</span> <span class="o">=</span> <span class="n">QtGui</span><span class="o">.</span><span class="n">QDesktopWidget</span><span class="p">()</span><span class="o">.</span><span class="n">availableGeometry</span><span class="p">()</span><span class="o">.</span><span class="n">center</span><span class="p">()</span>
</pre></div>
</div>
<p>我们计算出显示器的分辨率，并且从分辨率中得到了中间点。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">qr</span><span class="o">.</span><span class="n">moveCenter</span><span class="p">(</span><span class="n">cp</span><span class="p">)</span>
</pre></div>
</div>
<p>我们的矩形已经有其宽度和高度了。现在，我们把矩形的中心移到屏幕的中心。矩形的大小并未改变。</p>
<div class="highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">qr</span><span class="o">.</span><span class="n">topLeft</span><span class="p">())</span>
</pre></div>
</div>
<p>我们应用窗口的左上角移到 qr 的左上角，这样就完成了居中。</p>
<hr class="docutils" />
<p>在本部分，我们涉及一些基本的知识。</p>
</div>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/164981.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-05 10:00 <a href="http://www.cppblog.com/mirguest/archive/2012/02/05/164981.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python][PyQt4]PyQt4 toolkit 介绍</title><link>http://www.cppblog.com/mirguest/archive/2012/02/05/164980.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Sun, 05 Feb 2012 01:58:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/05/164980.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164980.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/05/164980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164980.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164980.html</trackback:ping><description><![CDATA[<div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="pyqt4-toolkit">
<h1>PyQt4 toolkit 介绍<a class="headerlink" href="#pyqt4-toolkit" title="Permalink to this headline">&#182;</a></h1>
<div class="section" id="id1">
<h2>关于此文档<a class="headerlink" href="#id1" title="Permalink to this headline">&#182;</a></h2>
<p>本文档是一篇介绍 PyQt4 的教程。本教程的目的是让你开始使用 PyQt4 的toolkit。教程是在 Linux 中编写及测试。</p>
</div>
<div class="section" id="pyqt4">
<h2>关于 PyQt4<a class="headerlink" href="#pyqt4" title="Permalink to this headline">&#182;</a></h2>
<p>PyQt4 是用于创建 GUI 应用的 toolkit 。它是 Python 和 Qt 库的混合。Qt 库是一种很强大的 GUI 库。PyQt4 的官方网站在 <cite>www.riverbankcomputing.co.uk/news</cite> 。其开发者是 <strong>Phil Thompson</strong> 。</p>
<p>PyQt4 以一系列 Python 模块实现。它有超过 300 个类，以及几乎 6000 的函数及方法。它是一个多平台的 toolkit。它可以运行于大多数的操作系统。包括 Unix，Windows 和 Mac。PyQt4 具有双重的证书。开发者可以在 GPL 和商业的证书间选择。早先，GPL 只适用于 Unix。但从 PyQt4 开始，GPL 适用于所有支持的平台。</p>
<p>由于有很多类，所以它们被划分为几个模块。</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">QtCore</span></tt></li>
<li><tt class="docutils literal"><span class="pre">QtGui</span></tt></li>
<li><tt class="docutils literal"><span class="pre">QtNetwork</span></tt></li>
<li><tt class="docutils literal"><span class="pre">QtXml</span></tt></li>
<li><tt class="docutils literal"><span class="pre">QtSvg</span></tt></li>
<li><tt class="docutils literal"><span class="pre">QtOpenGL</span></tt></li>
<li><tt class="docutils literal"><span class="pre">QtSql</span></tt></li>
</ul>
<p><tt class="docutils literal"><span class="pre">QtCore</span></tt> 模块包含核心的非GUI的功能。这个模块用于时间，文件和目录，多种数据类型，流，url，mime type，线程或进程。 <tt class="docutils literal"><span class="pre">QtGui</span></tt> 模块包含图形的组件和相关的类。这里包含例如按钮，窗口，状态栏，工具栏，边栏，位图，颜色，字体等。 <tt class="docutils literal"><span class="pre">QtNetwork</span></tt> 模块包含用于网络编程的类。这些类允许编写 TCP/IP 和 UDP 客户端及服务端。它们使得网络编程更加简单和可移植。 <tt class="docutils literal"><span class="pre">QtXml</span></tt> 包含用于处理 xml 文件的类。此模块提供了包括 SAX 和 DOM API 的实现。 <tt class="docutils literal"><span class="pre">QtSvg</span></tt> 模块提供了用于显示 SVG 文件内容的类。Scalable Vector Graphics（SVG）是一种用于描述二维图形的语言。 <tt class="docutils literal"><span class="pre">QtOpenGL</span></tt> 模块则用 OpenGL 库表现 3D 及 2D。这个模块可以无缝的把 Qt GUI 库和 OpenGL 库连接起来。 <tt class="docutils literal"><span class="pre">QtSql</span></tt> 库则提供了用于数据库的类。</p>
</div>
<div class="section" id="python">
<h2>Python<a class="headerlink" href="#python" title="Permalink to this headline">&#182;</a></h2>
<p>Python 是一个动态的面向对象的编程语言。这是一个通用的语言。它可以用于很多种软件开发。Python 语言的设计理念就是强调程序员的效率及代码的可读性。Python 最初是由 <strong>Guido van Rossum</strong> 开发。它在 1991 年放出第一版。Python 受到 ABC，Haskell，Java，Lisp，Icon 和 Perl 的启发。它是一个高层次，通用目的，多平台，解释型语言。Python 是一种极简的语言。其中一个最显而易见的特性就是它不使用分号或者花括号。取而代之，Python 使用缩进。目前 Python 有两个主要分支，Python 2.x 和 Python 3.x 。Python 3.x 不向下兼容。它的创建主要是想修改某些设计缺陷并使得语言更加简洁。最常见的 2.x 版本是 2.7.1 , 3.x 版本是 3.1.3 。本教程主要涉及 2.x 版本。大多数代码以 2.x 编写。把代码转到 3.x 需要花费一些时间。目前，Python 是由一大群世界上的志愿者维护。Python 是一个开源软件。</p>
<p>Python 非常适合于一些想学习编程的人。</p>
<p>Python 语言支持多种编程范式。它并不强行要求程序员用哪种特定的范式。Python 支持面向对象及过程式编程。对于函数式编程也有一定的支持。</p>
<p>Python 的官网是 <a class="reference external" href="http://python.org">python.org</a> 。</p>
<p>在 2011年 8月，TIOBE Index 中 Python 的排名是第 8 名。在 langpop.com 中则是第 6 位。</p>
<p>Perl，Python 和 Ruby 是最常用的脚本语言。它们有很多相似之处。它们是相近的对手。</p>
</div>
<div class="section" id="python-toolkit">
<h2>Python toolkit<a class="headerlink" href="#python-toolkit" title="Permalink to this headline">&#182;</a></h2>
<p>为了创建图形用户接口，Python 程序员目前会选择几种，PyQt4，PyGTK 和 wxPython。选择哪个依赖于具体的条件。</p>
<p>因为一些证书的问题和技术需求，一种新的 Qt 和 Python 结合的项目被开发，成为 PySide 。PySide 与 PyQt4 有很高的兼容性。</p>
</div>
</div>
          </div>
        </div>
      </div>
 </div><img src ="http://www.cppblog.com/mirguest/aggbug/164980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-05 09:58 <a href="http://www.cppblog.com/mirguest/archive/2012/02/05/164980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python] Leo 翻译 Some Outline Commands</title><link>http://www.cppblog.com/mirguest/archive/2012/02/03/164877.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Fri, 03 Feb 2012 04:54:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/03/164877.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164877.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/03/164877.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164877.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164877.html</trackback:ping><description><![CDATA[    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="some-outline-commands">
<h1>Some outline commands<a class="headerlink" href="#some-outline-commands" title="Permalink to this headline">&#182;</a></h1>
<p id="index-0">You can use Leo as fairly typical outliner. Click the expansion box of nodes to
show and hide their children.</p>
<p>你可以将 Leo 完全作为一个普通的 outliner 。
点击节点的扩展盒子来显示隐藏它们的子节点。</p>
<p id="index-1">Play around with some of the commands from the Outline menu or from the
minibuffer. The keyboard shortcut and minibuffer key sequence appear in
parentheses. <strong>Note</strong>: as usual, you can use tab completion in the minibuffer.</p>
<p>你可以从 outline 菜单或者 minibuffer 中玩弄一些命令。
键盘的快捷键和 minibuffer 按键总是成对出现。
<strong>注意</strong> ：和普通的一样，在 minibuffer 中你可以使用 tab 进行补全。</p>
<p>Edit Headline (Ctrl+H or &lt;Alt-x&gt;edit-headline&lt;return&gt;)</p>
<blockquote>
<div><p>Begins editing of the headline text of a node.
To end editing, hit &lt;return&gt; or &lt;Ctrl-g&gt;</p>
<p>开始编辑一个节点的 headline 文字。
要结束编辑，输入 &lt;return&gt; 或 &lt;Ctrl-g&gt;</p>
</div></blockquote>
<p>Insert Node (Ctrl+I or &lt;Alt-x&gt;insert-node&lt;return&gt;)</p>
<blockquote>
<div><p>Inserts a new headline into the outline.</p>
<p>往 outline 中插入一个新的 headline 。</p>
</div></blockquote>
<p>Cut Node (Ctrl+Shift+X or &lt;Alt-x&gt;cut-node&lt;return&gt;)</p>
<blockquote>
<div><p>Deletes a node and all its descendants, copying them to the clipboard.</p>
<p>删除一个节点及其所有子节点，然后复制它们到剪贴板。</p>
</div></blockquote>
<p>Paste Node (Ctrl+Shift+V or &lt;Alt-x&gt;paste-node&lt;return&gt;)</p>
<blockquote>
<div><p>Pastes a tree copied by the Cut Node command.</p>
<p>粘贴一个被剪切的树节点。</p>
</div></blockquote>
<p>Copy Node (Ctrl+Shift+C or &lt;Alt-x&gt;copy-node&lt;return&gt;)</p>
<blockquote>
<div><p>Copies a node and all its descendants to clipboard without deleting it from
outline. You can copy a tree from one Leo outline to another using Copy Node
and Paste Node.</p>
<p>复制一个节点及其所有子节点，但是并不将其删除。
你可以使用 Copy 和 Paste 将一棵树从一个 outline 到另一个 outline 。</p>
</div></blockquote>
<p>Contract or Go Left (Alt-Left-Arrow or &lt;Alt-x&gt;contract-or-go-left&lt;return)</p>
<blockquote>
<div><p>Contracts a node if it is expanded, otherwise selects its parent.</p>
<p>如果一个节点是展开的，那么就将其收缩。否则，选中其父节点。</p>
</div></blockquote>
<p>Expand and Go Right (Alt-Right-Arrow or &lt;Alt-x&gt;expand-and-go-right&lt;return&gt;)</p>
<blockquote>
<div><p>Select a node&#8217;s first child, expanding the original node if needed.</p>
<p>选中一个节点的第一个子元素，如果有必要，就展开此节点。</p>
</div></blockquote>
<p>Goto Prev Visible (Alt-Up-Arrow or &lt;Alt-x&gt;goto-prev-visible&lt;return&gt;)</p>
<blockquote>
<div><p>Select the previous visible node.</p>
<p>选中前一个可见的节点。</p>
</div></blockquote>
<p>Goto Next Visible (Alt-Down-Arrow or &lt;Alt-x&gt;goto-next-visible&lt;return&gt;)</p>
<blockquote>
<div><p>Select the next visible node.</p>
<p>选中下一个可见的节点。</p>
</div></blockquote>
<p>Move Up (Ctrl+U or &lt;Alt-x&gt;move-outline-up&lt;return&gt;)</p>
<blockquote>
<div><p>Moves a node up in the outline.</p>
<p>将一个节点上移。</p>
</div></blockquote>
<p>Move Down (Ctrl+D or &lt;Alt-x&gt;move-outline-down&lt;return&gt;)</p>
<blockquote>
<div><p>Moves a node down.</p>
<p>将一个节点下移。</p>
</div></blockquote>
<p>Move Left (Ctrl+L or &lt;Alt-x&gt;move-outline-left&lt;return&gt;)</p>
<blockquote>
<div><p>Moves a node left.</p>
<p>将一个节点左移。</p>
</div></blockquote>
<p>Move Right (Ctrl+R or &lt;Alt-x&gt;move-outline-right&lt;return&gt;)</p>
<blockquote>
<div><p>Moves a node right.</p>
<p>将一个节点右移。</p>
</div></blockquote>
<p>Promote (Ctrl+} or &lt;Alt-x&gt;promote&lt;return&gt;)</p>
<blockquote>
<div><p>Makes all the children of a node to be siblings of the node.</p>
<p>使一个节点的所有子节点与其同级。</p>
</div></blockquote>
<p>Demote (Ctrl+{ or &lt;Alt-x&gt;demote&lt;return&gt;)</p>
<blockquote>
<div><p>Makes all following siblings of a node to be children of the headline.</p>
<p>使一个节点后面的同级节点变为该节点的子节点。</p>
</div></blockquote>
<p>Please experiment with Leo&#8217;s outline now. Move around the tree and
expand/collapse nodes by pressing Alt + arrow keys. This also moves the focus to
tree, so, after pressing Alt + arrow, you can move around by using arrow keys
alone. Return the focus to the body control by pressing Enter.</p>
<p>请现在就试试 Leo 的 outline 。
通过 Alt + 箭头在树中上下移动，展开闭合节点。
这也移动了焦点，所以，在按了 Alt + 箭头后，
你可以直接用方向键了。
按 Enter 可以把焦点移回 body 中。</p>
</div>
          </div>
        </div>
      </div>
<img src ="http://www.cppblog.com/mirguest/aggbug/164877.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-03 12:54 <a href="http://www.cppblog.com/mirguest/archive/2012/02/03/164877.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Python] Leo Tutorial 翻译</title><link>http://www.cppblog.com/mirguest/archive/2012/02/03/164876.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Fri, 03 Feb 2012 04:50:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2012/02/03/164876.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/164876.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2012/02/03/164876.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/164876.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/164876.html</trackback:ping><description><![CDATA[<div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
  <div class="section" id="the-leo-tutorial">
<h1><a class="toc-backref" href="#id1">The Leo Tutorial</a><a class="headerlink" href="#the-leo-tutorial" title="Permalink to this headline">&#182;</a></h1>
<p id="index-0">Leo is a power tool for people who want to organize, study and work with data,
especially complex data like computer programs, books, web sites and data bases.
Superficially, Leo may look like other outlining programs, code folding editors
or class browsers, but it most certainly is not.</p>
<p>Leo 是一个强大的工具，适用于下面的人：希望组织，
管理，研究和处理数据，特别是复杂的数据，
像计算机程序，书籍，网页以及数据库。
表面上看， Leo 像其他 outline 的程序，
代码折叠编辑器或类浏览器，但是事实上，它并不是。</p>
<p>People say Leo is a revolutionary tool, and that Leo is fun to use, even
additive. There is a unique &#8220;Leo way&#8221; of managing data; the term <strong>Leonine</strong>
describes how people treat data in &#8220;the world according to Leo&#8221;. Leo definitely
takes a bit of work to understand. Leo&#8217;s users speak of an &#8220;Aha&#8221; moment, when
they see how these pieces fit together: outline structure is significant
everywhere.  For a more detailed introduction to Leo, see <a class="reference external" href="nutshell.html">Leo in a nutshell</a>.</p>
<p>人们说 Leo 是一个革命性的工具，而且 Leo 用起来很有趣，
而且还有甚者。管理书籍有 Leo 式的方法；单词 <strong>Leonine</strong>
描述了人么如何在 Leo 的世界中管理数据。
Leo 毫无疑问需要慢慢理解。当 Leo 的用户看到了一些片段，他们会说出&#8220;Aha&#8221;:
outline 结构在任何地方都很有意义。具体介绍 Leo 请参考 <a class="reference external" href="nutshell.html">Leo in a nutshell</a> 。</p>
<p>Leo is freely available in source or binary form for all major platforms. You
may download Leo from <a class="reference external" href="http://sourceforge.net/projects/leo/files/Leo/">http://sourceforge.net/projects/leo/files/Leo/</a> Leo is Open
Software and may be freely distributed.</p>
<p>Leo 无论源代码或是二进制程序都是免费的，而且支持大多数的平台。
你可以从 <a class="reference external" href="http://sourceforge.net/projects/leo/files/Leo/">http://sourceforge.net/projects/leo/files/Leo/</a> 下载 Leo。
Leo 是开源软件，而且可以免费发行。</p>
<p><a class="reference external" href="http://webpages.charter.net/edreamleo/front.html">Leo&#8217;s home page</a> contains additional documentation and links to other
resources. For another introduction to Leo, open the file quickstart.leo in the
leo/doc folder.</p>
<p><a class="reference external" href="http://webpages.charter.net/edreamleo/front.html">Leo&#8217;s home page</a> 包含了额外的文档和链接。
关于 Leo 另外的介绍，打开在 leo/doc 目录中的 quickstart.leo 进行查看。</p>
<p>This tutorial introduces the reader to the basic concepts and features of Leo.
It helps to have Leo running for hands-on experience, but all examples here are
self-contained, so the tutorial can be read off-line as well.
See <a class="reference external" href="installing.html">Leo&#8217;s Installation Guide</a>. for detailed installation instructions. If you
have problems installing Leo, please ask for help on <a class="reference external" href="http://groups.google.com/group/leo-editor">Leo&#8217;s forum</a>.</p>
<p>本教程将介绍 Leo 基本的概念和特性。
它帮助你快速的将 Leo 运行起来，所有的例子也是包含于安装包中，
所以你可以离线的阅读。关于安装具体请看 <a class="reference external" href="installing.html">Leo&#8217;s Installation Guide</a> 。
如果你在安装中碰到了困难，请在 <a class="reference external" href="http://groups.google.com/group/leo-editor">Leo&#8217;s forum</a> 中寻求帮助。</p>
<p>This tutorial does not attempt to be comprehensive and cover every single
feature of Leo, or even every commonly used feature. Instead, it introduces many
of Leo&#8217;s most noteworthy features, and will give you a good idea of Leo&#8217;s flavor
and style. After reading it, you will be able to use Leo in basic ways to create
external files, organize data and run simple scripts. You will then be ready to
learn more about Leo&#8217;s many advanced features.</p>
<p>这篇教程并不打算很全面的涉及 Leo 的每个特性，或者甚至是最常用的特性。
相反，它仅仅介绍很多值得注意的特性，并让你对 Leo 有相应的想法，比如它的流派和风格。
在阅读完它之后，你将会用 Leo 创建外部文件，组织数据以及运行简单的脚本。
然后你就会打算学习更多关于 Leo 的高级特性。</p>
<p>The <a class="reference external" href="genindex.html">Glossary</a> is also worth reading.</p>
<p><a class="reference external" href="genindex.html">Glossary</a> 也是很值得一读。</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#the-leo-tutorial" id="id1">The Leo Tutorial</a><ul>
<li><a class="reference internal" href="#leo-s-main-window" id="id2">Leo&#8217;s main window</a></li>
<li><a class="reference internal" href="#external-files-and-file-nodes" id="id3">External files and @file nodes</a></li>
<li><a class="reference internal" href="#creating-external-files-from-outlines" id="id4">Creating external files from outlines</a><ul>
<li><a class="reference internal" href="#section-references" id="id5">Section references</a></li>
<li><a class="reference internal" href="#the-others-directive" id="id6">The @others directive</a></li>
<li><a class="reference internal" href="#the-all-directive" id="id7">The @all directive</a></li>
<li><a class="reference internal" href="#choosing-between-others-and-sections" id="id8">Choosing between @others and sections</a></li>
<li><a class="reference internal" href="#organizing-programs-as-outlines" id="id9">Organizing programs as outlines</a></li>
</ul>
</li>
<li><a class="reference internal" href="#clones-views" id="id10">Clones &amp; views</a></li>
<li><a class="reference internal" href="#more-about-directives" id="id11">More about directives</a></li>
<li><a class="reference internal" href="#scripting-extending-and-customizing-leo" id="id12">Scripting, extending and customizing Leo</a></li>
<li><a class="reference internal" href="#summary" id="id13">Summary</a></li>
<li><a class="reference internal" href="#further-study" id="id14">Further study</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="leo-s-main-window">
<h2><a class="toc-backref" href="#id2">Leo&#8217;s main window</a><a class="headerlink" href="#leo-s-main-window" title="Permalink to this headline">&#182;</a></h2>
<p id="index-2">Let&#8217;s start looking at Leo in detail. We&#8217;ll start with what you see when you
first open Leo, Leo&#8217;s main window. Leo&#8217;s main window, shown below, represents an
entire project. As you can see, the main window contains three panes: the
<strong>outline pane</strong> at the top left, the <strong>log pane</strong> at the top right, and the
<strong>body pane</strong> at the bottom. The window also contains an <strong>icon area</strong> at the
very top, a <strong>status area</strong> and a <strong>mini-buffer</strong> at the very bottom.</p>
<p>让我们更详细的看看 Leo 。我们将从你一打开 Leo 的地方开始讲解。
Leo 的主窗口。 Leo 的主窗口，像下面显示的，代表了一个完整的项目。
正如你见到的，主窗口包含了三个面板：左上方的 <strong>outline pane</strong> ，
右上方的 <strong>log pane</strong> ，以及底部的 <strong>body pane</strong> 。
当然，窗口中还包含了很顶部的 <strong>icon area</strong> ，底部的
<strong>status area</strong> 和 <strong>mini-buffer</strong> 。</p>
<p id="index-3"><img alt="leoMainWindow" src="http://webpages.charter.net/edreamleo/_images/leo-qt-main-window.JPG" /></p>
<p id="index-4">Outline pane</p>
<blockquote>
<div><p>The outline pane shows your project as an outline. The outline
contains all your project&#8217;s data. An outline consists of <strong>nodes</strong>. The
<strong>icon box</strong> is a small icon directly to the left of the headline text.
The border of the icon box is black if the node has been changed.
Smaller icons within the icon box indicate the status of the node:</p>
<p>Outline pane 将你的项目以提纲的形式显示。
outline 中包含了所有你项目的数据。一个 outline 包含 <strong>node</strong> 。
而 <strong>icon box</strong> 是一个紧挨着标题的小的图标。
如果节点中的内容有改变，那么这个的边框就变为黑色的。
而里面更小的图标指示了节点的状态：</p>
<div class="highlight-python"><pre>A small blue box:   the node has body text.
A red vertical bar: the node is marked.
A circular arrow:   the node is cloned.
一个蓝色的盒子： 节点的 body 中包含了文字。
一个垂直的红棒： 节点被标记了。
一个圆形的箭头： 节点被 clone 了。</pre>
</div>
<p>If a node contains children, a smaller icon appears to the left of the icon
box. This icon contains a &#8216;+&#8217; or &#8216;-&#8216; symbol. Clicking this <strong>expansion box</strong>
expands or contracts the node.</p>
<p>如果一个节点包含了子节点，一个更小的图标将在这个的左边显示。
图标中包含了以后 &#8216;+&#8217; 或 &#8216;-&#8216; 这样的符号。
点击这个符号就将这个节点展开或闭合。</p>
</div></blockquote>
<p id="index-5">Node</p>
<blockquote>
<div><p>Each outline node has two two parts, a <strong>headline</strong> and <strong>body text</strong>. The outline pane
shows headlines. Selecting a headline selects the entire node; the node&#8217;s
body text appears in the body pane. Leo uses standard terminology to
describe the relationships of nodes in an outline. We speak of <strong>parent</strong>
nodes, <strong>child</strong> nodes, <strong>ancestor</strong> nodes and <strong>descendant</strong> nodes.</p>
<p>每个节点有两个部分，一个 <strong>headline</strong> 和 <strong>body text</strong> 。
而 outline pane 中显示 headline 。选择一个 headline 就选择了一整个节点；
节点的 body text 部分会显示在 body pane 中。 Leo 使用标准的术语来描述节点的关系。
我们会说 <strong>parent</strong> 节点， <strong>child</strong> 节点， <strong>ancestor</strong> 节点和 <strong>descendant</strong>
节点。</p>
</div></blockquote>
<p id="index-6">Body pane</p>
<blockquote>
<div><p>The body pane contains the body text of the node selected in the
outline pane.</p>
<p>Body pane 包含了被选定的节点的内容。</p>
</div></blockquote>
<p id="index-7">Log pane</p>
<blockquote>
<div><p>The log pane contains informational messages from Leo or your scripts.</p>
<p>Log pane 中包含从 Leo 或你的脚本中来的信息。</p>
</div></blockquote>
<p id="index-8">Icon area</p>
<blockquote>
<div><p>Depending on what plugins are enabled, the icon area may contain
buttons and other widgets that extend what Leo can do. The scripting plugin
makes it easy to add buttons to the icon area.</p>
<p>根据插件的激活情况，此处将会包含不同的按钮和其他的部件，用于扩展 Leo 。
scripting plugin 可以很方便的将按钮放到 icon area 中。</p>
</div></blockquote>
<p id="index-9">Status area</p>
<blockquote>
<div><p>The status area shows the line and column containing the body text&#8217;s cursor,
and the <strong>UNL</strong> (Uniform Node Location), the path from the top of the outline
to the selected node.  This path will change as you change outline nodes.</p>
<p>Status area 显示光标所在行和列，以及 <strong>UNL</strong> （Uniform Node Location），
从顶层节点到当前节点的路径。这个路径将随着你的选择而改变。</p>
</div></blockquote>
<p id="index-10">Minibuffer</p>
<blockquote>
<div><p>You can type command and search strings in the minibuffer. It works much
like the Emacs mini-buffer. To enter a command, type &lt;Alt-x&gt; followed by the
command name and then &lt;return&gt;. To type a search string, type &lt;ctrl-f&gt;
followed by the search string and then &lt;return&gt;. For full details, see
<a class="reference external" href="commands.html">Using Leo&#8217;s Commands</a>.</p>
<p>你可以在 minibuffer 中输入命令以及搜索的字符串。
这个和 Emacs 中的 mini-buffer 非常相似。
为了输入一个命令，输入 &lt;Alt-x&gt; 然后后面输入命令的名称，
然后输入 &lt;return&gt; 。为了搜索字符串，输入 &lt;ctrl-f&gt;
然后输入要搜索的路径并按 &lt;return&gt; 。
具体的请参考 <a class="reference external" href="commands.html">Using Leo&#8217;s Commands</a> 。</p>
</div></blockquote>
</div>
<div class="section" id="external-files-and-file-nodes">
<h2><a class="toc-backref" href="#id3">External files and @file nodes</a><a class="headerlink" href="#external-files-and-file-nodes" title="Permalink to this headline">&#182;</a></h2>
<p id="index-11">Leo stores outline data on your file system in <strong>.leo files</strong>. The format of
these files is <a class="reference external" href="http://en.wikipedia.org/wiki/XML">XML</a>. You don&#8217;t have to store all your data in .leo files: Leo
allows you to store parts of your outline data <strong>external files</strong>, that is,
other files on your file system.</p>
<p>Leo 将 outline 的数据 以 <strong>.leo</strong> 存在你的文件系统中。
这些文件的格式是 <a class="reference external" href="http://en.wikipedia.org/wiki/XML">XML</a> 。你不需要把你全部的数据全部存在 .leo 文件中：
Leo 允许你将 outline 中的部分数据以 <strong>external file</strong> 的形式保存。</p>
<p id="index-12"><strong>@file nodes</strong> create external files. @file nodes have headlines starting with
@file followed by a file name. Some examples:</p>
<p><strong>@file node</strong> 将创建外部的文件。 @file 节点的 headline 以 @file 开头，
然后跟着一个文件名。后面是一些例子：</p>
<div class="highlight-python"><pre>@file leoNodes.py
@file ../../notes.text</pre>
</div>
<p id="index-13">The file name can be an absolute path or a relative path to the file that starts
at Leo&#8217;s <strong>load directory</strong>, the directory containing the .leo file.</p>
<p>文件名可以是绝对路径或者是相对路径（以当前载入 leo 文件的路径开始）。</p>
<p>Leo reads and writes external files automatically when you open or save your Leo
outline:</p>
<p>Leo 将会自动地读取和写入 external file，当你打开或保存 Leo 的 outline：</p>
<ul>
<li><p class="first">When you open an outline (.leo file) Leo reads all the external files created
by the @file nodes in the outline. If you have changed an external file
outside of Leo, Leo will update the corresponding @file tree to reflect those
changes when Leo next opens the outline.</p>
<p>当你打开一个 outline （.leo 文件） Leo 将会读取所有被 @file 节点创建的
external 文件。如果你在 Leo 外改变了一个 external 文件， Leo 在下一次打开 outline 时，
将会更新相应的 @file 节点。</p>
</li>
</ul>
<ul id="index-14">
<li><p class="first">When you save your outline, Leo writes all <strong>dirty</strong> @file nodes. An @file
is dirty if the node or any of its descendant nodes has changed.
<strong>Important</strong>: When Leo writes an external file, Leo writes all the essential
information in the @file tree to the external file, <em>not</em> to the .leo file.
The only nodes that gets written to the .leo file are nodes that are not
contained in any @file tree.</p>
<p>当你保存 outline 时， Leo 会写入所有的 <strong>dirty</strong> @file 节点。
当一个节点或任何相应的子节点改变时，这个 @file 就是 dirty 的。
<strong>重要</strong> ：当 Leo 写一个 exteranl 文件， Leo 会写入所有重要的信息，
尤其是 @file 树中的信息到外部文件中，而 <em>不是</em> 到 .leo 文件中。
只有那些不包含 @file 的节点才被写入到 .leo 中。</p>
</li>
</ul>
</div>
<div class="section" id="creating-external-files-from-outlines">
<h2><a class="toc-backref" href="#id4">Creating external files from outlines</a><a class="headerlink" href="#creating-external-files-from-outlines" title="Permalink to this headline">&#182;</a></h2>
<p id="index-15">We come now to one of Leo&#8217;s most important and unusual features. When Leo writes
an external file, it does so in a flexible manner, directed by <strong>outline-based
markup</strong>. This markup tells Leo exactly how to create the external file from an
@file node.</p>
<p>我们现在来见见 Leo 中很重要而不寻常的特性。
当 Leo 向一个 external 的文件写入东西时，
Leo 会通过 <strong>outline-based markup</strong> 的指令，
进行合适配置。这个标记会准确的告诉 Leo 如果从一个 @file
节点创建 external 文件。</p>
<p id="index-16">The <strong>obvious</strong> way to write an external file would be to write the @file node
itself followed by all the descendant nodes in <strong>outline order</strong> (the order in
which nodes appear in the outline). But Leo does <em>not</em> write external files
exactly this way.</p>
<p>最明显的方式，就是根据子节点的 <strong>outline 顺序</strong>
对 @file 节点进行写入。但是 Leo 并不是完全按照这种方式进行。</p>
<p id="index-17">Yes, Leo does indeed start by writing the @file node itself. But Leo writes the
@file node&#8217;s descendants only when it sees one of three kinds of Leo
markup: section references, the @others directive and the @all directive.
We&#8217;ll discuss these three kinds of markup in the next section.</p>
<p>是的， Leo 的确从写入 @file 节点开始。但是对于 Leo ，
只有它见到了相应的指令，才会将 @file 节点的子节点的内容写入。
有三个这样的指令： <strong>section reference</strong> ， <strong>@other 指令</strong> ，
以及 <strong>@all 指令</strong> 。我们将在后面对这些标记进行讨论。</p>
<p>Section references and the @others and @all directives tell Leo to write the
<strong>expansion</strong> of one or more descendant nodes to the external file. Programmers
will recognize this process as akin to macro expansion. The following sections
will explain this process in detail.</p>
<p>Section reference ， @others 和 @all 指令告诉 Leo
将子节点 <strong>扩展</strong> 到 external 文件中。
程序员会知道这个宏扩展很像。下面的篇幅就将讨论这些。</p>
<div class="section" id="section-references">
<h3><a class="toc-backref" href="#id5">Section references</a><a class="headerlink" href="#section-references" title="Permalink to this headline">&#182;</a></h3>
<p id="index-18">A <strong>section reference</strong> is a line of body text of the form:</p>
<p>一个 <strong>section reference</strong> 就是在 body text 中有下列形式：</p>
<div class="highlight-python"><pre>&lt;&lt; a section name &gt;&gt;</pre>
</div>
<p id="index-19">Here, &#8220;a section name&#8221; can be any descriptive text not containing &#8220;&gt;&gt;&#8221;. When Leo
encounters a section reference, Leo searches all the descendants of the node
containing the reference looking for a node whose headline matches the section
reference. That is, Leo looks for a descendant node whose headline starts with:</p>
<p>此处， <tt class="docutils literal"><span class="pre">"a</span> <span class="pre">section</span> <span class="pre">name"</span></tt> 可以是任何文字，但不包括 &#8220;&gt;&gt;&#8221; 。
当 Leo 碰到一个 section reference ， Leo 会搜索所有的子节点，
然后去匹配在 headline 中有相同内容的引用。
也就是， Leo 会搜索下面的 headline ：</p>
<div class="highlight-python"><pre>&lt;&lt; a section name &gt;&gt;</pre>
</div>
<p id="index-20">We call such nodes <strong>named nodes</strong>. Leo doesn&#8217;t require an exact match. Leo
ignores whitespace and the case of letters when comparing headlines to section
reference. Also, Leo ignores anything that may follow the section name in a
named node. For example, the following headline will match the section reference
above:</p>
<p>我们称这些节点为 <strong>named node</strong> 。Leo 不需要完全的匹配。
它会忽略空格和大小写。同样， Leo 会忽略在此之后的内容。
比如，下面的 headline 也是可以被匹配的：</p>
<div class="highlight-python"><pre>&lt;&lt; A Section Name &gt;&gt; (to do)</pre>
</div>
<p>If Leo does find a match, Leo <em>replaces</em> the section reference (&#8220;&lt;&lt; a section
name&gt;&gt;&#8221;) by the <em>expansion</em> of the body text of the matched node. That is, Leo
replaces the section reference by the body text of the matched node, but Leo
<strong>expands all markup</strong> in the matched node <em>before</em> making the replacement. The
entire expansion of the matched node replaces the original section reference.
Programmers will recognize this process as recursive macro expansion.</p>
<p>如果 Leo 的确找到了一个匹配，Leo 会 <em>替换</em> 这个 section reference （&#8221;&lt;&lt; a
section name&gt;&gt;&#8221;），并把 <strong>named node</strong> 的内容扩展进来。
也就是， Leo 会把匹配的节点的 body text 替换到这里，
但是 Leo 在进行替换前，会先对所有的标记进行扩展。
这样，原始的 section reference 就被真正的内容替换了。
程序员就会想到这就是递归的宏扩展。</p>
<p>We have just discussed what happens if Leo does find a descendant named node
that matches the section reference. If no such match is found the section
reference is said to be <strong>undefined</strong> and Leo does not write any data to the
external file. This is <em>not</em> a serious error: Leo will will save the erroneous
@&lt;file&gt; tree in the .leo file instead of the external file. No information is
lost. By the way, Leo&#8217;s syntax coloring will indicate undefined section
reference by underlining the section name.</p>
<p>我们刚讨论了如果 Leo 发现一个子的 named node 之后会发生的事情。
如果没有找到这样的，那么这个 section reference 就被认为是 <strong>undefined</strong>
而且 Leo 也不会向 external 文件中写入任何东西。
这不是一个很严重的错误： Leo 会把这些写入到 .leo 文件中，
而不是 external 文件中。没有任何信息会被丢掉。
顺便说下， Leo 的语法加色会指示这个是未定义的引用，
通过加一个下划线。</p>
<p><strong>Important</strong>: the indentation of section references matters. When expanding a
section reference, Leo indents every line of the expansion by the leading
whitespace that occurs before the section reference. Note also that you can&#8217;t
write something after a section reference and expect it to end up on the same
line after expansion&#8211;Leo always writes a newline after the expansion.</p>
<p><strong>重要</strong> ：section reference 的缩进是有意义的。
当进行扩展时，被扩充的内容前面都会加入空格。
而且注意，你不能往 section reference 后写入东西并指望这些会出现在每行的末尾。
Leo 在扩展后总会插入一个新行。</p>
</div>
<div class="section" id="the-others-directive">
<h3><a class="toc-backref" href="#id6">The @others directive</a><a class="headerlink" href="#the-others-directive" title="Permalink to this headline">&#182;</a></h3>
<p id="index-21">The <strong>@others directive</strong> is the second (and most common) way of including
descendant nodes in an external files. When Leo encounters the @others
directive it replaces the @others directive by the <em>expansion</em> of all
<strong>unnamed</strong> descendant nodes. As with section references, Leo replaces all
markup in the descendant nodes, and the entire expansion replaces the @others
directive.</p>
<p><strong>@others directive</strong> 是第二个（而且是最常用的）方式，
对子节点进行包含。当 Leo 碰到 @others 指令时，
它会把所有 <strong>unamed</strong> 的子节点都包含进来。
和 section reference 一样， Leo 会替换所有的标记，
然后扩展完后的才会去替换 @others 指令。</p>
<p>In short, section references write <em>named</em> nodes; @others directives write all
<em>unnamed</em> nodes. By the way, no node may contain more than one @others
directive because there would be no way to &#8220;apportion&#8221; descendant nodes to more
than one @others directive. However, nodes may contain as many section
references as you like.</p>
<p>简而言之， section reference 会写入 <em>named</em> 节点；
而 @others 指令则会写入 <em>unnamed</em> 节点。
顺便说下，没有节点可以包含超过一个的 @others 指令。
因为没法将这些子节点分配给多个 @others 指令。
但是，节点中可以包含很多的 section reference 。</p>
<p>As with section references, the indentation of the @others directive matters.
This allows Leo to handle Python source code properly. For example, the following
is a common way of representing a Python class:</p>
<p>和 section reference 一样， @others 指令的缩进也是有意义的。
这就允许 Leo 可以正确的处理 Python 的源代码。
比如，下面一个是表示 Python 类最常用的方式：</p>
<div class="highlight-python"><pre>class myClass:
    '''a docstring'''
    @others</pre>
</div>
<p>When Leo writes this node to an external file, Leo will write the first two
lines to the external file, with the indentation in effect for the node. Leo
will then write all descendant nodes to the external files, with <em>additional</em>
indentation equal to the leading whitespace appearing before the @others
directive.</p>
<p>当 Leo 把这个节点写入一个 external 文件时，
Leo 会把头两行先写入 external 文件，而且缩进也会影响节点。
Leo 然后就把所有的子节点写入，然后会在替换出的内容前再加上额外的空白。</p>
</div>
<div class="section" id="the-all-directive">
<h3><a class="toc-backref" href="#id7">The @all directive</a><a class="headerlink" href="#the-all-directive" title="Permalink to this headline">&#182;</a></h3>
<p id="index-22">The @all directive is the third, simplest (and least common) way of including
descendant nodes. This directive causes Leo to write all descendant nodes in
outline order, regardless of whether they are named or not. Furthermore, the
@all directive does not expand any markup in descendant nodes. This results in
Leo writing the external file in the &#8220;obvious&#8221; way. That is, Leo writes all
descendant nodes in outline order.</p>
<p>而 @all 指令是第三个，最简单（最不常用）的方式来包含子节点。
这个指令会让 Leo 以 outline 的顺序写入所有的子节点，而不管节点是否命名。
此外， @all 指令不会对子节点中的任何标记进行扩展。
这个就使得 Leo 以最直接的方式写入 external 文件。
Leo 会以 outline 的顺序写入所有的子节点。</p>
<p>Use the all directive if your external file contains unrelated nodes. For
example, I use an external file to store programming notes. These notes
typically contain snippets of programming source code, but there is no real
relationships between the snippets&#8211;the file is simply a grab bag of
information. The @all directive is designed for this situation.</p>
<p>如果你的 external 文件包含了无关的节点，那么可以用这个指令。
比如，我用一个 external 文件保存编程的笔记。
这些笔记包含了代码中的一些片段，而在这些片段之间并无联系。
这些文件仅仅就是存放信息的袋子而已。
@all 指令就是为这种情况设计的。</p>
</div>
<div class="section" id="choosing-between-others-and-sections">
<h3><a class="toc-backref" href="#id8">Choosing between @others and sections</a><a class="headerlink" href="#choosing-between-others-and-sections" title="Permalink to this headline">&#182;</a></h3>
<p id="index-23">Newcomers to Leo frequently ask when to use the @others directive and when to
use sections. It is good style to use section references only when the order of
text within a external file matters. For example, Python programmers put
docstrings and imports at the start of files. So the body text of
@file nodes typically look something like this:</p>
<p>Leo 的新手经常会问到，什么时候使用 @others 指令而什么时候用 section 。
在涉及内容的顺序时，使用 section reference 是比较好的。
比如， Python 程序员一般会把 docstring 和 模块导入放在 文件的开头。
所以， @file 节点中的 body text 经常看起来像这样：</p>
<div class="highlight-python"><pre>&lt;&lt; docstring &gt;&gt;
\@language python
\@tabwidth -4
&lt;&lt; imports &gt;&gt;
@others</pre>
</div>
<p>This ensures that the docstring is first in the file, followed by imports,
followed by everything else. Note that the order in which functions are defined
in a file, or methods defined within a class, typically does <em>not</em> matter. Thus,
it is good style to define classes like this:</p>
<p>这就保证了 docstring 是在文件的最开始，然后再是模块导入，
而后又是其他任何东西。注意，在文件中函数的定义，
方法在类体内的定义的顺序是无关的。因此，
下面的定义类的方式是比较好的习惯：</p>
<div class="highlight-python"><pre>class myClass:
      &lt;&lt; class attributes &gt;&gt;
      @others</pre>
</div>
<p>It would be bad style to define a class like this:</p>
<p>而下面的则不是很好：</p>
<div class="highlight-python"><pre>class myClass:
      &lt;&lt; class attributes &gt;&gt;
      &lt;&lt; method 1 &gt;&gt;
      &lt;&lt; method 2 &gt;&gt;
      ...</pre>
</div>
<p>Not only does this over-specify the order in which methods are defined, but it
requires lots of extra typing. Not only must you add a line for each method, but
headlines must contain section names such as &lt;&lt; method 1 &gt;&gt;, &lt;&lt;method 2&gt;&gt;, etc.
When using @others it is good style simply to put the name of each method in the
headline.</p>
<p>不仅仅因为这过分特化了方法在类中的顺序，而且这也需要大量额外的输入。
你不仅需要为每个方法添加这样的一行，而且在 headline 中也需要包含像
&lt;&lt; method 1 &gt;&gt; ， &lt;&lt; method 2 &gt;&gt; 这样的东西。
而使用 @others 就大大简化了要把方法放在 headline 中这样的事情。</p>
</div>
<div class="section" id="organizing-programs-as-outlines">
<h3><a class="toc-backref" href="#id9">Organizing programs as outlines</a><a class="headerlink" href="#organizing-programs-as-outlines" title="Permalink to this headline">&#182;</a></h3>
<p>A few more words about style:</p>
<p>更多关于风格：</p>
<ul>
<li><p class="first">It is good style to put each class, function or method in its own node. This
makes it easy to see the shape of your code.</p>
<p>最好把每个类，函数或方法放在自己的节点中。这样就利于看清楚你代码的结构。</p>
</li>
<li><p class="first">It is good style to use organizer nodes to group related functions or methods.
An organizer node has no content except maybe for comments. Like this:</p>
<p>把相关的函数或方法分组也是很好的习惯。
一个所谓的 organizer 节点除了用于注释，就可以没有其他用处了。
像这样：</p>
<div class="highlight-python"><pre>+ myClass
    + birth and death
        + __init__
        etc.
    + getters
        etc.
    + setters
        etc.
    + misc methods
        etc.</pre>
</div>
<p>(In this notation, &#8216;+&#8217; denotes a headline.) This organization is far superior
to using hideous comments like:</p>
<p>（在这个记法中， &#8216;+&#8217; 表示一个 headline 。）
这样的组织比那种隐式的注释要好很多：</p>
<div class="highlight-python"><div class="highlight"><pre><span class="c">###########</span>
<span class="c"># Getters #</span>
<span class="c">###########</span>
</pre></div>
</div>
</li>
<li><p class="first">It is bad style to use @others in organizer nodes. There is no need to do so.</p>
<p>用 @others 当为组织节点并不好。没有必要那么做。</p>
</li>
<li><p class="first">It is bad style to use @others when order does matter. The reason is that it
is very easy to move nodes in a tree by mistake, say by alphabetizing nodes.
One wants to make the meaning of a external file immune from such movements.</p>
<p>当顺序是有意义的时候，最好不要使用 @others 。
原因是在一棵树中很容易误动节点，比如按字母顺序对节点排序。
我们希望这样的移动对文件没有任何影响。</p>
</li>
</ul>
<p>One last word about style. The world won&#8217;t end if you happen to use bad style by
mistake: you just might cause a bit more work for yourself than was strictly
necessary. Feel free to invent your own style of using Leo. Still, it would be
wise to &#8220;know the rules before you break them.&#8221;</p>
<p>最后再说一点。你由于无意使用了不好的风格，也不会怎样：
你可能仅仅为自己带来了一点小麻烦。
在使用 Leo 的过程中你可以创造自己的风格。
但是&#8220;在打破规则前了解它们&#8221;还是比较明智的。</p>
</div>
</div>
<div class="section" id="clones-views">
<h2><a class="toc-backref" href="#id10">Clones &amp; views</a><a class="headerlink" href="#clones-views" title="Permalink to this headline">&#182;</a></h2>
<p id="index-24">A <strong>clone</strong> is a node that appears in more than one place in a Leo outline.
Clones are marked with a small red arrow in the icon box. All clones of a node
are actually <em>the same node</em>, so any change to one clone affects all clones. For
example, inserting, moving or deleting any child of a clone will change all
other clones on the screen.</p>
<p><strong>克隆（clone）</strong> 是在 Leo 的 outline 中，不止在一个地方出现的节点。
在 icon box 中，以一个红色的箭头标记克隆。
一个节点的所有 clone 事实上是 <em>相同的节点</em> ，
所以对任何一个克隆的改变都会影响所有的克隆。
比如，插入，移动或删除任何克隆的子节点都会导致所有其他克隆的改变。</p>
<p>Please take a few moments to experiment with clones. Create a node whose
headline is A. Clone node A using the Clone Node command in Leo&#8217;s Outline menu.
Type some text into the body of either clone of A. The same text appears in the
bodies of all other clones of A. Now insert a node, say B, as a child of any of
the A nodes. All the A nodes now have a B child. See what happens if you clone
B. See what happens if you insert, delete or move nodes that are children of A.
Verify that when you delete the penultimate clone, the last clone becomes a
regular node again.</p>
<p>请最好花一点时间试试克隆。
创建一个节点，称其 headline 是 A 。
然后再使用 Leo outline 菜单中的克隆命令对节点 A 进行克隆。
然后再往 A 的任何克隆的 body 中输入一些文字。
这样其他克隆中也就会出现相应的文字。
现在，插入一个节点，称为 B ，作为 A 的子节点。
这样，所有 A 节点就会有 B 这样的子节点。
现在，再看看如果克隆了 B 有什么后果。
看看如果你插入，删除或移动 A 的子节点会发生什么。
核实下当你删除倒数第二个克隆后，最后一个克隆是不是又变回一个正常的节点了。</p>
<p>Clones are much more than a cute feature. Clones allow multiple views of data to
exist <strong>within a single outline</strong>. With Leo, there is no such thing as a single,
&#8220;correct&#8221; view of data. You can have as many views of data as you like.</p>
<p>克隆不止是一个非常好的特性。
克隆允许对数据进行多种视图。
在 Leo 中，没有所谓 &#8220;正确的&#8221;视图方式。
你可以任由你的喜欢对数据进行视图。</p>
<p>To create a new view of the data in your outline, just do the following:</p>
<p>要创建一个新的视图方式，只要按下面做就可以了：</p>
<ol class="arabic" id="index-25">
<li><p class="first">Create an <em>ordinary</em> node, that will represent the view. We call these nodes
<strong>view nodes</strong> merely to indicate they represent a view.</p>
<p>创建一个 <em>正常的</em> 节点，用于代表视图（view）。
我们称这些节点为 <strong>view node</strong> 仅仅是代表一个视图。</p>
</li>
<li><p class="first">Clone all the nodes from the outline that you want the view to contain. Move
these clones so they become children of the view node.</p>
<p>克隆所有你所需要的节点。然后把它们移到 view node 中。</p>
</li>
<li><p class="first">(Optional) You can add regular nodes as children of the view node too.</p>
<p>（可选的）你可以增加一个正常的节点作为 view node 的子节点。</p>
</li>
</ol>
<p id="index-26">For example, when I fix a bug in Leo, I create an ordinary node to represent the
bug. This <strong>bug node</strong> is my view of all the data in Leo&#8217;s source code that
relates to the bug. As I discover code related to the bug, I clone their nodes
and move them under the bug node. I&#8217;ll also add ordinary nodes as children of
the bug node. These nodes contain the original bug report, descriptions of how I
fixed the bug, test data, or any other notes I might want to keep.</p>
<p>比如，当我修复了 Leo 中的一个bug时，我会创建一个正常的节点用于表示bug。
这个 <strong>bug node</strong> 就是用于 bug 相关的视图。
如果我发现与此 bug 相关的代码，我会把这段代码进行克隆，然后移到 bug 节点下。
我也会增加普通的节点作为 bug node 的子节点。
这些节点包含了原始的 bug 报告，我如何修复了这个bug，
测试的数据，或者其他我保留的节点。</p>
<p>Once I have created the bug node, I concentrate <em>only</em> on that node and its
children. I can examine the bug node and its children without having to jump
around the outline. Everything I need is in one place. When I get around to
actually fixing the bug I can do so by changing the clones. Again, I do not have
to jump around the outline. It doesn&#8217;t matter how big or complex the entire
outline is: I am only dealing with the bug node and its children. This extremely
narrow focus makes it <em>much</em> easier to fix bugs.</p>
<p>一旦我创建了一个 bug 节点，我主需要关注那个节点和它的子节点。
我可以检验那个 bug 节点及子节点而无须在 outline 跳转。
所有我需要做的，就是在一个地方。当我有时间修复了 bug ，
我只需要修改 clone 。再次的，我也无须跳转。
整个 outline 有多大或多复杂都无所谓：
我仅仅需要处理 bug 节点及其子节点即可。
把问题集中在一点就使得修复 bug 变得比较简单。</p>
<p>By the way, I never have to remember to save external files. When I change any
clone, Leo marks all instances of that clone throughout the entire outline as
dirty (changed). When I save the Leo outline, Leo automatically writes all the
external files that contain dirty nodes.</p>
<p>顺便说下，我从来不需要记得保存 external 文件。
当我改变了任何一个克隆，Leo 就会标记所有克隆的实例，
整个 outline 被认为是 dirty （改变了）。
当我保存 Leo 的 outline，Leo 自动的会写入包含 dirty 节点的 external 文件。</p>
<p>Views have an unlimited number of uses. Use them whenever you want to focus your
attention on some smaller set of nodes. For example, I often create view nodes
when studying other people&#8217;s code. The view node helps me concentrate on just
the part of the code that interests me at the moment.</p>
<p>视图的使用没有限制。在你想集中于一些更小的节点集合时就使用它们。
比如，我在研究别人的代码时，我就会创建视图节点。
这些视图节点帮助我集中于某一段我感兴趣的代码。</p>
</div>
<div class="section" id="more-about-directives">
<h2><a class="toc-backref" href="#id11">More about directives</a><a class="headerlink" href="#more-about-directives" title="Permalink to this headline">&#182;</a></h2>
<p id="index-27">Leo&#8217;s <strong>directives</strong> control such things as syntax coloring, line wrapping
within the body pane and the width of tabs. Leo directives may appear in
headlines or body text. Leo directives start with &#8216;@&#8217;, followed by the name of
the directive.</p>
<p>Leo 的 <strong>指令(directive)</strong> 控制着一些这样的事情，如语法加亮，
在 body 面板中行的包装和 tab 的宽度。Leo的指令可以出现于 headline 或 body 文字中。
Leo的指令以 <tt class="docutils literal"><span class="pre">'@'</span></tt> 开始，而后跟着指令的名字。</p>
<p><strong>Note</strong>: Leo handles Python decorators properly, providing they don&#8217;t conflict
with Leo&#8217;s directives.</p>
<p><strong>注意</strong> ：Leo可以正确的处理 Python 的装饰器（decorator），
而不会使得与 Leo 的指令相冲突。</p>
<p>Here are some of Leo&#8217;s directives:</p>
<p>这里是一些 Leo 的指令：</p>
<div class="highlight-python"><pre>@language python
@tabwidth -4
@wrap
@nowrap
@color
@nocolor
@killcolor</pre>
</div>
<p>Most directives must start with the &#8216;@&#8217; in the leftmost column, but whitespace
may appear before the <a class="reference external" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#38;&#35;&#51;&#55;&#59;&#38;&#35;&#53;&#50;&#59;&#38;&#35;&#52;&#56;&#59;&#111;&#116;&#104;&#101;&#114;&#115;">'<span>@</span>others</a>&#8216; and <a class="reference external" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#39;&#38;&#35;&#51;&#55;&#59;&#38;&#35;&#53;&#50;&#59;&#38;&#35;&#52;&#56;&#59;&#97;&#108;&#108;">'<span>@</span>all</a>&#8216; directives. As we have seen, such
whitespace is significant.</p>
<p>大多数的指令必需在最左边的列上以 <tt class="docutils literal"><span class="pre">'@'</span></tt> 开头，
但是在 <tt class="docutils literal"><span class="pre">'@others'</span></tt> 及 <tt class="docutils literal"><span class="pre">'@all'</span></tt> 前可以出现空白。
正如我们所见，这些空白是有意义的。</p>
<p>Directives apply until overridden in a subtree. All of these directives apply to
the node they are contained in, and also to the entire tree of descendant nodes,
unless <strong>over-ridden</strong> by a similar directive in a descendant node. For example,
the directive:</p>
<p>指令在子树中都会生效直至遇到覆写。
所有的这些指令在包含它们的节点中都会生效，以及相应的子节点，
除非是在子节点有相同的指令对此进行覆写。
比如，这个指令：</p>
<div class="highlight-python"><pre>@language python</pre>
</div>
<p>tells Leo to syntax color the node and all descendant nodes as Python code.
However, some descendant node might contain:</p>
<p>告诉 Leo 以 Python 的语法加亮这个节点及所有派生节点。
但是有些派生的节点可以包含：</p>
<div class="highlight-python"><pre>@language rest</pre>
</div>
<p>which tells Leo to color that node and all of <em>its</em> descendants as
reStructureText. This principle applies to almost all of Leo&#8217;s directives: the
directive is in effect throughout a tree, unless overridden in some subtree.</p>
<p>这个就告诉 Leo 以 reStructureText 对这个节点及派生节点进行高亮。
这个原则对几乎所有的 Leo 指令都适用：
指令在整棵树中都有效果，除非在一些子树中被覆写。</p>
<dl class="glossary docutils">
</dl>
<p>@color, @nocolor and @killcolor</p>
<blockquote>
<div><p>These directives control how Leo colors body text. You can mix @nocolor and
@color directives in a single node. This directives affect descendant
nodes unless a node contains both @color and @color.  Such <strong>ambiguous</strong>
nodes do not affect the coloring of descendant nodes.</p>
<p>这些指令控制这 Leo 如何对 body 中的文字进行加亮。
可以在一个节点中混合使用 @nocolor 和 @color 指令。
这些指令会影响派生的节点除非一个节点中同时包含 @nocolor 和 @color
指令。这样不确定的节点的子节点就不会受到影响。</p>
</div></blockquote>
<p id="index-29">@first</p>
<blockquote>
<div><p>This directive forces a lines to appear before the first sentinel of a
external file. Here is a common way to start a Python file:</p>
<p>这个指令强行让一行按顺序出现于一个 external 文件中。
此处在 Python 文件中是最常见的：</p>
<blockquote>
<div>@first #! /usr/bin/env python
@first # -<em>- coding: utf-8 -</em>-</div></blockquote>
</div></blockquote>
<p id="index-30">@language</p>
<blockquote>
<div><p>Sets the language in effect for a tree. This affects how Leo colors body
text. It also sets the comment delimiters used in external files. Leo
supports dozens of languages. See <cite>Leo&#8217;s reference</cite> for a complete list.
Here are a few:</p>
<p>设置相应的语言。这就影响 Leo 对 body 文字的加亮方式。
这也设置了在 external 文件中注释所用的分界符。
Leo 支持挺多语言的。参考 <cite>Leo&#8217;s reference</cite> 。
此处是一些：</p>
<div class="highlight-python"><pre>@language python
@language c
@language rest # restructured text
@language plain # plain text: no syntax coloring.</pre>
</div>
</div></blockquote>
<p id="index-31">@pagewidth &lt;n&gt;</p>
<blockquote>
<div><p>Sets the page width used to format break doc:</p>
<p>设置格式化文档时所用的页宽：</p>
<div class="highlight-python"><pre>@pagewidth 100</pre>
</div>
</div></blockquote>
<p id="index-32">@path &lt;path&gt;</p>
<blockquote>
<div><p>This directive is a convenience.  Rather than specifying long paths
in @file nodes, you can specify a path in an ancestor @path node.
For example, suppose three nodes have the following headlines:</p>
<p>这个指令很方便。不需要在 @file 中指明很长的路径，
你可以在一个父节点中指定 @path 节点。
比如，假设有下面三个节点：</p>
<div class="highlight-python"><pre>@path a
    @path b
        @file c/d.py</pre>
</div>
<p>Because of the ancestor @path nodes, the @file node creates the file
a/b/c/d.py</p>
<p>因为父节点的 @path ，@file 节点创建的文件会是 <tt class="docutils literal"><span class="pre">a/b/c/d.py</span></tt> 。</p>
<p>Within @path and @&lt;file&gt; paths, {{exp}} gets evaluated with the following
symbols known: c, g, p, os and sys.  For example:</p>
<p>在 @path 和 @&lt;file&gt; 的路径中， <tt class="docutils literal"><span class="pre">{{exp}}</span></tt> 会执行下面已知的符号：
c，g，p，os和sys。比如：</p>
<div class="highlight-python"><pre>@file {{os.path.abspath(os.curdir)}}/abc.py</pre>
</div>
<p>refers to the file abc.py in (absolute path of) the current directory.</p>
<p>就会指向当当前目录下的 abc.py 文件。</p>
</div></blockquote>
<p id="index-33">@tabwidth</p>
<blockquote>
<div><p>Sets the width of tabs. Negative tab widths cause Leo to convert tabs to
spaces and are highly recommended for Python programming.</p>
<p>设置 tab 的宽度。负的宽度就表示将 tab 转换为空格，并且这是
Python 编程建议的。</p>
</div></blockquote>
<p id="index-34">@wrap and @nowrap.</p>
<blockquote>
<div><p>These enable or disable line wrapping the Leo&#8217;s body pane.</p>
<p>这个开启或关闭行包装。</p>
</div></blockquote>
</div>
<div class="section" id="scripting-extending-and-customizing-leo">
<h2><a class="toc-backref" href="#id12">Scripting, extending and customizing Leo</a><a class="headerlink" href="#scripting-extending-and-customizing-leo" title="Permalink to this headline">&#182;</a></h2>
<p id="index-35">Leo is fully scriptable using the Python language. Leo can execute any body text
as a Python script. To run the entire body text as a script, simply choose the
node and execute the Execute Script command (Ctrl+B). If text is selected, the
Execute Script command will run just the selected text as the script.</p>
<p>Leo 可以使用 Python 进行脚本编程。
Leo 可以将任意的 body 文字作为 Python 脚本执行。
为了将一整段作为脚本执行，只要选中相应的节点，
然后执行执行脚本的命令（Ctrl+B）。
如果有文字被选中，那么就会只执行选中的部分。</p>
<p>The Execute Script command <strong>preprocesses</strong> the script before executing it, in
exactly the same way that Leo writes external files. Leo expands section
references and processes @others directives before executing the script. This
allows you to use all of Leo&#8217;s outlining capabilities to organize your scripts.</p>
<p>执行脚本命令在执行它之前将预处理这个脚本，
这和 Leo 写入 external 文件是一样的。
在执行这个脚本前，
Leo 将会扩展 section reference 和处理 @others 指令。
这个就允许你使用 Leo 的 outline 来组织你的脚本。</p>
<p>Your Python scripts can easily access data in an outline. Leo&#8217;s execute-script
(Ctrl-B) command predefines three variables, c, g and p, that scripts can use to
easily access any part of any Leo outline, and Leo&#8217;s own source code. For
example, the following script will print all the headlines in an outline:</p>
<p>你的 Python 脚本可以很容易访问在 outline 中的数据。
Leo 的执行脚本（Ctrl-B）命令预定义了三个变量，c，g和p，
这样脚本可以访问 Leo 的 outline 的任意部分，
以及 Leo 自身的代码。
举个例子，下面的脚本将会打印所有的 headline：</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">c</span><span class="o">.</span><span class="n">all_positions</span><span class="p">():</span>
    <span class="k">print</span> <span class="s">' '</span><span class="o">*</span><span class="n">p</span><span class="o">.</span><span class="n">level</span><span class="p">(),</span><span class="n">p</span><span class="o">.</span><span class="n">h</span>
</pre></div>
</div>
<p>The example above is only the beginning of what scripts can do.
See <a class="reference external" href="scripting.html">Scripting Leo with Python</a> for a complete discussion of scripting Leo.</p>
<p>上面的例子仅仅是脚本可以做什么的开端。
参考 <a class="reference external" href="scripting.html">Scripting Leo with Python</a> 有更详细的讨论。</p>
<p id="index-36"><strong>Plugins</strong> are Python modules that change how Leo works. Leo&#8217;s user have
contributed dozens of plugins that have extended Leo&#8217;s capabilities in many new
directions. The file leoPlugins.leo contains all plugins that are included in
Leo distributions.</p>
<p><strong>Plugin</strong> 是 Python 的模块用于改变 Leo 运行的方式。
Leo 的用户贡献了大量的插件用于扩展 Leo 在各方面的能力。
文件 leoPlugin.leo 包含了 Leo 发行版中所有的插件。</p>
<p id="index-37">Plugins and other parts of Leo can get options from <strong>@settings</strong> trees.
@settings trees allow plugins to get options without any further support from
Leo&#8217;s core code. For a full discussion of @settings trees,
see <a class="reference external" href="customizing.html">Customizing Leo</a>.</p>
<p>插件和其他部分可以从 <strong>@settings</strong> 树中获取选项。
@settings 树允许插件获取选项而无须 Leo 核心代码的支持。
关于此的更多讨论，参考 <a class="reference external" href="customizing.html">Customizing Leo</a> 。</p>
</div>
<div class="section" id="summary">
<h2><a class="toc-backref" href="#id13">Summary</a><a class="headerlink" href="#summary" title="Permalink to this headline">&#182;</a></h2>
<p>Using Leo quickly becomes second nature:</p>
<p>使用 Leo 迅速变为第二种特性：</p>
<ul>
<li><p class="first">You can use Leo like any ordinary outliner, as a filing cabinet, but Leo&#8217;s
clones makes this filing cabinet much more flexible and useful than usual.</p>
<p>你可以像任何普通的 outline 软件一样使用 Leo，
像一个文件柜，但是 Leo 的克隆使得这个文件柜更灵活实用。</p>
</li>
<li><p class="first">You create external files using @file trees. Within @file trees, you use
section references and the @others directive to tell Leo how to write nodes
to the external file. Directives such as @tabwidth and @language provide other
information to Leo. Leo&#8217;s @file trees allow you to organize your scripts
and programs with Leo&#8217;s outline structure.</p>
<p>你可以使用 @file 创建 external 文件。
有了 @file 树，你可以用 section reference 以及
@others 指令告诉 Leo 如何把节点写入 Leo。
Leo 的 @file 使得你可以用 Leo 的 outline 组织你的脚本和程序。</p>
</li>
<li><p class="first">You can execute Python scripts from any node in a Leo outline. Leo scripts
have full, easy, access to all the information in the outline. Using scripts
and plugins, you can easily add new features to Leo.</p>
<p>在一个 Leo 的 outline 中，你可以从任何一个节点中运行 Python 脚本。
Leo 脚本可以访问 outline 中的所有信息。
使用脚本和插件，你可以轻松增加新的特性。</p>
</li>
</ul>
</div>
<div class="section" id="further-study">
<h2><a class="toc-backref" href="#id14">Further study</a><a class="headerlink" href="#further-study" title="Permalink to this headline">&#182;</a></h2>
<p>LeoPyRef.leo (in the core subdirectory of the leo folder) contains almost all of
Leo&#8217;s source code. It provides hundreds of examples of everything discussed
here. This file will repay close study. For full details on all aspects of Leo
see LeoDocs.leo.</p>
<p>LeoPyRef.leo（在leo目录的core目录下）包含了几乎所有的 Leo 源代码。
它提供了这里讨论过的很多的例子。
这个文件值得深入学习。关于 Leo 各方面的详情参考 LeoDocs.leo。</p>
</div>
</div>
          </div>
        </div>
      </div>
 </div><img src ="http://www.cppblog.com/mirguest/aggbug/164876.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2012-02-03 12:50 <a href="http://www.cppblog.com/mirguest/archive/2012/02/03/164876.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[学习]使用python控制ie管理C++博客的css配置</title><link>http://www.cppblog.com/mirguest/archive/2011/02/04/139724.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Fri, 04 Feb 2011 09:38:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2011/02/04/139724.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/139724.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2011/02/04/139724.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/139724.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/139724.html</trackback:ping><description><![CDATA[昨天，写了基本的控制代码。<br>然后，通过查看css中的html代码，分析出各个block的id。<br>在将value读取，写到临时文件中，使用vim对此文件进行编辑。<br>保存后，就把这个又写回去。然后确认。<br><br>代码：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 46.91%; PADDING-RIGHT: 5px; HEIGHT: 586px; MARGIN-LEFT: 30px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><span style="COLOR: #008080">&nbsp;1</span><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;win32com.client&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;DispatchEx<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;time<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;subprocess<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;os<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">ie</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">DispatchEx(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">InternetExplorer.Application</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">ie.Navigate(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">http://www.cppblog.com/mirguest/admin/Configure.aspx</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">ie.Visible</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;ie.Busy:<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">body</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">ie.Document.body<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;body.getElementsByTagName(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">textarea</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">):<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;str(i.getAttribute(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">id</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">))</span><span style="COLOR: #000000">==</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Edit_txbSecondaryCss</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">tmpcss</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">i.value<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">f</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">open(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">tmp.css</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">w</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">f,tmpcss<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">f.close()<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">gvim</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">subprocess.Popen(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">gvim&nbsp;tmp.css</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">gvim.wait()<br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">f</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">open(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">tmp.css</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">s</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">f.read()<br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">f.close()<br></span><span style="COLOR: #008080">28</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">i.value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">s<br></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">os.remove(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">tmp.css</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><br></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;body.getElementsByTagName(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">a</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">):<br></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;str(i.getAttribute(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">id</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">))</span><span style="COLOR: #000000">==</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Edit_lkbPost</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">i.click()<br></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<img src ="http://www.cppblog.com/mirguest/aggbug/139724.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2011-02-04 17:38 <a href="http://www.cppblog.com/mirguest/archive/2011/02/04/139724.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[学习]使用python操作ie</title><link>http://www.cppblog.com/mirguest/archive/2011/02/03/139711.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Thu, 03 Feb 2011 10:05:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2011/02/03/139711.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/139711.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2011/02/03/139711.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/139711.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/139711.html</trackback:ping><description><![CDATA[以前写过一个使用python的urllib操作的登录脚本。<br>今天逛着发现，在windows下可以用win32com操作。<br>参考文章：<br><a href="http://msdn.microsoft.com/en-us/library/aa752084(VS.85).aspx">http://msdn.microsoft.com/en-us/library/aa752084(VS.85).aspx</a><br><a href="http://www.quou.cn/archives/234">http://www.quou.cn/archives/234</a><br>下面是代码，登录人人的：<br>
<div style="BORDER-BOTTOM: #cccccc 1px solid; BORDER-LEFT: #cccccc 1px solid; PADDING-BOTTOM: 4px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 4px; WIDTH: 98%; PADDING-RIGHT: 5px; FONT-SIZE: 13px; WORD-BREAK: break-all; BORDER-TOP: #cccccc 1px solid; BORDER-RIGHT: #cccccc 1px solid; PADDING-TOP: 4px"><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"><span style="COLOR: #008000">#</span><span style="COLOR: #008000">&nbsp;-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-&nbsp;</span><span style="COLOR: #008000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #800000">"""</span><span style="COLOR: #800000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">http://msdn.microsoft.com/en-us/library/aa752084(VS.85).aspx<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">http://www.quou.cn/archives/234<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #800000">"""</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;win32com.client&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;time&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;getpass<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">ie</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">win32com.client.DispatchEx(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">InternetExplorer.Application</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">ie.Navigate(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">http://renren.com/</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">ie.Visible</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;ie.Busy:&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">document</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">ie.Document<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">body</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">document.body<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">myElements</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">[]<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;body.getElementsByTagName(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">input</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">):<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;str(i.getAttribute(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">id</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">))&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">email</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">password</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">login</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">]:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myElements.append(i)<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;myElements:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;str(j.getAttribute(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">id</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">))</span><span style="COLOR: #000000">==</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">email</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j.value</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">lintao51@163.com</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">elif</span><span style="COLOR: #000000">&nbsp;str(j.getAttribute(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">id</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">))</span><span style="COLOR: #000000">==</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">password</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j.value</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">getpass.getpass()<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">:<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j.click()<br><img align=top src="http://www.cppblog.com/Images/OutliningIndicators/None.gif"></span></div>
<br>因为随便的，所以看起来不够简洁。
<img src ="http://www.cppblog.com/mirguest/aggbug/139711.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2011-02-03 18:05 <a href="http://www.cppblog.com/mirguest/archive/2011/02/03/139711.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python in nutshell Section 5.1</title><link>http://www.cppblog.com/mirguest/archive/2011/02/03/139703.html</link><dc:creator>mirguest</dc:creator><author>mirguest</author><pubDate>Thu, 03 Feb 2011 02:55:00 GMT</pubDate><guid>http://www.cppblog.com/mirguest/archive/2011/02/03/139703.html</guid><wfw:comment>http://www.cppblog.com/mirguest/comments/139703.html</wfw:comment><comments>http://www.cppblog.com/mirguest/archive/2011/02/03/139703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mirguest/comments/commentRss/139703.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mirguest/services/trackbacks/139703.html</trackback:ping><description><![CDATA[<p>本来用sphinx+rst输出html，但贴上来发现效果不行，因此直接贴上rst的。</p>
<p>Section 5.1 Classes and Instances<br>+++++++++++++++++++++++++++++++++</p>
<p>如果你已经熟悉面向对象编程，像在其他语言，C++或Java，这样你可能有一个很好的理解，像类和实例：一个类，就是一个用户定义的类型，你可以将它实例化得到实例对象，而它们就是这个类型的。Python支持这些概念，通过它的类和各个实例对象。</p>
<p>5.1.1 Python Classes<br>--------------------</p>
<p>类就是有一些特性的python对象：</p>
<p>* 你可以调用一个类，好像它就是一个函数。这个调用返回了另一个对象，这就是一个类的实例；而类也就是这个实例的类型。<br>* 一个类的属性可以任意的绑定和引用。<br>* 类属性的值可以是描述符（包括函数），或者是普通的数据对象。<br>* 类属性绑定了函数，就是我们所知的类的方法。<br>* 一个方法，可以有一个特殊的python定义的名字，它是以两个下划线起始，而又以两个下划线结尾。Python会隐式地调用这些特殊的方法，如果一个类提供了它们，并且当各个操作发生在那个类的实例上。<br>* 一个类可以从其他类中继承，这就意味着它如果在本身中没有找到一个属性，那么它就会委托给其他类，让它们在它们的类中搜索。</p>
<p>一个类的实例，是一个python对象，有任意命名了的属性，而你可以绑定和引用。一个实例对象隐式地将在实例本身中未搜寻到的属性委托给它的类来搜索。而这个类，如果可以，又会依次的搜索它所继承的类。</p>
<p>在python中，类是对象，而且可以像其他对象那样使用。因此，你可以将一个类作为参数，传递给一个函数。同样的，一个函数可以返回一个类。一个类，就像其他的对象，可以绑定一个变量（全局或局部），一个容器中的元素，或者是一个对象的属性。类也可以成为一个字典的键值。事实上，类是一个普通的对象，这也就是常说的类是一级对象。</p>
<p>5.1.2 The class Statement<br>-------------------------</p>
<p>``class`` 语句是最常见的方式，来创建一个类对象。 ``class`` 是一个单子句符合语句，遵循下列的语法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class classname(base-classes):</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statement(s)</p>
<p>``classname`` 是一个标识符。它是一个变量，可以绑定到类对象，在 ``class`` 语句完成执行后。</p>
<p>``base-classes`` 是一系列以逗号分隔，而值都必须是类对象的表达式。这些类在不同的编程语言中有着不同的名字；这完全看你喜欢，可以是基类，超类，或者是被创建类的父类。而被创建的类，可以说是继承，派生，扩展，或是子类。这都完全看你所熟悉的语言是怎么称呼它们的。这个类也可以说是一个直接子类，或者是它基类的后代。</p>
<p>语法上， ``base-classes`` 是可选的：为了表示你创建的类是没有基类的，你可以忽略 ``base-classes`` （而且还有它两边的括号也要忽略），直接将冒号放在类名字后面（在python 2.5中，你也可以使用这对空括号，其意思是一样的）。但是，一个没有基类的类，由于向后兼容的问题，所以是一个 **旧式** 的类（除非你定义了 ``__metaclass__`` 属性）。为了创建 **新式** 的类，而又没有&#8220;真正&#8221;的基类，那么这样编写代码： ``class C(object):`` ；因为每个类型都把内置对象归入子类，为了区分是新式的类还是旧式的类，我们就用 ``object`` 来加以指明。如果你的类的祖先都是旧式的类，而又没有定义 ``__metaclass__`` 属性，那么它就是旧式的；否则，有基类的类总是新式的类（就算有些基类是新式的，有些是旧式的）。</p>
<p>在各个类中的子类关系，是可传递的：如果 ``C1`` 是 ``C2`` 的子类，而 ``C2`` 又是 ``C3`` 的子类，那么， ``C1`` 就是 ``C3`` 的子类。内置函数 ``issubclass(C1,C2)`` 接受两个是类对象的参数：它将会返回 ``True`` 如果 ``C1`` 是 ``C2`` 的子类；否则将返回 ``False`` 。任何一个类将被认为是自己的子类；所以， ``issubclass(C,C)`` 将会返回 ``True`` 。关于基类如何影响这个类的方式可以参考&#8220;继承&#8221;。</p>
<p>而在 ``class`` 语句后面的不为空的语句，则被称为类体。一个类体在 ``class`` 语句被执行时也就被作为其一部分被执行了。直到类体结束执行，一个新的类对象还不存在，并且 ``classname`` 标识符也并未绑定（或重绑定）。在&#8220;如何用元类构造类中&#8221;提供了更详细的信息。</p>
<p>最后，注意， ``class`` 语句并不是立即创建任何新类的实例，而是定义了一系列的属性的集合，而这个集合又被你后来创建的实例所共享。</p>
<p>5.1.3 The Class Body<br>--------------------</p>
<p>一个类的主体，是你指定类属性的地方；这些属性可以是描述符对象（包括函数），或者是任意类型的普通数据对象（一个类的属性可以是另一个类，举个例子，你可以有一个嵌套的 ``class`` 语句在另一个 ``class`` 语句中。）</p>
<p>5.1.3.1 Attributes of class objects<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>你可以指定一个类的属性，通过绑定一个值给类体中的标识符。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C1(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = 23</p>
<p>&nbsp;&nbsp;&nbsp; print C1.x<br>&nbsp;&nbsp;&nbsp; #prints:23</p>
<p>类对象 ``C1`` 有一个属性，叫做 ``x`` ，它绑定了一个值 ``23`` ，而 ``C1.x`` 则指向这个属性。</p>
<p>你可以在类体外绑定或解除属性。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C2(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; C2.x = 23<br>&nbsp;&nbsp;&nbsp; print C2.x<br>&nbsp;&nbsp;&nbsp; #prints: 23</p>
<p>但是，你的程序如果把绑定属性之类的东西都放入类体中，这样可读性可能高一点。任何类属性，都是隐式的被全部的实例共享，一旦实例被创建。这个我们后面很快就会讨论。</p>
<p>使用了 ``class`` 语句后，将会隐式的设置一些类属性。属性 ``__name__`` 是 ``classname`` 标识符的字符串值。而属性 ``__bases__`` 则是一个tuple，里面是各个给定的基类对象。举个例子，使用刚才创建的 ``C1`` ：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; print C1.__name__, C1.__base__<br>&nbsp;&nbsp;&nbsp; #prints: C1, (&lt;type 'object'&gt;,)</p>
<p>一个类还有个属性 ``__dict__`` ，它是一个字典对象，类用它来存放所有其他的属性。对于任意类对象 ``C`` ，任意对象 ``x`` ，和任意标识符 ``s`` （除了 ``__name__`` ， ``__bases__`` 和 ``__dict__`` ）， ``c.s`` 是和 ``c.__dict__['s']=x`` 等价的。举个例子，再次引用刚才创建的 ``C1`` ：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; C1.y=45<br>&nbsp;&nbsp;&nbsp; C1.__dict__['z'] = 67<br>&nbsp;&nbsp;&nbsp; print C1.x, C1.y, C1.z<br>&nbsp;&nbsp;&nbsp; #prints: 23, 45, 67</p>
<p>以下的设定是没有区别的：像在类体内定义属性，或是在类体外通过指定一个属性，再或者，在类体外，显式地绑定到 ``c.__dict__`` 。</p>
<p>直接在类体中的语句，如果引用属性时，要使用简单的名字，而不是完全的名字。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C3(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = 23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y = x + 22<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #must use just x,not C3.x</p>
<p>但是呢，如果是在类体中所定义的方法内，引用时就必须使用完整的名字，而不是简单的名字。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C4(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = 23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def amethod(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print C4.x<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # must use C4.x, not just x</p>
<p>注意，使用属性引用时（也就是像 ``c.s`` ）比函数绑定有更多的语义。具体参考&#8220;Attribute Reference Basics&#8221;。</p>
<p>5.1.3.2 Function definitions in a class body<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>大多数类体内包含 ``def`` 语句，因为函数（在此处被称为方法）对于很多类对象来说都是很重要的属性。一个 ``def`` 语句尽管在类体中，但是仍然是和 &#8220;Function&#8221;的约定是一样的。另外，在类体中的方法一直要有个强制的第一个参数，约定称为 ``self`` ，而他表示你调用方法所对应的实例。在方法调用中， ``self`` 扮演一个很重要的角色。</p>
<p>这里是一个例子，一个类包含一个方法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C5(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def hello(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "hello"</p>
<p>一个类可以定义多个特殊方法（就是方法的名字前后都有两个下划线），而它们又与实例的特殊操作有关。我在&#8220;Special Methods&#8221;中有详细讨论。</p>
<p>5.1.3.3 Class-private variables<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>当一个类体中的语句（或者是一个方法）使用一个标识符以两个下划线开头（但不是结尾），比如就像 ``__ident`` ，python就会隐式地将标识符转成了 ``_classname__ident`` ，此次 ``classname`` 就是类的名字。这就可以使一个类使用私有的命名，以此减少无意中命名冲突的风险。</p>
<p>根据约定，所有以单下划线起始的标识符，意味着对于绑定它们的作用域是私有的，不管这个作用域是不是一个类。python编译器并不会强制进行转换；这完全取决于编程人员来遵守它。</p>
<p>5.1.3.4 Class documentation strings<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>如果在类体中的第一条语句是一个字符串常量，那么编译器会将其认为是这个类的文档。这个属性叫做 ``__doc__`` 而且也被叫做一个类的 *docstring* 。更多地参考 &#8220;Docstring&#8221;。</p>
<p>5.1.4 Descriptors<br>-----------------</p>
<p>一个描述符，就是一个新式的对象，而这个类提供了特殊的方法叫做 ``__get__`` 。描述符就是在语义上，控制一个实例属性的访问及设定。通俗的来讲，就是当你访问一个实例的属性时，python会通过调用描述符的 ``__get__`` 来获取属性值。具体参考&#8220;Attribute Reference Basics&#8221;。</p>
<p>5.1.4.1 Overriding and nonoverriding descriptors<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>如果一个描述符类还提供了特殊方法 ``__set__`` ，那么这个描述符就是所谓的 *overriding descripter* （或者，一个旧式的，比较混乱的术语， *data descriptor* ）；如果这个描述符类仅仅提供了 ``__get__`` ，而没有 ``__set__`` ，那么这个描述符就是所谓的 *nonoverriding descriptor* （或者是 *nondata* ）。举个例子，一个函数对象的类如果提供了 ``__get__`` ，但没有 ``__set__`` ；那么，这个函数对象就是个 *nonoverriding descriptor* 。通俗地讲，当你指派一个值给一个实例的属性，而它又是一个 *overriding* 的描述符，那么python会调用 ``__set__`` 来赋值。<br>具体的参考&#8220;Attributes of instance object&#8221;。</p>
<p>旧式的类也可以有描述符，但是在旧式类中的描述符运行起来就好像是 *nonoverriding* 一样（它们的 ``__set__`` 方法，就会被忽略）。</p>
<p>5.1.5 Instance<br>--------------</p>
<p>为创建一个类的实例，可以像调用函数一样，调用那个类对象。每次调用都会返回一个新的实例，而它的类型就是那个类：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; anInstance=C5()</p>
<p>你可以调用内置函数 ``isinstance(I,C)`` ，用一个类对象 ``C`` 作为参数。如果 ``isinstance`` 返回 ``True`` ，那么标识实例 ``I`` 是类 ``C`` 的实例或是其子类。不然， ``isinstance`` 返回 ``False`` 。</p>
<p>5.1.5.1 __init__<br>~~~~~~~~~~~~~~~~~~</p>
<p>当一个类定义了或继承了一个名为 ``__init__`` 的方法，那么调用这个类对象时，就会隐式地执行 ``__init__`` 来初始化一个新的实例。而调用时传入的参数必须要和 ``__init__`` 的参数一致，除了第一个参数 ``self`` 。举个例子，考虑下面的类：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C6(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __init__(self,n):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.x=n</p>
<p>这里是如何创建 ``C6`` 的实例：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; anotherInstance = C6(42)</p>
<p>就像在 ``C6`` 中展示的， ``__init__`` 方法一般含有绑定实例属性的语句。而且，一个 ``__init__`` 方法不能够返回一个值；否则，python会抛出一个 ``TypeError`` 异常。</p>
<p>方法 ``__init__`` 的目的，是为了绑定，从而创建新建实例的属性。你也可以绑定或解除实例的属性在 ``__init__`` 的外面，就像你等等会看到的。但是，你的代码会有更好的可读性，如果你在 ``__init__`` 方法中初始化所有属性的值。</p>
<p>当 ``__init__`` 是缺省的，那么你调用时不能给定参数。而且，新生成的实例没有因实例而特殊的属性。</p>
<p>5.1.5.2 Attributes of instance objects<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>一旦你创建了一个实例，那么你就可以访问这个属性（数据和方法）通过使用点（ ``.`` ）操作符。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; anInstance.hello()<br>&nbsp;&nbsp;&nbsp; #prints: Hello<br>&nbsp;&nbsp;&nbsp; anotherInstance.x<br>&nbsp;&nbsp;&nbsp; #prints: 42</p>
<p>属性引用有很丰富的语义，具体参考&#8220;Attribute Reference Basics&#8221;。</p>
<p>你可以给一个实例对象任意的属性，通过绑定一个值给一个属性引用。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class C7:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; z = C7()<br>&nbsp;&nbsp;&nbsp; z.x = 23<br>&nbsp;&nbsp;&nbsp; print z.x<br>&nbsp;&nbsp;&nbsp; #prints: 23</p>
<p>实例对象 ``z`` 现在就有一个名为 ``x`` 的属性，绑定了值 ``23`` ，而 ``z.x`` 则指向那个属性。注意特殊方法 ``__setattr__`` ，如果存在时，将会侦听每个绑定属性的行为。此外，对于一个新式的实例，如果你尝试绑定属性，而这个属性又是一个 *overriding* 描述符，那么这个描述符的 ``__set__`` 将会监听。在这种情况下，语句 ``z.x=23`` 其实是执行了 ``type(z).x.__set__(z,23)`` （旧式的实例将会忽略描述符的这个特性，也就是说，它们从未调用它们的 ``__set__`` 方法）。</p>
<p>创建一个实例时将隐式地设置两个实例属性。对于任何实例 ``z`` ， ``z.__class__`` 是 ``z`` 所属的类对象，而 ``z.__dict__`` 则是一个字典用来存放它的其它属性。例如，对于实例 ``z`` 我们这样创建：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; print z.__class__.__name__, z.__dict__<br>&nbsp;&nbsp;&nbsp; #prints: C7, {'x':23}</p>
<p>你可能重新绑定（但不是解除）任意或全部的属性，但是这很少是必需的。一个新式实例的 ``__class__`` 仅仅可能被重绑定到新式类上，而且一个 *legacy* 实例的 ``__class__`` 仅能绑定到 *legacy* 的类上。</p>
<p>对于任何实例 ``z`` ，对象 ``x`` ，和标识符 ``s`` （除了 ``__class__`` 和 ``__dict__`` ）， ``z.s=x`` 等价于 ``z.__dict__['s']=x`` （除非有个特殊方法 ``__setattr__`` ，或者是一个 *overriding* 描述符的特殊方法 ``__set__`` ，将会监听尝试绑定的行为）。举个例子，重新使用刚才创建的 ``z`` ：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; z.y = 45<br>&nbsp;&nbsp;&nbsp; z.__dict__['z'] = 67<br>&nbsp;&nbsp;&nbsp; print z.x, z.y, z.z<br>&nbsp;&nbsp;&nbsp; #prints: 23, 45, 67</p>
<p>在实例创建属性时使用 ``__init__`` 和显示使用 ``z.__dict__`` 是一样的。</p>
<p>5.1.5.3 The factory-function idiom<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>一个常见的任务是根据一些条件来创建不同类的实例，或者是防止创建一个新实例，假如已经存在一个可复用的。一个常见的误解就是，在 ``__init__`` 应该返回一个对象，但是这是很难实现的：python会产生异常，当返回了任何值而不是 ``None`` 。最好的方式来执行一个灵活对象的创建，是使用普通的函数，而不是直接调用这个类对象。一个扮演这个角色的函数称为一个 *factory function* 。</p>
<p>调用一个 *factory function* 是一个很灵活的方法：一个函数可能会返回一个已存在可复用的实例，或者是创建一个新的实例通过调用任何适合的类。加入你有两个差不多可交换的类（ ``SpecialCase`` 和 ``NormalCase`` ），而你希望依据参数，灵活地创建合适的实例。下面的 *factory function* ``appropriateCase`` 就允许你做这样的事情：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class SpecialCase(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def amethod(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "special"</p>
<p>&nbsp;&nbsp;&nbsp; class NormalCase(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def amethod(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "normal"</p>
<p>&nbsp;&nbsp;&nbsp; def appropriateCase(isnormal=True):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if isnormal:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NormalCase()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return SpecialCase()</p>
<p>&nbsp;&nbsp;&nbsp; aninstance = appropriateCase(isnormal=False)<br>&nbsp;&nbsp;&nbsp; aninstance.amethod()<br>&nbsp;&nbsp;&nbsp; #prints "special", as desired</p>
<p>5.1.5.4 __new__<br>~~~~~~~~~~~~~~~</p>
<p>每一个新式类都有（或继承了）一个静态方法（ **static method** ） ``__new__`` 。当你调用 ``C(*args,**kwds)`` 来创建类 ``C`` 的新实例时，Python会首先调用 ``C.__new__(C,*args,**kwds)`` 。Python使用 ``__new__`` 的返回值 ``x`` 作为新创建的实例。然后，python会再调用 ``C.__init__(x,*args,**kwds)`` ，但是仅仅当 ``x`` 确实是 ``C`` 或它子类的实例时（不然，``x`` 的状态仍处于 ``__new__`` 留给它的 ）。因此，举个例子，语句 ``x=C(23)`` 等同于：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; x = C.__new__(C,23)<br>&nbsp;&nbsp;&nbsp; if isinstance(x,C):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type(x).__init__(x,23)</p>
<p>这里， ``object.__new__`` 将创建一个新的，为初始化的实例，并且接受这个类作为第一个参数。它将会忽略其他的参数，如果它有一个 ``__init__`` 方法。但是如果它接受其他参数在这个参数之前，那么将会产生一个异常。当然如果没有 ``__init__`` 方法也是会抛出异常的。当你在类体中重载了 ``__new__`` ，你不需要增加 ``__new__=staticmethod(__new__)`` ，就如你一般会喜欢的：python会识别这个名字 ``__name__`` 并且在它的上下文特殊地处理它。在那些不常有的情况下，如果你在类体外面重新绑定了 ``C.__new__`` 那么你就确实需要使用 ``C.__new__=staticmethod(whatever)`` 。</p>
<p>对于 ``__new__`` 有着大部分 **factory function** 的灵活性。 ``__new__`` 将会适时地选择返回一个已存在的实例或创建一个新的实例。当 ``__new__`` 确实需要创建一个新的实例，它经常会把创建的任务委托给 ``object.__new__`` 的调用或者是它其他父类的 ``__new__`` 的调用。下面的例子演示了如何重载静态方法 ``__new__`` 为了实现一个 **Singleton** 设计模式：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class Singleton(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _singletons={}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __new__(cls,*args,**kwds):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if cls not in cls._singletons:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cls._singletons[cls] = super(Singleton,cls).__new__(cls)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return cls._singletons[cls]</p>
<p>任何 ``Singleton`` 的子类（当然没有重载 ``__new__`` ），就将只有一个实例。如果一个子类定义了一个 ``__init__`` 方法，这个子类必须确保它的 ``__init__`` 是安全的，当被重复调用时（在每次的创建请求下）。</p>
<p>旧式的类是没有 ``__new__`` 方法的。</p>
<p>5.1.6 Attribute Reference Basics<br>--------------------------------</p>
<p>一个属性引用就是形如 ``x.name`` 的表达式，这里 ``x`` 可以是任何表达式，而 ``name`` 是一个被称为 *attribute name* 的标识符。很多种python对象都具有属性，但是一个熟悉引用在 ``x`` 指向一个类或实例时具有特殊的丰富的语义。记住，方法也是属性，所以任何我们所谓的属性同样也适用于可调用的属性（比如说方法）。</p>
<p>假如 ``x`` 是一个类 ``C`` 的实例，而它又是继承自基类 ``B`` 。两个类和实例有一些属性（数据和方法），就像下面的：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class B(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = 23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = 45<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def f(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method f in class B"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def g(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method g in class B"</p>
<p>&nbsp;&nbsp;&nbsp; class C(B):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = 67<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = 89<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d = 123<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def g(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method g in class C"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def h(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method h in class C"</p>
<p>&nbsp;&nbsp;&nbsp; x = C()<br>&nbsp;&nbsp;&nbsp; x.d = 77<br>&nbsp;&nbsp;&nbsp; x.e = 88</p>
<p>一些属性名字是特殊的。举个例子， ``C.__name__`` 是字符串 ``'C'`` 而且是这个类名称。 ``C.__bases__`` 则是一个元组 ``(B,)`` ，这是类 ``C`` 的基类。 ``x.__class__`` 是类 ``C`` ，它是 ``x`` 所属的类。当你指向这些特殊的属性，这个属性引用将会访问给定的位置，然后把它找到的值拿出来。你不能解除这些属性。重新绑定是允许的，所以你可以改变名字或者是这个类的基类，或者是实例的类对象，匆忙地，但是这个高级的技术非同寻常的重要。</p>
<p>类 ``C`` 和实例 ``x`` 都各自有一个其他的特殊属性：一个叫做 ``__dict__`` 的字典。全部其他的属性，除了仅有的几个特殊属性外，全部都被放在类或实例的 ``__dict__`` 中。</p>
<p>5.1.6.1 Getting an attribute from a class<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>当你使用语法 ``C.name`` 来指向一个类 ``C`` 上的属性，搜索会分成两步进行：</p>
<p>1. 如果 ``name`` 就在 ``C.__dict__`` 中，那么 ``C.name`` 将会从 ``C.__dict__['name']`` 中取得值 ``v`` 。然后，如果 ``v`` 是一个描述符（也就是说， ``type(v)`` 提供了名为 ``__get__`` 的方法）， ``C.name`` 的值将是调用 ``type(v).__get__(v,None,C)`` 的结果。否则， ``C.name`` 的值就是 ``v`` 。<br>2. 否则， ``C.name`` 就委托给 ``C`` 的基类来查找，意味着它会沿着 ``C`` 的祖先一个个查找 ``name`` （关于其查找顺序，参考1.8.1）。</p>
<p>5.1.6.2 Getting an attribute from an instance<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>但你使用 ``x.name`` 来指向类 ``C`` 的实例 ``x`` ，搜索会分成三步进行：</p>
<p>1. 当在 ``C`` （或者是在 ``C`` 的祖先类中）找到了 ``name`` ，作为一个 *overriding* 描述符 ``v`` 的名字（也就是说， ``type(v)`` 提供了 ``__get__`` 和 ``__set__`` 方法）， ``C.name`` 的值将是调用 ``type(v).__get__(v,x,C)`` 的结果。（此步不适用于旧式实例）。<br>2. 否则，当 ``name`` 是在 ``x.__dict__`` 中的键值，那么 ``x.name`` 将会获取并返回 ``x.__dict__['name']`` 的值。<br>3. 否则， ``x.name`` 将搜索委托给 ``x`` 的类（和搜索 ``C.name`` 的两步是一样的，就像刚才所说的 ）。如果一个描述符 ``v`` 被找到了，那么属性搜寻的结果，又将是 ``type(v).__get__(v,x,C)`` ；如果是一个非描述符值 ``v`` 被找到，那么结果就是 ``v`` 。</p>
<p>当这些搜索步骤结束后没有找到属性，python就会产生一个 ``AttributeError`` 的异常。但是，对于 ``x.name`` 的搜索，如果 ``C`` 定义或者继承了特殊方法 ``__getattr__`` ，python将会调用 ``C.__getattr__(x,'name')`` 而不是产生一个异常（这完全取决于 ``__getattr__`` 是返回一个合适的值还是产生一个合适的异常，经常是 ``AttributeError`` ）。</p>
<p>考虑下面的属性引用：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; print x.e, x.d, x.c, x.b, x.a<br>&nbsp;&nbsp;&nbsp; #prints: 88, 77, 89, 67, 23</p>
<p>这里的 ``x.e`` 和 ``x.d`` 在实例搜寻的第二步就成功了，因为没有涉及描述符，而且 ``e`` 和 ``d`` 都是在 ``x.__dict__`` 中的键值。所以，搜索不会继续，而是返回 ``88`` 和 ``77`` 。而其他三个则是到第三步，并且搜索了 ``x.__class__`` （也就是 ``C`` ）。 ``x.c`` 和 ``x.b`` 是在类搜寻的第一步就成功了，因为 ``c`` 和 ``b`` 是在 ``C.__dict__`` 中。所以它们就返回了 ``89`` 和 ``67`` 。而 ``x.a`` 则是直到类搜索的第二步，搜索 ``C.__bases__[0]`` （也就是 ``B`` ）。 ``a`` 是 ``B.__dict__`` 的键值，所以 ``x.a`` 终于成功并且返回 ``23`` 。</p>
<p>5.1.6.3 Setting an attribute<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>注意属性搜寻的步骤，只有在你引用它时才会发生，而不是在你绑定一个属性的时候。当你绑定（不管是类还是实例）一个属性时，而它的名字不是特殊的（除非有个 ``__setattr__`` 方法，或者是一个 *overriding* 描述符的 ``__set__`` 方法，截取一个实例属性的绑定），你仅仅影响了在 ``__dict__`` 中的属性（在类或实例中）。换句话说，在属性绑定的情况下，是没有搜索被执行的，除了检查是否是个 *overriding* 描述符。</p>
<p>5.1.7 Bound and Unbound Methods<br>-------------------------------</p>
<p>一个函数对象的 ``__get__`` 方法返回一个包装了函数的 *unbound method object* 或 *bound method object* 。在两者间的不同点在于，一个 **unbound method** 没有和一个特别的实例绑定，而 **bound method** 则有。</p>
<p>在前面段落的代码中，属性 ``f`` ， ``g`` 和 ``h`` 都是函数；所以，对于任一的属性引用将会返回一个包装了相应函数的方法对象。考虑下面的：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; print x.h, x.g, x.f, C.h, C.g, C.f</p>
<p>这个语句将输出三个绑定方法，像这样：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; &lt;bound method C.h of &lt;__main__.C object at 0x8156d5c&gt;&gt;</p>
<p>然后是像这样的三个未绑定方法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; &lt;unbound method C.h&gt;</p>
<p>当我们引用实例 ``x`` 的属性时将返回绑定方法，而引用类 ``C`` 的属性时则返回未绑定的方法。</p>
<p>因为一个绑定的方法已经和一个特殊的实例绑定了，你可以这样调用方法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; x.h()<br>&nbsp;&nbsp;&nbsp; #prints: method in class C</p>
<p>这里要注意的就是，你不需要传给方法第一个参数， ``self`` 。对于实例 ``x`` 的绑定方法会隐式地把对象 ``x`` 绑定给参数 ``self`` 。因此，方法的主体能够访问实例的属性，作为 ``self`` 的属性，尽管我们没有显示的传递给方法这个参数。</p>
<p>一个未绑定的方法，是没有和一个特殊实例关联的，所以你必须指定一个合适的对象给第一个参数，当你调用一个未绑定方法，举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; C.h(x)<br>&nbsp;&nbsp;&nbsp; #prints: method h in class C</p>
<p>你调用一个未绑定的方法比绑定方法次数要少的多。未绑定方法的主要用途是来访问 *overridden* 方法；更好的是使用 ``super`` 。</p>
<p>5.1.7.1 Unbound method details<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>就像刚才我们讨论的，当一个属性引用是从类指向函数时，返回一个引用指向那个包裹了函数的未绑定方法。一个未绑定方法除了包装的函数外还有三个额外的属性： ``im_class`` 是提供方法的类对象， ``im_func`` 是被包装的函数，而 ``im_self`` 通常返回 ``None`` 。这些属性是只读的，这意味着尝试重绑定或解除绑定都会抛出异常。</p>
<p>你可以调用一个未绑定的方法就如同你调用了它的 ``im_func`` 函数，但是第一个参数必须是是 ``im_class`` 的实例或是后裔。换句话说，对于未绑定方法的调用，必须至少有一个参数，这个参数应该和被包装的函数的第一个参数一致（一般称为 ``self`` ）。</p>
<p>5.1.7.2 Bound method details<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>当一个属性引用自一个实例，在搜索中，找到一个函数对象，而那是一个实例的类中的属性，查找会调用函数的 ``__get__`` 方法来获取属性值。这个调用，在这种情况下，创建并返回了一个绑定的方法，并包裹着那个函数。</p>
<p>注意当一个属性引用的查找在 ``x.__dict__`` 中找到了函数对象，那么属性引用操作不会创建一个绑定方法，因为在这种情况下函数并不是当作一个描述符，而且，函数的 ``__get__`` 是不可调用的；更准确地说，函数对象本身就是属性值。类似的，没有一个绑定的方法是为不普通的函数调用而创建的，就如内置的（与python代码对照）函数，因为它们不是描述符。</p>
<p>一个绑定方法，和一个未绑定方法是类似的，它们都有三个只读的属性，那是包装函数对象多出来的。像在未绑定方法中， ``im_class`` 是一个提供方法的类对象，而 ``im_func`` 是被包装的函数。但是，在一个绑定方法的对象中，属性 ``im_self`` 指向获得方法的实例 ``x`` 。</p>
<p>一个绑定方法使用起来像它的 ``im_func`` 函数，但是调用绑定方法不需要显式提供第一个参数（一般约定为 ``self`` ）。当你调用一个绑定方法，在传递其他参数时，绑定方法把 ``im_self`` 传递给 ``im_func`` 的第一个参数。</p>
<p>让我们看看下面这个底层的概念上的是如何调用 ``x.name(arg)`` 。在下面的例子中：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; def f(a,b):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # a function f with two arguments</p>
<p>&nbsp;&nbsp;&nbsp; class C(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = f</p>
<p>&nbsp;&nbsp;&nbsp; x = C()</p>
<p>这里 ``x`` 是一个类 ``C`` 的实例对象， ``name`` 是一个标识符，指明了 ``x`` 的方法（ ``C`` 的属性，它是一个函数，在这里是函数 ``f`` ），而 ``arg`` 是任何的表达式。python先检查 ``name`` 是否是 ``C`` 中的属性，并且它还是一个描述符。但是事实上它并不是，因为它们的类虽然定义了 ``__get__`` 方法，但是并不是 *overriding* 的描述符，因为它们没有 ``__set__`` 方法。python接下来检查 ``name`` 是否在 ``x.__dict__`` 中。但它们也不是。所以python在类 ``C`` 中查找 ``name`` （任何东西都会起作用以同样的方式如果 ``name`` 被找到了，通过继承，在 ``C`` 的 ``__bases__`` 中）。python注意到这个属性值，也就是函数对象 ``f`` ，是一个描述符。所以，python调用 ``f.__get__(x,C)`` ，这就创建了一个绑定方法， ``im_func`` 设定为 ``f`` ， ``im_class`` 被设定为 ``C`` ，而 ``im_self`` 被设为 ``x`` 。然后python调用这个绑定方法对象，以 ``arg`` 作为唯一的参数。这个绑定方法插入了 ``im_self`` （也就是 ``x`` ）作为第一个参数，而 ``arg`` 成为第二个，然后调用 ``im_func`` （也就是 ``f`` ）。总的效果就像是这样调用：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; x.__class__.__dict__['name'](x,arg)</p>
<p>当一个绑定方法的函数体执行了，它没有特别的命名空间，不管是 ``self`` 或其他类。变量引用的是局部或全局的，就像其他的函数一样。变量并不会隐式的指明 ``self`` 的属性，或是任何其他类中的属性。当一个方法需要指向，绑定，或解除绑定一个 ``self`` 对象的属性，它也需要标准的属性引用的语法（比如， ``self.name`` ）。隐式的作用域可能会导致使用其他用过的，而python则不是这样（因为python和其他面向对象不同），但是这使得python简洁明了，而避免了混淆。</p>
<p>绑定方法对象是一级对象，你可以在任何你可以使用可调用对象的地方使用它们。因为绑定方法持有一个包装函数的引用，并且指向它所执行的 ``self`` 对象，它是更有用更灵活的选择对应嵌套的来说。一个实例对象的类提供了特殊的方法 ``__call__`` 提供了另一个可行的选择。这些概念中的每一个使你绑定一些行为（代码）和状态（数据）到一个单独的可调用对象中。嵌套可能是最简单的，但有很多的限制。这里是嵌套：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; def make_adder_as_closure(augend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def add(addend, _augend=augend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return addend+_augend<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return add</p>
<p>绑定方法和可调用的实例更加的丰富和灵活。这里是用绑定方法实现同样的功能：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; def make_adder_as_bound_method(augend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Adder(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __init__(self,augend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.augend = augend<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def add(self, addend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return addend+self.augend<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Adder(augend).add</p>
<p>这里是以一个可调用实例来执行（这个实例的类提供了特殊方法 ``__call__`` ）：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; def make_adder_as_callable_instance(augend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Adder(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __init__(self,augend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.augend=augend<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __call__(self,addend):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return addend+self.augend<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Adder(augend)</p>
<p>从这些代码调用函数来看，它们是可交换的，因为它们都返回多态的可调用对象（也就是都是可用的）。在这里，嵌套是最简单的；而其他两种则是更灵活，普遍而且更强大的机制，但是在这个简单的例子中没必要使用这么强大的功能。</p>
<p>5.1.8 Inheritance<br>-----------------</p>
<p>当你使用一个属性引用 ``C.name`` ，但是 ``name`` 不在 ``C.__dict__`` 中，搜寻会隐式的在 ``C.__bases__`` 以特殊的顺序执行（历史原因，称为 *method resolution order* ，或者是 **MRO** ，甚至是对于任何属性，而不仅仅是对方法）。 ``C`` 的基类会又会依次的搜寻它们的基类。搜寻机制检查直接或间接的祖先，一个又一个，以 **MRO** 进行，当 ``name`` 被找到时将会停止。</p>
<p>5.1.8.1 Method resolution order<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>在一个类中，属性名字的搜寻本质上通过以 **left-to-right** ， **depth-first** 的顺序访问祖先发生。但是，在多继承的存在下（这样就使继承的图表是一个非循环的图表，而不是一个树形的），这个简单的方法可能导致一些祖先类被访问了两次。在这样的情况下，这种分解的顺序被阐明，通过在搜寻的列表留下右边的那个类，这将会持续到搜索完，然后再去刚才剩下的那些类中重新开始搜索。这个就使得多类继承很难正确有效的使用。而新式对象则在此方面更加高级。</p>
<p>这在 **left-right** ， **depth-first** 搜索中个问题，可以很简单的在旧式类中被论证：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class Base1:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def amethod(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Base1"</p>
<p>&nbsp;&nbsp;&nbsp; class Base2(Base1):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; class Base3:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def amethod(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Bases3"</p>
<p>&nbsp;&nbsp;&nbsp; class Derived(Base2,Base3):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; aninstance=Derived()<br>&nbsp;&nbsp;&nbsp; aninstance.amethod()<br>&nbsp;&nbsp;&nbsp; #prints: "Base1"</p>
<p>在这个情况下， ``amethod`` 的搜寻将从 ``Derived`` 开始。当没有在此处找到，将会去搜索 ``Base2`` 。因为在此处也没有找到，旧式的搜寻将会继续搜索它的父类， ``Base1`` ，而在这里找到了那个属性。所以，就是类将会停止，而不在考虑 ``Base3`` ，而在这里也可以找到那个属性。而新式的 **MRO** 则解决了那个问题，通过移除最左边的 ``Base1`` ，所以将会搜索 ``Base3`` 中的 ``amethod`` 。</p>
<p>Figure 5-1 展示了旧式和新式的 **MRO** ，在这个菱形的继承图中。</p>
<p>.. figure:: pythonian_0501.jpg<br>&nbsp;&nbsp;&nbsp; :align: center</p>
<p>&nbsp;&nbsp;&nbsp; **Figure 5-1. Legacy and new-style MRO**<br><img border=0 alt="" src="http://www.cppblog.com/images/cppblog_com/mirguest/pythonian_0501.jpg" width=549 height=376><br></p>
<p><br>每一个新式的类和内置类型都有一个特殊制度的类属性，叫做 ``__mro__`` ，这是一个用于方法分解的元组，以一定顺序存放类型。你只可以在类中引用 ``__mro__`` ，而不以在实例上，而且因为 ``__mro__`` 是只读的属性，你不可以重新绑定或解除绑定。具体的，你可以参考 Michele Simionato 写的 &#8220;The Python 2.3 Method Resolution Order&#8221; ，在 <a href="http://www.python.org/2.3/mro.html"><u><font color=#0066cc>http://www.python.org/2.3/mro.html</font></u></a> 。</p>
<p>5.1.8.2 Overriding attributes<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>就像我们刚看到的，一个属性的搜寻会依照 **MRO** （典型的是根据继承树）然后在找到时就会停止。而派生类会比他们的父类先被搜寻，这样子，当子类和父类都定义了相同名字的属性时，搜索就会在子类中寻到定义并在那里停止。这就是所谓的 **覆写** 了父类中的定义。考虑下面的例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class B(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a=23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b=45<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def f(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method f in class B"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def g(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method g in class B"</p>
<p>&nbsp;&nbsp;&nbsp; class C(B):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b=67<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c=89<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d=123<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def g(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method g in class C"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def h(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "method h in class C"</p>
<p>在这段代码中，类 ``C`` 覆写了超类 ``B`` 的属性 ``b`` 和 ``g`` 。注意，不像其他的语言，python中你可以覆写数据属性，也可以是可调用的属性（方法）。</p>
<p>5.1.8.3 Delegating to superclass methods<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>当一个子类 ``C`` 覆写了它的超类 ``B`` 中的一个方法 ``f`` 时， ``C.f`` 的主体经常需要把某些操作委托给超类中的方法来执行。这个可以使用未绑定方法，像下面：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class Base(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def greet(self,name):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Welcome ",name</p>
<p>&nbsp;&nbsp;&nbsp; class Sub(Base):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def greet(self,name):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Well Met and",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Base.greet(self,name)</p>
<p>&nbsp;&nbsp;&nbsp; x=Sub()<br>&nbsp;&nbsp;&nbsp; x.greet('Alex')</p>
<p>在 ``Sub.greet`` 的主体中，超类的委托，通过属性引用 ``Base.greet`` 使用了未绑定方法，所以正常的传递了所有的属性，包括 ``self`` 。未绑定方法最常用的就是在委托超类执行中。</p>
<p>一个很常见的委托就是在特殊方法 ``__init__`` 中。当python创建一个实例时，基类的 ``__init__`` 方法不会自动调用，就像在其他一些面向对象的语言中一样。因此，必要时，就依靠于使用委托来完成合适的初始化。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class Base(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __init__(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.anattribute = 23</p>
<p>&nbsp;&nbsp;&nbsp; class Derived(Base):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __init__(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Base.__init__(self)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.anotherattribute=45</p>
<p>如果在类 ``Derived`` 的 ``__init__`` 中未显式调用类 ``Base`` ， ``Derived`` 的实例将会丢失初始化的部分信息，所以他将缺少属性 ``anotherattribute`` 。</p>
<p>5.1.8.4 Cooperative superclass method calling<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>使用未绑定方法调用超类的方法，可能在多重继承上出问题，特别是菱形状的。考虑下面的定义：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class A(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'A.met'</p>
<p>&nbsp;&nbsp;&nbsp; class B(A):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'B.met'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A.met(self)</p>
<p>&nbsp;&nbsp;&nbsp; class C(A):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'C.met'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A.met(self)</p>
<p>&nbsp;&nbsp;&nbsp; class D(B,C):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'D.met'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B.met(self)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C.met(self)</p>
<p>在这个代码中，当我们调用 ``D().met()`` ， ``A.met`` 将会出现两次。那我们如何确保祖先只被调用一次，而且仅仅一次？解决的办法就是，使用内置的 ``super`` 。 ``super(aclass,obj)`` ，将会返回对象 ``obj`` 的特殊超级对象。当我们搜寻一个属性（比如一个方法）在这个超级对象中，搜寻将会开始于在 ``obj`` 的 **MRO** 的类 ``aclass`` 中。所以我们可以这样改写先前的代码：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class A(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'A.met'</p>
<p>&nbsp;&nbsp;&nbsp; class B(A):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'B.met'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(B,self).met()</p>
<p>&nbsp;&nbsp;&nbsp; class C(A):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'C.met'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(C,self).met()</p>
<p>&nbsp;&nbsp;&nbsp; class D(B,C):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def met(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'D.met'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(D,self).met()</p>
<p>现在， ``D().met()`` 对每个类的 ``met`` 都只调用了一次。如果你形成了在使用超类时使用 ``super`` 的习惯，那么尽管可能有很复杂的结构，你的类也能很好的使用。无论这个继承结果有多简单，使用这个并没有坏处，而且，我也推荐使用新式的对象模型。</p>
<p>你使用未绑定方法的技术的唯一的情况，可能就是，类之间的方法有不相容的签名，但如果你真的要处理这种东西，那么使用未绑定方法的技术可能会至少有点讨厌。多重继承的合适使用可能会有限制。但是，就算OOP的大多数基本的特征，像在基类与子类间的多态将会因为签名的不一致导致有所削减。</p>
<p>5.1.8.5 "Deleting" class attributes<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>继承和覆写提供了简单有效的方式来增加或修改类属性（特别是方法）但不带侵略性的（也就是说，不会修改那个定义了属性的类）通过在子类中增加或覆写属性。但是，继承并不提供来删除或隐藏基类的属性的方式但不带侵略性的。如果子类定义或覆写一个属性失败了，python就会寻找基类的定义。如果你需要执行这样的删除，那么可能包含：</p>
<p>* 覆写方法并在方法内产生异常。<br>* 避开继承，拥有这个属性在其他地方而不是在子类的 ``__dict__`` ，而且定义 ``__getattr__`` 来有选择的委托。<br>* 使用新式对象模型，而且覆写 ``__getattribute__`` 实现相同的效果。</p>
<p>5.1.9 The Built-in object Type<br>------------------------------</p>
<p>内置的 ``object`` 类型是全部内置类型和新式类的祖先。这个 ``object`` 类型定义了一些特殊的方法，它们执行对象的默认语义。</p>
<p>``__new__`` ``__init__``<br>&nbsp;&nbsp;&nbsp; 你可以创建一个 ``object`` 的直接实例，通过不带参数的调用 ``object()`` 。调用将会隐式地使用 ``object.__new__`` 和 ``object.__init__`` 来创建和返回一个没有属性的实例对象（甚至没有存放属性的 ``__dict__`` ）。这个实例对象就像一个&#8220;哨兵&#8221;一样有用，保证不和其他不同的对象不相同。</p>
<p>``__delattr__`` ``__getattribute__`` ``__setattr__``<br>&nbsp;&nbsp;&nbsp; 默认的，一个对象操作属性引用通过使用 ``object`` 的这些方法。</p>
<p>``__hash__`` ``__repr__`` ``__str__``<br>&nbsp;&nbsp;&nbsp; 任意对象可以传递给函数 ``hash`` 和 ``repr`` 和传给类型 ``str`` 。</p>
<p>一个 ``object`` 的子类会覆写这些方法或增加其他。</p>
<p>5.1.10 Class-Level Methods<br>--------------------------</p>
<p>Python提供了两种内置的 **nonoverriding** 描述符类型，这就给了一个类两种不同的&#8220;类级方法（classlevel method）&#8221;。</p>
<p>5.1.10.1 Static methods<br>~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>一个 **static method** 是一个方法，你可以在类上或者在类的任意实例调用，但没有特殊的行为和普通方法的约束，绑定和未绑定，而且关注第一个参数。一个静态方法可以有任意的签名；它可以没有参数，而第一个参数没有什么作用。你可以认为静态方法就是一个普通的函数，你可以正常的调用，尽管它事实上是一个绑定到类的方法。当它并不是必须要定义静态方法时（你总可以定义一个正常的函数取代之），一些程序员认为它们是一个精致的选择当一个函数的目的是更紧的绑定到一些特殊类上。</p>
<p>要创建一个静态方法，调用内置类型 ``staticmethod`` 然后把它的结果绑定到一个类属性。像所有的属性绑定，通常是在类体中被完成的，当然你也可以放在其他位置。唯一要给 ``staticmethod`` 的参数就是当python调用这个静态方法时要调用的函数。下面的例子展示了如何定义和调用一个静态方法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class AClass(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def astatic():<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'a static method'<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; astatic=staticmethod(astatic)</p>
<p>&nbsp;&nbsp;&nbsp; anInstance=AClass()<br>&nbsp;&nbsp;&nbsp; AClass.astatic()<br>&nbsp;&nbsp;&nbsp; #prints: a static method<br>&nbsp;&nbsp;&nbsp; anInstance.astatic()<br>&nbsp;&nbsp;&nbsp; #prints: a static method</p>
<p>这个例子对于要传递给静态方法的函数和静态方法返回的结果使用相同的名字。这个方式并不是强制的，但是个好的主意，而且我也推荐使用。在Python 2.4中提供了特殊，简单的语法，可以参考 **装饰符** 。</p>
<p>5.1.10.2 Class methods<br>~~~~~~~~~~~~~~~~~~~~~~</p>
<p>一个类方法是一个方法，你可以在类或其任意实例中调用。Python把你所调用方法的类绑定给了这个方法的第一个参数，或者也可以所调用方法的实例的类；它并不会像绑定方法一样，把实例绑定给第一个参数。对于类方法来说，是没有等同的未绑定方法的。第一个参数一般约定为 ``cls`` 。虽然定义一个类方法不是必须的（你可以定义一个函数，然后接受类对象作为第一个参数），一些程序员认为对于这些函数来说是不错的选择。</p>
<p>要创建一个类方法，调用内置类型 ``classmethod`` 然后再把结果绑定到类属性上。也许所有的属性绑定，经常将其写在类体中，但你也可以在其他地方实现。而唯一的参数就是这个要作为类方法调用的函数。下面是定义和调用：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class ABase(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def aclassmet(cls):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'a class method for',cls.__name__<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; aclassmet=classmethod(aclassmet)</p>
<p>&nbsp;&nbsp;&nbsp; class ADeriv(ABase):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; bInstance=ABase()<br>&nbsp;&nbsp;&nbsp; dInstance=ADeriv()<br>&nbsp;&nbsp;&nbsp; ABase.aclassmet()<br>&nbsp;&nbsp;&nbsp; #prints: a class method for ABase<br>&nbsp;&nbsp;&nbsp; bInstance.aclassmet()<br>&nbsp;&nbsp;&nbsp; #prints: a class method for ABase<br>&nbsp;&nbsp;&nbsp; ADeriv.aclassmet()<br>&nbsp;&nbsp;&nbsp; #prints: a class method for ADeriv<br>&nbsp;&nbsp;&nbsp; dInstance.aclassmet()<br>&nbsp;&nbsp;&nbsp; #prints: a class method for ADeriv</p>
<p>同样，和上一小节所说，可以使用 **装饰符** 。</p>
<p>5.1.11 Properties<br>-----------------</p>
<p>python提供一个内置的 **overriding** 描述符，你可以用来给出一个类的实例 **property** 。</p>
<p>一个 **property** 是一个实例的属性，有着特殊的功能。你引用，绑定，解绑定一个属性可以用一个普通的语法（也就是 ``print x.prop`` ，``x.prop=23`` ， ``del x.prop`` ）。但是，不仅仅是这些普通的语义，你还可以给其指定特殊的方法。下面是定义一个只读的属性：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class Rectangle(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __init__(self,width,height):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.width=width<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.height=height<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def getArea(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self.width*self.height<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; area=property(getArea,doc='area of the rectangle')</p>
<p>每一个类 ``Rectangle`` 的实例 ``r`` 都有个只读的属性 ``r.area`` ，通过调用方法 ``r.getArea()`` 把矩形的两边相乘。而docstring ``Rectangle.area.__doc__`` 则是 ```area of the rectangle``` 。属性 ``r.area`` 是只读的（尝试重绑定或解绑定都会失败）因为我们只给 ``property`` 一个 ``get`` 方法，而没有 ``set`` 或 ``del`` 方法。</p>
<p>属性和特殊方法 ``__getattr__`` ， ``__setattr__`` ， ``__delattr__`` 的工作差不多，但是方法更快更简单。你可以创建一个属性通过调用内置的 ``property`` 并把结果绑定给类属性。想其他的属性，一般是放在类体中，当然你也可以放其他地方。在类 ``C`` 内，使用这样的语法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; attrib=property(fget=None,<br>&nbsp;&nbsp;&nbsp; fset=None, fdel=None,<br>&nbsp;&nbsp;&nbsp; doc=None)</p>
<p>当 ``x`` 是 ``C`` 的实例，你又引用 ``x.attrib`` ，python会调用 ``fget`` 给属性构造器，但没有参数。当以 ``x.attrib=value`` 赋值是，python会调用 ``fset`` ，并把 ``value`` 作为唯一传人的参数。而当执行 ``del x.attrib`` ，python又会执行 ``fdel`` ，不传人任何参数。python又会将 ``doc`` 的内容作为 ``doctstring`` 。 ``property`` 的全部参数都是 *可选的* 。当一个参数没有，那么这个操作就被认为是禁止的（此时，python会产生一个异常）。举个例子，刚才我们使 ``Rectangle`` 的属性 ``area`` 只读，那是因为我们只提供了 ``fget`` ，而没有 ``fset`` 或 ``fdel`` 。</p>
<p>5.1.11.1 Why properties are important<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>属性的重要性在于，它们的存在使得非常安全，而且你可以使这个属性作为公共接口。如果这变得必要的，在你以后的版本中可能需要这个属性多态运行，或是在被引用、重绑定或解绑定时调用其他的一些代码，你知道你将会将简单的属性变成 **property** ，而且得到想要的效果但不对其他代码产生影响。这就使你避免笨的特色，像一个 *accessor* 或 *mutator* 方法，这是在缺少 **property** 或等同机制的OOp中经常需要的。举个例子，客户代码可以使用下面自然的语法：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; someInstance.widgetCounter += 1</p>
<p>而不是像下面这种嵌套的形式：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; someInstance.setWidgetCounter(someInstance.getWidgetCounter()+1)</p>
<p>如果编写代码时，你考虑使用 ``getThis`` 或 ``setThis`` 的名字，那么就考虑使用 **property** 来变得清楚。</p>
<p>5.1.11.2 Properties and inheritance<br>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</p>
<p>**property** 也可以像其他属性那样继承。但是，这里可能有点小陷阱： **property** 所调用的是它所在类中的方法，而不是其子类的方法。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class B(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def f(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g=property(f)</p>
<p>&nbsp;&nbsp;&nbsp; class C(B):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def f(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 42</p>
<p>&nbsp;&nbsp;&nbsp; c=C()<br>&nbsp;&nbsp;&nbsp; print c.g<br>&nbsp;&nbsp;&nbsp; #prints 23, not 42</p>
<p>属性 ``c.g`` 调用了 ``B.f`` ，而不是你直觉上所想的 ``C.f`` 。这个原因很简单：因为 **property** 是通过传递函数对象 ``f`` 创建的（而且是在 ``B`` 被执行时所创建，所以这个时候，这个函数对象就被认为是 ``B.f`` ）。事实上， ``f`` 在子类 ``C`` 中被重新定义了，但是因为 **property** 并没有搜寻到它，而只是使用了先前的那个。如果你需要解决这个问题，那么就需要引入一个间接层：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class B(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def f(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 23<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def _f_getter(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self.f()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g=property(_f_getter)</p>
<p>&nbsp;&nbsp;&nbsp; class C(B):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def f(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 42</p>
<p>&nbsp;&nbsp;&nbsp; c=C()<br>&nbsp;&nbsp;&nbsp; print c.g<br>&nbsp;&nbsp;&nbsp; #prints 42, as expected</p>
<p>这里，被 **property** 所持有的函数对象是 ``B._f_getter`` ，它在执行时会搜寻到 ``f`` （因为它调用了 ``self.f()`` ）；所以，覆写的 ``f`` 会起效果。</p>
<p>5.1.12 __slots__<br>----------------</p>
<p>一般来说，任何类 ``C`` 的每个实例对象 ``x`` 都有一个字典 ``x.__dict__`` ，这是python用来让你任意绑定属性给 ``x`` 的。为了节省点内存（让 ``x`` 仅使用预定义的属性），你可以定义一个新式类 ``C`` 的 ``__slots__`` 属性，这是一个字符串（通常是表示符）序列（通常是元组）。当一个新式类 ``C`` 有个属性 ``__slots__`` 时，一个类 ``C`` 的直接实例 ``x`` 是没有 ``x.__dict__`` 的，而且尝试绑定不在 ``C.__slots__`` 中的属性将会产生异常。使用了 ``__slots__`` 就使你减少了内存的消耗，对于小的实例对象，这是很值得的，当有很多这样的对象时，就节省了大大的空间。但不像大多数的属性， ``__slots__`` 只有当一些类体中的语句把它绑定为类属性时才有效。后来修改 ``__slots__`` 是不起效果的，继承也是。这里是把 ``__slots__`` 增加到 ``Rectangle`` 中：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class OptimizedRectangle(Rectangle):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __slots__='width','height'</p>
<p>我们不需要给 ``area`` 定义个 *slot* 。 ``__slots__`` 中并不放 **property** ，仅仅是普通的实例对象，这些属性如果没有在 ``__slots__`` 中定义，将会搜寻 ``__dict__`` 。</p>
<p>5.1.13 __getattribute__<br>-----------------------</p>
<p>对于新式的实例，实例属性的引用都是通过特殊方法 ``__getattribute__`` 执行的。这个方法是基类 ``object`` 所提供的，它执行了所有具体的属性引用。但是，你也可以覆写这个 ``__getattribute__`` 方法，像隐藏被继承类的属性。下面的例子展示了在新式对象模型中一个没有 ``append`` 的链表：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class listNoAppend(list):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __getattribute__(self,name):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if name=='append':<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise AttributeError,name<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return list.__getattribute__(self,name)</p>
<p>类 ``listNoAppend`` 的实例 ``x`` 几乎和内置的链表对象是一样的，除了当调用 ``x.append`` 时将产生异常。</p>
<p>5.1.14 Per-Instance Methods<br>---------------------------</p>
<p>不管旧式或是新式的对象模型，都允许一个实例，拥有一个实例特化的属性绑定，包括可调用的属性。对于一个方法，就像其他的属性（除了那些新式类中的 **overriding** 描述符），一个实例特化绑定隐藏了一个类级的绑定：属性搜索如果在实例中找到了就不会考虑类了。在两种对象模型中，对于可调用属性的一个实例特化的绑定不会进行什么变换。换句话说，一个属性引用返回相同的可调用对象，而且已经在先前已经绑定。</p>
<p>旧式和新式的对象模型的确有区别，在每个实例绑定的效果上，python会隐式地调用。在经典的的对象模型中，一个实例一般会覆写一个特殊方法，然后python在隐式调用方法时使用每个实例的绑定。在新式的对象模型上，特殊方法的隐式使用一般依赖于特殊方法的类级绑定，如果有的话。下面的代码展示了两者的区别：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; def fakeGetItem(idx):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return idx</p>
<p>&nbsp;&nbsp;&nbsp; class Classic:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; c=Classic()<br>&nbsp;&nbsp;&nbsp; c.__getitem__=fakeGetItem<br>&nbsp;&nbsp;&nbsp; print c[23]<br>&nbsp;&nbsp;&nbsp; # prints: 23</p>
<p>&nbsp;&nbsp;&nbsp; class NewStyle(object):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>&nbsp;&nbsp;&nbsp; n=NewStyle()<br>&nbsp;&nbsp;&nbsp; n.__getitem__=fakeGetItem<br>&nbsp;&nbsp;&nbsp; print n[23]<br>&nbsp;&nbsp;&nbsp; #prints in:<br>&nbsp;&nbsp;&nbsp; # Traceback (most recent call last):<br>&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp; File "&lt;stdin&gt;", line 1, in ?<br>&nbsp;&nbsp;&nbsp; # TypeError: unindexable object</p>
<p>经典对象模型的语义在这个方面可能比较有用。但是，新式对象模型的方法更普遍，而且它调整和简化了类和元类的关系。</p>
<p>5.1.15 Inheritance from Built-in Types<br>--------------------------------------</p>
<p>一个新式类可以从内置类型派生。但是，一个类可能直接或间接从多个内置的类型派生，如果这些类型是特殊设计的，来允许这个层次的兼容。python不支持不受拘束的继承从多个任意的内置对象中。一般的，一个新式类只能以其中一种派生，当然也包括 ``object`` ，这是所有的类型的超类。举个例子：</p>
<p>::</p>
<p>&nbsp;&nbsp;&nbsp; class noway(dict,list):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass</p>
<p>将会产生一个 ``TypeError`` 异常，具体会解释为&#8220;当调用元类的基类有错误：多基类有实例的冲突&#8221;。如果你曾经看过这样的错误，这就意味着你尝试继承，直接或间接，从多个内置类型派生，但他们并不是设定为可合作的。<br></p>
<img src ="http://www.cppblog.com/mirguest/aggbug/139703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mirguest/" target="_blank">mirguest</a> 2011-02-03 10:55 <a href="http://www.cppblog.com/mirguest/archive/2011/02/03/139703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>