【PyQt】PyQt學習(二)模塊介紹+QObject學習

簡介

PyQt API 是一組包含大量類和函數(shù)的模塊。核心模塊如下:

  • QtGui:包含了窗口系統(tǒng)、事件處理(QEvent)、2D 圖像(QImage)、基本繪畫、字體(QFont)和文字類;
  • QtCore:包含所有的核心非 GUI 類;
  • QtWidgets:包含一系列創(chuàng)建桌面應用的 UI 元素,所有的 GUI 元素都在這個模塊中;
  • QtMultimedia:包含了處理多媒體的內容和調用攝像頭 API 的類,所有的低級多媒體類倒在這個模塊;
  • QtNetwork:網(wǎng)絡編程類;
  • QtOpenGL:OpenGL 支持類;
  • QtPositioning:包含了定位的類,可以使用衛(wèi)星、WiFi 甚至文本;
  • QtWebEngine:Qt 集成了 Web 瀏覽器;
  • QtSql:包含整個 SQL 處理的類;
  • QtXml:包含了處理 xml 的類,提供了 SAX 和 DOM API 的工具;
  • QtSvg:包含顯示 SVG 文件內容的類;

PyQt 庫的核心就是 QtGui、QtCore 和 QtWidgets 三個模塊,他們基本包含了 GUI 創(chuàng)建和邏輯處理所需的全部類,也是我們學習 PyQt 的核心。

PyQt5不兼容 PyQt4。PyQt5有一些巨大的改進:

  • 重新組合模塊,一些模塊已經(jīng)被廢棄(QtScript),有些被分為兩個子模塊(QtGui, QtWebKit);
  • 添加了新的模塊,比如 QtBluetooth, QtPositioning,和 Enginio;
  • 廢棄了 SINGAL()和 SLOT()的調用方式,使用了新的信號和 xx 處理方式;
  • 不再支持被標記為廢棄的或不建議使用的 API;

信號與槽機制

在正式介紹 PyQt 的各個控件之前,先介紹一下 Qt 框架的信號與槽機制。信號與槽(Signal/Slots)是 Qt 編程的基礎,也是 Qt 框架的一大特色。因為有了信號與槽機制的存在,在 Qt 中處理界面組件的交互操作時變得比較直觀和簡單。

信號(Signal)就是在特定情況下被發(fā)射(emit)的一種告示,例如 PushButton 按鈕最常見的信號就是鼠標點擊的時候發(fā)射的 clicked () 信號;一個 ComboBox 最常見的信號是選擇的項目發(fā)生變化的時候發(fā)射的 CurrentIndexChanged () 信號。GUI 程序設計的主要內容就是對界面上各個組件發(fā)射的特定信號進行響應,只需要知道哪一個控件在什么情況下發(fā)射了哪些信號,然后合理地去響應這些信號即可。

槽(Slot)就是對信號響應的函數(shù)。槽的本質是一個函數(shù),他可以直接被調用,這個和普通的函數(shù)沒有什么不同,槽函數(shù)與普通函數(shù)不同的一點是:槽函數(shù)可以與一個信號關聯(lián),當信號被發(fā)射的時候,關聯(lián)的槽函數(shù)會自動被執(zhí)行。Qt 的類一般都有一些內建(build-in)的槽函數(shù),例如 QWidget 有一個槽函數(shù) close(),其功能是關閉窗口,如果一個信號與之關聯(lián),當信號發(fā)射的時候就會關閉窗口。

信號與槽是一個非常復雜的機制,其底層就是 Qt 的事件機制,我將會在后面的博文中詳細說明。

QObject

當我們打開 Qt-Designer 的時候,可以看到最頂層的 QObject 屬性設置,具體如下圖所示:

Qt-Designer

QObject 是所有對象的父對象,它定義了一個 QObject 是 Qt 對象模型的核心。這個模型的中心特性是一個非常強大的對象通信機制,稱為信號和插槽。QObject 以對象樹的形式組織自身。當創(chuàng)建 QObject 并將另一個對象作為父對象時,該對象將自動將其自身添加到父對象的子對象列表中,父對象取得子對象的所有權。QObject 在 Qt 中還提供了基本的定時器支持,高級定時器功能由 QTimer 進行實現(xiàn)。

重要方法和屬性

設置控件的屬性

  • setObjectName():設置控件的唯一標識符;
  • objectName():獲取控件的名稱;
  • setProperty():設置控件的一個屬性;
  • property():獲取控件的屬性;
  • dynamicPropertyNames():動態(tài)的獲取使用 setProperty() 方法設置的屬性名稱。

