Python pyQt4/pyQt5 學習筆記1(空白窗口,按鈕,控件事件,控件提示,窗體顯示到屏幕中間,messagebox)


PyQt4是用來編寫有圖形界面程序(GUI applications)的一個工具包。PyQt4作為一個Python模塊來使用,它有440個類和超過6000種函數和方法。同時它也是一個可以在幾乎所有主流操作系統(如Unix,windows,Mac OS)上運行的跨平台的工具包。

PyQt4的類庫可分為以下模塊:

  • QtCore
  • QtGui
  • QtNetwork
  • QtXml
  • QtSvg
  • QtOpenGL
  • QtSql

其中QtCore包含了PyQt非GUI功能模塊的核心部分,這個模塊用來對時間、文件和目錄、不同的數據類型、流、URL、資源的媒體類型、線程和進程進行處理。 
QtGui包含了圖形相關的組件和類庫,包括按鈕(button)、窗口(window)、狀態欄(status bar)、工具欄(toolbar)、滑塊(slider)、位圖(bitmap)、顏色(color)和字體(font)等等【這些名詞的英文我們在編程中會經常用到】。 
QtNetwork包含了網絡編程相關模塊。這些類庫有助於TCP/IP編程和客戶端&服務器端的UDP編程,使得網絡編程更加簡單和輕便。 
QtXml包含處理Xml文件的類庫。這個模塊提供了對SAM和DOM接口的實現。 
QtSvg提供了顯示svg文件的類庫。SVG,全稱Scalable Vector Graphics,即可縮放矢量圖形,是一種基於xml的描述二維圖形和圖像應用的文件格式。 
QtOpenGL是用OpenGL庫來渲染2D、3D圖像的模塊。它可以使Qt GUI庫和OpenGL庫無縫接合【好厲害的樣子】。 
最后,QtSql模塊提供了處理數據庫的類庫。

 

PyQt4 和 PyQt5 的不同之處

The PyQt5 is not backward compatible with PyQt4; there are several significant changes in PyQt5. However, it is not very difficult to adjust older code to the new library. The differences are, among others, the following:

PyQt5不向后兼容PyQt4;這是一些在PyQt5中的重要改變。然而,將舊代碼遷移到新的版本中並不是非常困難。不同點如下:

  • Python 模塊已經被改寫. 一些模塊被舍棄 (QtScript), 部分的模塊被分割成子模塊 (QtGuiQtWebKit).
  • 新的模塊被引進, 包含 QtBluetoothQtPositioning, 和 Enginio.
  • PyQt5 只支持最新風格的信號和槽的寫法. SIGNAL()和SLOT()的調用將不會被長時間支持.
  • PyQt5 不支持任何在Qt 5.0版本中棄用或取消的API

其它GUI框架

寫GUI程序的Python程序員可以在這三種框架中選擇:PyQt,PyGTK和wxPython。

 

例子:生成一個空白窗口

 下面是PyQt4的程序(windows版本):

 1 import sys
 2 from PyQt4 import QtGui
 3 
 4 def main():
 5     app=QtGui.QApplication(sys.argv)
 6     w=QtGui.QWidget()
 7     w.resize(250,150)
 8     w.move(300,300)
 9     w.setWindowTitle('Simple')
10     w.show()
11     sys.exit(app.exec_())
12 
13 if __name__=='__main__':
14     main()

 結果:

w = QtGui.QWidget()

QtGui.QWidget是PyQt4所有用戶接口對象中的基礎類庫。我們在這里調用了QtGui.QWidget的默認構造函數,這個構造沒有父對象。我們把沒有父對象的部件(widget)叫做窗口(window)

 

下面是PyQt5的相同例子(macOS版本):

 1 import sys
 2 from PyQt5.QtWidgets import QApplication, QWidget
 3 
 4 def main():
 5     app=QApplication(sys.argv)
 6     w=QWidget()
 7     w.resize(250,150)
 8     w.move(300,300)
 9     w.setWindowTitle('Simple')
10     w.show()
11     sys.exit(app.exec_())
12 
13 if __name__=='__main__':
14     main()

結果:

 

例子:按鈕,控件事件,控件提示,窗體顯示到屏幕中間,messagebox

下面是PyQt4的程序(windows版本)

