PyQt

出自Local Chinese Wikipedia
跳至導覽 跳至搜尋
PyQt
File:Python and Qt.svg
Qt Designer
Qt Designer
開發者Riverbank Computing
首次發布1998
當前版本
    Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)
    源代碼庫
    • {{URL|example.com|可选的显示文本}}
    Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)
    編程語言C++ / Python[1]
    引擎
      Module:EditAtWikidata第29行Lua錯誤:attempt to index field 'wikibase' (a nil value)
      操作系統跨平台
      許可協議GNU GPL和商業授權
      網站riverbankcomputing.com

      PyQtPython語言的GUI編程解決方案之一。可以用來代替Python內置的Tkinter。其它替代者還有PyGTKwxPython等。與Qt一樣,PyQt是一個自由軟件。PyQt是PyKDE的基礎。

      PyQt的開發者是英國的「Riverbank Computing」公司。與4.5版本之前的Qt一樣,它提供了GPL與商業協議兩種授權方式,因此它可以免費地用於自由軟件的開發。不過目前尚不提供LGPL授權方式。PyQt可以運行於Microsoft WindowsMac OS XLinux以及Unix的多數變種上。

      2009年8月,Qt的開發公司諾基亞發布PySide,提供與PyQt類似的功能,但提供了LGPL授權。主要原因是「Riverbank Computing」不願以LGPL授權發布PyQt。[2]

      自4.5版本以後[3],PyQt同時支持Python 2.x與Python 3.x。但是在API方面有所區別,最主要的是運行在Python 3.x下的PyQt不使用QString,而是str。另外,之前為了避開Python 2.x關鍵詞限制的exec_()print_()兩個函數現在重新命名為exec()print()

      File:Python and Qt 2.svg
      另外一種PyQt標誌

      PyQt組件[編輯]

      PyQt包含了大約440個類型、超過6000個的函數和方法。

      • 「QtGui」模塊包含了大多數的GUI類型。包含按鈕、文本框、列表等常見控件,還包含了基於MVC設計模式的列表、表格、樹型控件。同時還提供了一個能夠容納成千上萬個元素的畫布控件,其中可以放置各種控件和圖形。此外,QtGui還支持界面動畫與界面狀態機編程。
      • 「QtNetwork」模塊可以用於編寫非阻塞式的UDP、TCP程序。還包含了DNS、HTTP與FTP的客戶端。
      • 「QtOpenGL」模塊允許Qt程序使用OpenGL渲染3D圖形,而且不必大量更改代碼。
      • 「QtSql」模塊支持多種SQL數據庫。包括SQLiteODBCMySQLPostgreSQLOracle。還提供了一個基於MVC模式的數據模型,與QtGui的的表格控件配合使用。
      • 「QtXml」包含一個XML解釋器,同時支持SAXDOM兩種編程方式。
      • 「QtWebkit」與「QtScript」兩個子模塊支持WebKitECMAScript腳本語言
      • 「Phonon」子模塊支持高級的多媒體編程。包含音頻播放器、視頻播放器與聲效處理。
      • 「uic」子模塊能夠將Qt的窗體文件轉換為Python代碼,能夠即時讀入窗體文件並且顯示出來。它依賴於QtXml模塊。「QScintilla」子模塊包含一個基於Scintilla的文本編輯器控件,Eric IDE使用它作為代碼編輯器。「QtMultimedia」提供了底層的多媒體支持,現在多數開發者改用Phonon模塊。「QtSvg」支持SVG 1.2 Tiny的靜態標準,用於顯示與保存SVG格式的圖形。

      簡單例子[編輯]

      下面一段代碼演示了一個簡單的PyQt程序,它的功能是在窗體內顯示一個按鈕,當按下按鈕時,要求用戶輸入名字。根據用戶是否輸入了名字,會分別顯示兩種問候語。

      File:PyQt Example Screenshot.png
      結果
      # -*- coding: utf-8 -*-
      #该程序适合Python 2.x
      
      import sys
      from PyQt4.QtGui import *
      
      class TestWidget(QWidget):
          def __init__(self):
              QWidget.__init__(self, windowTitle=u"A Simple Example for PyQt.")
              self.outputArea=QTextBrowser(self)
              self.helloButton=QPushButton(self.trUtf8("问候(&S)"), self)
              self.setLayout(QVBoxLayout())
              self.layout().addWidget(self.outputArea)
              self.layout().addWidget(self.helloButton)
      
              self.helloButton.clicked.connect(self.sayHello)
      
          def sayHello(self):
              yourName, okay=QInputDialog.getText(self, self.trUtf8("请问你的名字是?"), self.trUtf8(b"名字"))
              if not okay or yourName==u"": #用户没有输入名字,或者是点了取消
                  self.outputArea.append(self.trUtf8("你好,陌生人!"))
              else:
                  self.outputArea.append(self.trUtf8("你好,<b>%1</b>。").arg(yourName))
      
      app=QApplication(sys.argv)
      testWidget=TestWidget()
      testWidget.show()
      sys.exit(app.exec_())
      

      signal和slot[編輯]

      Qt採用了signal和slot的概念來處理GUI程序中的用戶事件。PyQt同樣支持這種方法,還進而針對Python的特點增強了某些功能。任何Python類型都可以定義signal和slot,並與GUI控件的signal和slot相連接。PyQt支持old-style與new-style兩種連接方式。不過,目前一般推薦使用new-style connection。因為它還支持連接到Python函數,而且看起來也比較pythonic。

      #old-style connection,
      self.connect(self, SIGNAL("mySignal(int)"), self, SLOT("mySlot(int)"))
      #new-style connection
      self.mySignal.connect(self.mySlot)
      #连接到函数
      self.mySignal.connect(lambda value:sys.stdout.write(str(value)))
      

      QMetaObject.connectSlotsByName(obj)函數可以幫助程序員自動連接signal和slot。使用它可以免去很多代碼。

      Qt設計器[編輯]

      Qt設計器是Qt所包含的可視化UI設計器。在安裝PyQt時,可以選擇安裝Qt設計器。它使用拖拉操作來設計圖形界面。在設計的同時,還能夠直接預覽最終的窗體效體。當窗體很複雜或者整個程序需要大量的窗體時,Qt設計器可以節省大量的代碼。不過稍有改變的是,設計好窗體後需要運行pyuic4這個腳本,將窗體文件轉換成Python代碼。仍以「簡單例子」中的小程序為例,首先使用Qt設計器設計出窗體。假定保存為"h:\pyqt_example.ui"。窗體文件內容是:

      <?xml version="1.0" encoding="UTF-8"?>
      <ui version="4.0">
       <class>TestWidget</class>
       <widget class="QWidget" name="TestWidget">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>0</y>
          <width>361</width>
          <height>271</height>
         </rect>
        </property>
        <property name="windowTitle">
         <string>A Simple Example for PyQt.</string>
        </property>
        <layout class="QVBoxLayout" name="verticalLayout">
         <item>
          <widget class="QTextBrowser" name="outputArea"/>
         </item>
         <item>
          <widget class="QPushButton" name="helloButton">
           <property name="text">
            <string>问候(&amp;S)</string>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
       <resources/>
       <connections/>
      </ui>
      

      使用如下命令將窗體文件轉換成Python代碼(適用於Windows系統):

      H:\> C:\Python26\pyuic4.bat -o ui_pyqt_example.py pyqt_example.ui
      

      新的示例程序是(假定保存為h:\pyqt_example.py):

      # -*- coding: utf-8 -*-
      #该程序适合Python 2.x版本。
      
      import sys
      from PyQt4.QtGui import *
      #差异1:从转换后的代码里面导入窗体
      from ui_pyqt_example import Ui_TestWidget
      
      #差异2:需要继承Ui_TestWidget
      class TestWidget(QWidget, Ui_TestWidget):
          def __init__(self):
              QWidget.__init__(self)
              #差异3:原来长篇累牍的创建控件的代码不再需要了,取而代之的是一行简单的setupUi()
              self.setupUi(self)
              self.helloButton.clicked.connect(self.sayHello)
      
          def sayHello(self):
              yourName, okay=QInputDialog.getText(self, self.trUtf8("请问你的名字是?"), self.trUtf8(b"名字"))
              if not okay or yourName==u"": #用户没有输入名字,而是点了取消
                  self.outputArea.append(self.trUtf8("你好,陌生人!"))
              else:
                  self.outputArea.append(self.trUtf8("你好,<b>%1</b>。").arg(yourName))
      
      app=QApplication(sys.argv)
      testWidget=TestWidget()
      testWidget.show()
      sys.exit(app.exec_())
      

      PyQt的優劣[編輯]

      優勢[編輯]

      • PyQt的API與Qt類似,Qt的文檔通常仍然可以應用於PyQt。因此,PyQt的文檔比PyGTKwxPythonTkinter等GUI編程庫的文檔豐富得多。
      • 如果程序員具備使用Qt的經驗,一般很快就可以過渡到PyQt上。而使用PyQt的程序員,如果同時精通C++的話,也可以很快地過渡到Qt平台上。
      • 利用SIP,大多數為Qt開發的控件可以方便地port到PyQt。——然而,SIP也需要一些學習成本。
      • 有方便的周邊工具支持PyQt。如QtDesigner,可以使用拖拉式的方法來設計界面,簡單易用。Eric6,一個使用PyQt設計的Python IDE,對PyQt有特殊的支持。

      劣勢[編輯]

      • 由於PyQt同時使用Qt以及Python的兩種內存管理方法,所以在使用PyQt的過程中要注意避免內存泄露以及懸掛指針[4]
      • 運行時龐大,在Windows平台,只使用PyQt.QtCore與PyQt.QtGui兩個子模塊時,壓縮後至少需要4.09M
      • 需要學習一些C++知識,主要是C++類型、內存管理兩個方面,以便於閱讀Qt文檔和理解PyQt的行為。

      SIP[編輯]

      SIP是一個自動為C和C++庫生成Python擴展模塊的工具。為了方便開發PyQt,SIP於1998被「Riverbank Computing」公司創造出來。不過,SIP不專用於PyQt,而是適用於所有的C和C++庫。

      使用SIP時,程序員首先要編寫一個特殊的".sip"文件,使用類似於C++的語法在其中描述擴展模塊所提供的類型與函數。然後用SIP將這個文件轉化為C++代碼。最終編譯,與C、C++庫鏈接後就成為Python擴展模塊。".sip"文件類似於C、C++的頭文件。根據需要,需要程序員用SIP定義的語法添加一些C++代碼中沒有的信息。因為SIP不支持完整的C++語法,所以不能直接使用C++的頭文件作為".sip"文件。

      使用PyQt的著名應用程式[編輯]

      參考文獻[編輯]

      1. ^ PyQt4 Download. Riverbankcomputing. 2010 [2010-04-19]. (原始內容存檔於2010-02-21). 
      2. ^ PySide has been released – PySide – Python for Qt. Pyside.org. 2009-08-18 [2009-09-03]. (原始內容存檔於2009-10-25). 
      3. ^ PyQt v4.5 Released. Riverbank Computing Limited. 2009-06-05 [2011-04-28]. (原始內容存檔於2010-11-14). 
      4. ^ Garbage Collection. [2013-06-24]. (原始內容存檔於2013-07-18). 

      延伸閱讀[編輯]

      外部連結[編輯]