設置父子關系

  • setParent():設置父對象。
  • parent():獲取父對象。
  • children():獲取所有的子對象。
  • findchildren():查找改對象的所有子對象(可以指定查找的對象類型,還可以指定是查找直接還是所有子對象)

進行類型判斷:

  • isWidgetType():判定是否是一個控件類型。
  • inherits():判定一個對象時候直接/間接繼承了指定的父類。

對象刪除:

  • deleteLater():向主消息隊列發(fā)送一個事件,下一次收到該事件的時候再進行清除。(刪除對象的時候會刪除任何父子關系)

定時器

  • startTimer():開啟一個定時器。
  • killTimer():刪除定時器。
  • timerEvent():定時器執(zhí)行的事件。

信號

  1. ObjectNameChanged:對象名稱發(fā)生改變的時候發(fā)出此信號。
  2. destory:對象銷毀的時候發(fā)出此信號。
  3. blockSignals:對象臨時屏蔽一個信號。

應用場景

  1. 用于 QSS 的 ID 選擇器,方便統(tǒng)一設置格式;
  2. 控件內存管理
    1. 所有得到對象都可以在一個父對象中進行自我組織;
    2. 內存管理變得容易,當一個父對象被銷毀,它的所有子對象也都被銷毀了;
  3. 一個空間是否能夠作為頂級窗口存在依賴于它是否有父控件,如果沒有父控件那么它將作為頂級窗口存在;
  4. 簡單定時器實現(xiàn);
  5. 控件類型判斷;

示例

下面的示例創(chuàng)建了三個 QObject 對象,并進行了如下演示:

  1. 設置 objectname 屬性;
  2. 設置父子關系;
  3. 設置 property 屬性;
# 定義三個QObject對象  
widget1 = QObject()  
widget2 = QObject()  
widget3 = QObject()  
  
# 設置三個控件的objectname并打印  
widget1.setObjectName("widget1")  
widget2.setObjectName("widget2")  
widget3.setObjectName("widget3")  
  
print(widget1.objectName()) -> widget1  
print(widget2.objectName()) -> widget2    
print(widget3.objectName()) -> widget3    
  
  
# 設置父子關系并打印  
# 只能顯示直接子對象,不能顯示間接子對象
widget3.setParent(widget2)  
widget2.setParent(widget1)  
  
print(widget1.children()) -> [<PyQt5.QtCore.QObject object at 0x0000026BC638D5E0>]  
print(widget2.children()) -> [<PyQt5.QtCore.QObject object at 0x0000026BC638D790>]  
print(widget1.children()[0].objectName()) -> widget2  
print(widget2.children()[0].objectName()) -> widget3

# 設置property并打印
# 如果沒有設置相應屬性則返回None
widget1.setProperty("value", 1)
widget2.setProperty("value", 2)  
widget3.setProperty("value", 3)  
  
print(widget1.property('value')) ->  1  
print(widget2.property('value')) ->  2  
print(widget3.property('value')) ->  3  
print(widget1.property('path')) ->  None

下面的示例演示了 QObject 提供的定時器功能,一個 QObject 對象設置定時器,當定時器設定時間截止之后會自動調用對象的timerEvent方法(事件機制的一部分),示例源碼如下:

# 定時器示例  
class MainWindow(QMainWindow):  
    def __init__(self):  
        super(MainWindow, self).__init__()  
        # 計數(shù)器,看timerEvent的調用次數(shù)
        self.counter = 0  
        # 設置一個1000毫秒的定時器
        self.startTimer(1000, Qt.TimerType.PreciseTimer)  

    # 重寫timerEvent方法
    def timerEvent(self, event) -> None:  
        self.counter += 1  
        print(f"timerEvent第{self.counter}次調用")  
        if self.counter == 5:  
            print("調用結束,關閉窗口")
            self.close()
  
  
if __name__ == '__main__':  
    import sys  
  
    app = QApplication(sys.argv)  
    win = MainWindow()  
    win.show()    
    sys.exit(app.exec())

運行結果如下:

運行結果

往期回顧

  1. 【PyQt】PyQt學習(一)

文中難免會出現(xiàn)一些描述不當之處(盡管我已反復檢查多次),歡迎在留言區(qū)指正,相關的知識點也可進行分享,希望大家都能有所收獲!!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容