import sys
from PyQt4 import QtGui,QtCore

class winForm(QtGui.QWidget):
    def __init__(self):
        super(winForm,self).__init__()
        self.initUI()

    def initUI(self):
        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif',10))
        self.setToolTip('this is a <b>QWidget</b> widget')
        btn=QtGui.QPushButton('Button',self)
        btn.setToolTip('this is a <b>QPushButton</b> widget')
        btn.resize(btn.sizeHint())
        btn.move(50,50)
        

        btn1=QtGui.QPushButton('Quit',self)
        btn1.clicked.connect(QtCore.QCoreApplication.instance().quit)
        btn1.resize(btn1.sizeHint())
        btn1.move(150,50)
        
        self.setGeometry(300,300,250,150)
        self.setWindowTitle('Tooltips')
     self.setWindowIcon(QtGui.QIcon()) self.center() self.show()
def closeEvent(self,event): res=QtGui.QMessageBox.question(self,'info', "你要確定退出嗎?",QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) if res==QtGui.QMessageBox.Yes: event.accept() else: event.ignore() def center(self): qr=self.frameGeometry() cp=QtGui.QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def main(): app=QtGui.QApplication(sys.argv) ex=winForm() sys.exit(app.exec_()) if __name__=='__main__': main()

 

下面是程序的運行效果,依次演示了控件提示,messagebox彈窗

      

 

下面解說上面的代碼:

class winForm(QtGui.QWidget):
    def __init__(self):
        super(winForm,self).__init__()

這里我們創建了一個新的類叫做winForm,括號中的QtGui.QWidget表明這個Example類是從QtGui.QWidget類繼承來的。這意味着我們為新類寫構造函數時需要調用父類的構造函數。super(Example, self)返回了Example的父對象(即QtGui.QWidget),接着我們調用了父對象的構造函數。注意__init__是Python中的構造函數。

注意:你必須調用父類的構造函數,否則會出現運行錯誤:

RuntimeError: super-class __init__() of type winForm was never called

 

 QtGui.QToolTip.setFont(QtGui.QFont('SansSerif',10))
        self.setToolTip('this is a <b>QWidget</b> widget')
        btn=QtGui.QPushButton('Button',self)
        btn.setToolTip('this is a <b>QPushButton</b> widget')

我們調用setTooltip()這個方法,我們還可以使用html標簽!真是想不到。筆者突然想有空可以試試加入div標簽,走馬燈標簽和超鏈接標簽試試。

 btn.resize(btn.sizeHint())
        btn.move(50,50)

我們設定了按鈕的大小,位置。其中sizeHint()方法返回了一個推薦的大小

 btn1=QtGui.QPushButton('Quit',self)
        btn1.clicked.connect(QtCore.QCoreApplication.instance().quit)
        btn1.resize(btn1.sizeHint())
        btn1.move(150,50)

這段代碼就是那個名為Quit的按鈕,它是一個push button,點擊它程序就退出。

我們在例子中要使用的QtGui.QPushButton的構造函數原型是這樣的:

QPushButton(string text, QWidget parent = None)

其中text參數是按鈕上顯示的文字。parent參數是部件的父對象,在這里就是我們要把按鈕放在什么上,本例中是一個QtGui.QWidget【其實是一個窗口(window)】

這里我們創造了一個按鈕(push button),它是QtGui.QPushButton類的一個實例。第一個參數是按鈕上的文字‘Quit’,第二個參數是父對象,這里就是我們創建的winForm了,也就是self,它繼承自QtGui.QWidget類【Example沒有父對象,是一個窗口(window),記得嗎】。

PyQt4中的事件處理系統是由信號槽機制(signals and slots)實現的。如果我們點擊了這個按鈕,就會發出“clicked”這個信號。QtCore.QCoreApplication這個東西包含了程序的主循環,它處理和分派所有的事件,而instance()方法返回的是目前的實例(insatnce)。注意到QtCore.QCoreApplication隨着QtGui.QApplication的創建而創建,而由於我們這里用connect()函數將“clicked”事件和可以終止應用的quit()函數聯系(connect)在了一起,所以點擊按鈕,應用終止。這種交流在兩個對象之間完成:發送者和接受者,其中發送者是按鈕,接受者是應用本身。

        self.setGeometry(300,300,250,150)
        self.setWindowTitle('Tooltips')
        self.setWindowIcon(QtGui.QIcon())
        self.center()
        self.show()

這段代碼設置窗體的顯示位置、大小、標題、程序圖標,最后把窗體顯示出來。還有一個自定義的函數center,用於窗體居中顯示。(你可以注釋self.center()來看看有什么不同)

由於我們是繼承 QtGui.QWidget類,我們的新類winForm其實就是一個部件(widget),有widget的所有方法,這三個方法就都出自widget。 

setGeometry這個方法,它做了兩件事情:將部件定位並設定了它的大小【其實就是resize和move的混合函數】。前兩個參數是部件相對於父元素的x,y坐標【這里其實是個窗口(window),沒有父元素記得嗎?所以是屏幕上的x,y坐標。】,后兩個參數是部件的寬和高

setWindowIcon這個方法,它設定了應用的圖標。為了做到這一點,我們創建了一個QtGui.QIon對象,創建時的參數就是我們想要的圖標的路徑

def center(self):
        qr=self.frameGeometry()
        cp=QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

自定義的函數center,用於窗體居中顯示

其中QtGui.QDesktopWidget這個類提供了用戶桌面的信息,包括屏幕大小。

frameGeometry方法得到了主窗口的矩形框架qr

QtGui.QDesktopWidget().availableGeometry().center() 這些方法來得到屏幕分辨率,並最終得到屏幕中間點的坐標cp

qr.moveCenter(cp) 將矩形框架移至屏幕正中央,大小不變

self.move(qr.topLeft())  最后我們將應用窗口移至矩形框架的左上角點,這樣應用窗口就位於屏幕的中央了【注意部件的move都是左上角移動到某點】。

 

  def closeEvent(self,event):
        res=QtGui.QMessageBox.question(self,'info',
                "你要確定退出嗎?",QtGui.QMessageBox.Yes |
                                       QtGui.QMessageBox.No,
                                       QtGui.QMessageBox.No)
        if res==QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

這段代碼出彈窗,用戶可以確認或者取消操作。

根據類定義,如果關閉QtGui.QWidget,QtGui.QCloseEvent將會執行。所以為了達到我們的目的,我們需要重新定制closeEvent()這個事件句柄(event handler)。看來類似於C#中的重寫虛函數。

 

 下面是PyQt5的相同功能的代碼(macOS版本):

 1 import sys
 2 from PyQt5.QtWidgets import QApplication, QWidget, QToolTip, QPushButton, QMessageBox, QDesktopWidget
 3 from PyQt5 import QtCore
 4 from PyQt5.QtGui import QFont, QIcon
 5 
 6 class winForm(QWidget):
 7     def __init__(self):
 8         super(winForm, self).__init__()
 9         self.initUI()
10 
11     def initUI(self):
12         QToolTip.setFont(QFont('SansSerif', 10))
13         self.setToolTip('this is a <b>QWidget</b> widget')
14         btn = QPushButton('Button', self)
15         btn.setToolTip('this is a <b>QPushButton</b> widget')
16         btn.resize(btn.sizeHint())
17         btn.move(50, 50)
18 
19         btn1 = QPushButton('Quit', self)
20         btn1.clicked.connect(QtCore.QCoreApplication.instance().quit)
21         btn1.resize(btn1.sizeHint())
22         btn1.move(150, 50)
23 
24         self.setGeometry(300, 300, 250, 150)
25         self.setWindowTitle('Tooltips')
26 
27         self.setWindowIcon(QIcon())
28         self.center()
29         self.show()
30 
31     def closeEvent(self, event):
32         res = QMessageBox.question(self, 'info', '你要確定退出嗎?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
33         if res == QMessageBox.Yes:
34             event.accept()
35         else:
36             event.ignore()
37 
38     def center(self):
39         qr = self.frameGeometry()
40         cp = QDesktopWidget().availableGeometry().center()
41         qr.moveCenter(cp)
42         self.move(qr.topLeft())
43 
44 
45 def main():
46     app = QApplication(sys.argv)
47     ex=winForm()
48     sys.exit(app.exec_())
49 
50 
51 if __name__ == '__main__':
52     main()

 

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM