中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

徐州哪有做網(wǎng)站的熱門seo推廣排名穩(wěn)定

徐州哪有做網(wǎng)站的,熱門seo推廣排名穩(wěn)定,藍(lán)色創(chuàng)新業(yè)務(wù)功能展示網(wǎng)頁(yè)模板,淘客網(wǎng)站做百度推廣【QT八股文】系列之篇章2 | QT的信號(hào)與槽機(jī)制及通訊流程 前言2. 信號(hào)與槽信號(hào)與槽機(jī)制介紹/本質(zhì)/原理,什么是Qt信號(hào)與槽機(jī)制?如何在Qt中使用?信號(hào)與槽機(jī)制原理,解析流程Qt信號(hào)槽的調(diào)用流程信號(hào)與槽機(jī)制的優(yōu)缺點(diǎn)信號(hào)與槽機(jī)制需要注…

【QT八股文】系列之篇章2 | QT的信號(hào)與槽機(jī)制及通訊流程

  • 前言
  • 2. 信號(hào)與槽
    • 信號(hào)與槽機(jī)制介紹/本質(zhì)/原理,什么是Qt信號(hào)與槽機(jī)制?如何在Qt中使用?
    • 信號(hào)與槽機(jī)制原理,解析流程
    • Qt信號(hào)槽的調(diào)用流程
    • 信號(hào)與槽機(jī)制的優(yōu)缺點(diǎn)
    • 信號(hào)與槽機(jī)制需要注意的問(wèn)題
    • 信號(hào)的注意點(diǎn)
    • 信號(hào)與槽與回調(diào)函數(shù)區(qū)別
    • Qt信號(hào)與槽的多種用法
    • PYQT5 connect 函數(shù)
    • Qt connect 函數(shù)的連接方式
    • PYQT5信號(hào)槽的鏈接方式
    • 信號(hào)槽同步與異步/多線程下,信號(hào)槽分別在什么線程中執(zhí)行,如何控制——`Qt connect 函數(shù)的連接方式`來(lái)控制
  • 3. 通訊流程
    • QT的TCP通訊流程
    • QT的UDP通訊流程
  • 下一章筆記
  • 說(shuō)明

前言

第一篇章主要是基礎(chǔ)定義及QT中重要的事件機(jī)制
筆記鏈接:【QT八股文】系列之篇章1 | QT的基礎(chǔ)知識(shí)及事件/機(jī)制

這里我們?cè)诹私饬薗T的大概后,我們將來(lái)了解QT中的核心機(jī)制:信號(hào)與槽
因?yàn)榻榻B到信號(hào)與槽,所以筆者我會(huì)講通訊流程提前在前面來(lái)介紹

原創(chuàng)文章,未經(jīng)同意請(qǐng)勿轉(zhuǎn)載

2. 信號(hào)與槽

信號(hào)與槽機(jī)制介紹/本質(zhì)/原理,什么是Qt信號(hào)與槽機(jī)制?如何在Qt中使用?

在這里插入圖片描述

  • 定義
    Qt信號(hào)與槽機(jī)制是一種基于事件機(jī)制的編程模型,用于對(duì)象之間的通信。信號(hào)是由發(fā)送方對(duì)象發(fā)射的事件,而槽是接收方對(duì)象用于處理這些事件的函數(shù)。在Qt中,我們可以使用QObject類中的信號(hào)和槽機(jī)制來(lái)實(shí)現(xiàn)對(duì)象間的通信。通過(guò)定義信號(hào)和槽函數(shù),在信號(hào)發(fā)射時(shí),會(huì)自動(dòng)調(diào)用對(duì)應(yīng)的槽函數(shù)進(jìn)行處理。

  • 使用
    PyQt的內(nèi)置信號(hào)是自動(dòng)定義的,使用PyQt5.QtCore.pyqtSignal函數(shù)可以為QObject對(duì)象創(chuàng)建一個(gè)信號(hào),使用pyqtSignal函數(shù)可以把信號(hào)定義為類的屬性。使用connect函數(shù)可以將信號(hào)綁定到槽函數(shù)上,使用disconnect函數(shù)可以解除信號(hào)與槽函數(shù)的綁定,使用emit函數(shù)可以發(fā)射信號(hào)。

  • 本質(zhì)(就是回調(diào)函數(shù))
    在事件的處理方面,信號(hào)槽相比回調(diào)函數(shù),具有類型安全、松耦合、任意參數(shù)的優(yōu)勢(shì),但執(zhí)行效率會(huì)有一點(diǎn)損失。信號(hào)相當(dāng)于傳遞參數(shù)(指實(shí)參,用于傳遞值/動(dòng)作變化),槽函數(shù)像用于傳遞函數(shù)體(形參/函數(shù)體,用于接收值/根據(jù)動(dòng)作變化來(lái)做出對(duì)應(yīng)操作。)

  • 原理

    1. Qt 中的信號(hào)與槽機(jī)制是一種事件處理機(jī)制,它允許程序在接收到特定事件時(shí)執(zhí)行特定的操作。在 Qt 中,信號(hào)與槽機(jī)制被廣泛應(yīng)用于組件之間的通信和事件處理。
    2. 具體來(lái)說(shuō),Qt 中的信號(hào)與槽機(jī)制是基于 QObject 類的。任何一個(gè) QObject 對(duì)象都可以作為一個(gè)信號(hào)源,它可以通過(guò) emit() 方法發(fā)出信號(hào)。同時(shí),任何一個(gè) QObject 對(duì)象都可以作為一個(gè)槽,它可以接受并處理來(lái)自信號(hào)源的信號(hào)。當(dāng)一個(gè)信號(hào)源發(fā)出信號(hào)時(shí),它會(huì)連接到相應(yīng)的槽。這些槽可以是與信號(hào)源同一個(gè)對(duì)象,也可以是其他 QObject 對(duì)象。當(dāng)信號(hào)源接收到信號(hào)時(shí),它會(huì)將信號(hào)傳遞給所有已經(jīng)連接到該槽的對(duì)象。這些對(duì)象會(huì)在接收到信號(hào)時(shí)執(zhí)行相應(yīng)的操作。

信號(hào)與槽機(jī)制原理,解析流程

在這里插入圖片描述

  • 原理

    1. Qt 中的信號(hào)與槽機(jī)制是一種事件處理機(jī)制,它允許程序在接收到特定事件時(shí)執(zhí)行特定的操作。在 Qt 中,信號(hào)與槽機(jī)制被廣泛應(yīng)用于組件之間的通信和事件處理。
    2. 具體來(lái)說(shuō),Qt 中的信號(hào)與槽機(jī)制是基于 QObject 類的。任何一個(gè) QObject 對(duì)象都可以作為一個(gè)信號(hào)源,它可以通過(guò) emit() 方法發(fā)出信號(hào)。同時(shí),任何一個(gè) QObject 對(duì)象都可以作為一個(gè)槽,它可以接受并處理來(lái)自信號(hào)源的信號(hào)。當(dāng)一個(gè)信號(hào)源發(fā)出信號(hào)時(shí),它會(huì)連接到相應(yīng)的槽。這些槽可以是與信號(hào)源同一個(gè)對(duì)象,也可以是其他 QObject 對(duì)象。當(dāng)信號(hào)源接收到信號(hào)時(shí),它會(huì)將信號(hào)傳遞給所有已經(jīng)連接到該槽的對(duì)象。這些對(duì)象會(huì)在接收到信號(hào)時(shí)執(zhí)行相應(yīng)的操作。
  • 解析流程

    1. moc查找頭文件中的signals,slots,標(biāo)記出信號(hào)和槽。
    2. 將信號(hào)槽信息存儲(chǔ)到類靜態(tài)變量staticMetaObject中,并且按聲明順序進(jìn)行存放,建立索引。
    3. 當(dāng)發(fā)現(xiàn)有connect連接時(shí),將信號(hào)槽的索引信息放到一個(gè)map中,彼此配對(duì)。
    4. 當(dāng)調(diào)用emit時(shí),調(diào)用信號(hào)函數(shù),并且傳遞發(fā)送信號(hào)的對(duì)象指針,元對(duì)象指針,信號(hào)索引,參數(shù)列表到active函數(shù)
    5. 通過(guò)active函數(shù)找到在map中找到所有與信號(hào)對(duì)應(yīng)的槽索引
    6. 根據(jù)槽索引找到槽函數(shù),執(zhí)行槽函數(shù)。

Qt信號(hào)槽的調(diào)用流程

注意:信號(hào)槽的實(shí)現(xiàn):元對(duì)象編譯器MOC,MOC的本質(zhì)就是反射器

  • MOC(元對(duì)象編譯器)查找頭文件中的signal與slots,標(biāo)記出信號(hào)槽。將信號(hào)槽信息儲(chǔ)存到類靜態(tài)變量staticMetaObject中,并按照聲明的順序進(jìn)行存放,建立索引。
  • connect鏈接,將信號(hào)槽的索引信息放到一個(gè)雙向鏈表中,彼此配對(duì)。
  • emit被調(diào)用,調(diào)用信號(hào)函數(shù),且傳遞發(fā)送信號(hào)的對(duì)象指針,元對(duì)象指針,信號(hào)索引,參數(shù)列表到active函數(shù)。
  • active函數(shù)在雙向鏈表中找到所有與信號(hào)對(duì)應(yīng)的槽索引,根據(jù)槽索引找到槽函數(shù),執(zhí)行槽函數(shù)。

信號(hào)與槽機(jī)制的優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn)
    • 類型安全。需要關(guān)聯(lián)的信號(hào)槽的簽名必須是等同的。即信號(hào)的參數(shù)類型和參數(shù)個(gè)數(shù)同接受該信號(hào)的槽的參數(shù)類型和參數(shù)個(gè)數(shù)相同。若信號(hào)和槽簽名不一致,編譯器會(huì)報(bào)錯(cuò)。信號(hào)的參數(shù)可以多于槽,槽參數(shù)數(shù)量不能大于于信號(hào)。

      💡 槽函數(shù)的參數(shù)是否可以比信號(hào)的參數(shù)多?
      也可以。唯一的情況就是槽函數(shù)參數(shù)帶有默認(rèn)參數(shù),除去默認(rèn)參數(shù)外,槽函數(shù)的參數(shù)必須小于等于信號(hào)的參數(shù)。

    • 松散耦合。QT的信號(hào)槽的建立和解除綁定十分自由。信號(hào)和槽機(jī)制減弱了Qt對(duì)象的耦合度。激發(fā)信號(hào)的Qt對(duì)象無(wú)需知道是那個(gè)對(duì)象的那個(gè)信號(hào)槽接收它發(fā)出的信號(hào),它只需在適當(dāng)?shù)臅r(shí)間發(fā)送適當(dāng)?shù)男盘?hào)即可,而不需要關(guān)心是否被接受和那個(gè)對(duì)象接受了。Qt就保證了適當(dāng)?shù)牟鄣玫搅苏{(diào)用,即使關(guān)聯(lián)的對(duì)象在運(yùn)行時(shí)被刪除。程序也不會(huì)奔潰。

      💡 信號(hào)重載了,如何確定連接哪個(gè)信號(hào)?
      采用函數(shù)指針確定連接哪個(gè)信號(hào)。

    • 靈活性。一個(gè)信號(hào)可以關(guān)聯(lián)多個(gè)槽,或多個(gè)信號(hào)關(guān)聯(lián)同一個(gè)槽。

  • 不足
    • 速度較慢。與回調(diào)函數(shù)相比,信號(hào)和槽機(jī)制運(yùn)行速度比直接調(diào)用非虛函數(shù)慢10倍。信號(hào)槽同真正的回調(diào)函數(shù)比起來(lái)時(shí)間的耗損還是很大的,所以在嵌入式實(shí)時(shí)系統(tǒng)中應(yīng)當(dāng)慎用。
      • 原因:
        • ①需要定位接收信號(hào)的對(duì)象。
        • ②安全地遍歷所有關(guān)聯(lián)槽。
        • ③編組、解組傳遞參數(shù)。
        • ④多線程的時(shí)候,信號(hào)需要排隊(duì)等待。(然而,與創(chuàng)建對(duì)象的new操作及刪除對(duì)象的delete操作相比,信號(hào)和槽的運(yùn)行代價(jià)只是他們很少的一部分。信號(hào)和槽機(jī)制導(dǎo)致的這點(diǎn)性能損耗,對(duì)實(shí)時(shí)應(yīng)用程序是可以忽略的。
    • 不能出現(xiàn)宏定義。信號(hào)槽的參數(shù)限定很多例如不能攜帶模板類參數(shù),不能出現(xiàn)宏定義等等。

信號(hào)與槽機(jī)制需要注意的問(wèn)題

信號(hào)與槽機(jī)制是比較靈活的,但有些局限性我們必須了解,這樣在實(shí)際的使用過(guò)程中才能夠做到有的放矢,避免產(chǎn)生一些錯(cuò)誤。下面就介紹一下這方面的情況。

  • 信號(hào)與槽的效率是非常高的,但是同真正的回調(diào)函數(shù)比較起來(lái),由于增加了靈活 性,因此在速度上還是有所損失,當(dāng)然這種損失相對(duì)來(lái)說(shuō)是比較小的,通過(guò)在一臺(tái) i586- 133 的機(jī)器上測(cè)試是 10 微秒(運(yùn)行 Linux),可見這種機(jī)制所提供的簡(jiǎn)潔性、靈活性還是 值得的。但如果我們要追求高效率的話,比如在實(shí)時(shí)系統(tǒng)中就要盡可能的少用這種機(jī)制。
  • 信號(hào)與槽機(jī)制與普通函數(shù)的調(diào)用一樣,如果使用不當(dāng)?shù)脑?#xff0c;在程序執(zhí)行時(shí)也有可能 產(chǎn)生死循環(huán)。因此,在定義槽函數(shù)時(shí)一定要注意避免間接形成無(wú)限循環(huán),即在槽中再次發(fā)射 所接收到的同樣信號(hào)。
  • 如果一個(gè)信號(hào)與多個(gè)槽相關(guān)聯(lián)的話,那么,當(dāng)這個(gè)信號(hào)被發(fā)射時(shí),與之相關(guān)的槽被 激活的順序?qū)⑹请S機(jī)的,并且我們不能指定該順序。
  • 宏定義不能用在 signal 和 slot 的參數(shù)中。
  • 構(gòu)造函數(shù)不能用在 signals 或者 slots 聲明區(qū)域內(nèi)。
  • 函數(shù)指針不能作為信號(hào)或槽的參數(shù)。
  • 信號(hào)與槽不能有缺省參數(shù)。
  • 信號(hào)與槽也不能攜帶模板類參數(shù)。

信號(hào)的注意點(diǎn)

  • 所有的信號(hào)聲明都是公有的,所以Qt規(guī)定不能在signals前面加public,private, protected。
  • 所有的信號(hào)都沒有返回值,所以返回值都用void。
  • 所有的信號(hào)都不需要定義。
  • 必須直接或間接繼承自QOBject類,并且開頭私有聲明包含Q_OBJECT。
  • 在同一個(gè)線程中,當(dāng)一個(gè)信號(hào)被emit發(fā)出時(shí),會(huì)立即執(zhí)行其槽函數(shù),等槽函數(shù)執(zhí)行完畢后,才會(huì)執(zhí)行emit后面的代碼,如果一個(gè)信號(hào)鏈接了多個(gè)槽,那么會(huì)等所有的槽函數(shù)執(zhí)行完畢后才執(zhí)行后面的代碼,槽函數(shù)的執(zhí)行順序是按照它們鏈接時(shí)的順序執(zhí)行的。不同線程中(即跨線程時(shí)),槽函數(shù)的執(zhí)行順序是隨機(jī)的。
  • 在鏈接信號(hào)和槽時(shí),可以設(shè)置鏈接方式為:在發(fā)出信號(hào)后,不需要等待槽函數(shù)執(zhí)行完,而是直接執(zhí)行后面的代碼,是通過(guò)connect的第5個(gè)參數(shù)。
  • 信號(hào)與槽機(jī)制要求信號(hào)和槽的參數(shù)一致,所謂一致,是參數(shù)類型一致。如果不一致,允許的情況是,信號(hào)的參數(shù)可以比槽函數(shù)的參數(shù)多,即便如此,槽函數(shù)存在的那些參數(shù)的順序也必須和信號(hào)的前面幾個(gè)一致起來(lái)。這是因?yàn)?#xff0c;你可以在槽函數(shù)中選擇忽略信號(hào)傳來(lái)的數(shù)據(jù)(也就是槽函數(shù)的參數(shù)比信號(hào)的少),但是不能說(shuō)信號(hào)根本沒有這個(gè)數(shù)據(jù),你就要在槽函數(shù)中使用(就是槽函數(shù)的參數(shù)比信號(hào)的多,這是不允許的)。

信號(hào)與槽與回調(diào)函數(shù)區(qū)別

  1. 鏈接的不同

    • 回調(diào)函數(shù)使用函數(shù)指針來(lái)實(shí)現(xiàn)的,如果多個(gè)類都關(guān)注一個(gè)類的動(dòng)態(tài)變化,這樣就會(huì)需要寫出一個(gè)比較長(zhǎng)的列表來(lái)管理這些類之間的關(guān)系。稍微在編碼方面不那么靈活,稍顯冗余。
    • QT使用信號(hào)與槽來(lái)解決這個(gè)連接問(wèn)題,這種方式比較清晰簡(jiǎn)單一些,一個(gè)類只需要清楚自己有幾個(gè)槽函數(shù)有幾個(gè)信號(hào),然后將信號(hào)與槽進(jìn)行連接,QT會(huì)自己處理函數(shù)的調(diào)用關(guān)系。這樣在軟件設(shè)計(jì)角度更加的清晰,靈活,不容易出錯(cuò)。
  2. 執(zhí)行順序/時(shí)間的不同

    • Qt 信號(hào)與槽機(jī)制中的槽函數(shù)在接收到信號(hào)時(shí)會(huì)自動(dòng)執(zhí)行,而回調(diào)函數(shù)通常是在調(diào)用時(shí)立即執(zhí)行。Qt 信號(hào)與槽機(jī)制可以在信號(hào)觸發(fā)時(shí)立即執(zhí)行槽函數(shù),也可以延遲執(zhí)行槽函數(shù),而回調(diào)函數(shù)通常是立即執(zhí)行的。
    • 信號(hào)與槽機(jī)制中的信號(hào)與槽之間的執(zhí)行順序是不確定的,可以是任意順序,也可以是逆序;而回調(diào)函數(shù)機(jī)制中的回調(diào)函數(shù)之間的執(zhí)行順序通常是確定的,按照函數(shù)聲明的順序執(zhí)行。
  3. 對(duì)象綁定

    信號(hào)與槽機(jī)制可以實(shí)現(xiàn)對(duì)象之間的動(dòng)態(tài)綁定,可以在運(yùn)行時(shí)動(dòng)態(tài)地綁定信號(hào)與槽;而回調(diào)函數(shù)機(jī)制通常只能在程序啟動(dòng)時(shí)進(jìn)行綁定。

  4. 主要用途不同

    信號(hào)和槽機(jī)制是用于在程序運(yùn)行時(shí)傳遞數(shù)據(jù)和事件的機(jī)制,而回調(diào)函數(shù)則通常被用于函數(shù)或方法的調(diào)用。因此,信號(hào)和槽機(jī)制可以用于模塊之間的通信和交互,而回調(diào)函數(shù)則通常用于函數(shù)或方法的調(diào)用。

Qt信號(hào)與槽的多種用法

  • 一個(gè)信號(hào)可以和多個(gè)槽相連
    這時(shí)槽的執(zhí)行順序和在不在同一個(gè)線程上有關(guān),同一線程,槽的執(zhí)行順序和聲明順序有關(guān),跨線程時(shí),執(zhí)行順序是不確定的。
  • 多個(gè)信號(hào)可以連接到一個(gè)槽
    只要任意一個(gè)信號(hào)發(fā)出,這個(gè)槽就會(huì)被調(diào)用。
  • 一個(gè)信號(hào)可以連接到另外的一個(gè)信號(hào)
    當(dāng)?shù)谝粋€(gè)信號(hào)發(fā)出時(shí),第二個(gè)信號(hào)被發(fā)出。除此之外,這種信號(hào)-信號(hào)的形式和信號(hào)-槽的形式?jīng)]有什么區(qū)別。
  • 槽可以被取消鏈接
    這種情況并不經(jīng)常出現(xiàn),因?yàn)楫?dāng)一個(gè)對(duì)象delete之后,Qt自動(dòng)取消所有連接到這個(gè)對(duì)象上面的槽。想主動(dòng)取消連接就用disconnect()函數(shù)中添加任何實(shí)現(xiàn)。
  • 可以使用Lambda 表達(dá)式
    在使用 Qt 5 的時(shí)候,能夠支持 Qt 5 的編譯器都是支持 Lambda 表達(dá)式的。

PYQT5 connect 函數(shù)

注:在Qt中第五個(gè)參數(shù)用于指定信號(hào)與槽的匹配規(guī)則。而PYQT5是第四個(gè)參數(shù)
在 PyQt5 中,connect 函數(shù)【connect: PyQt5.QtWidgets.QSignalMapper()】是一個(gè)用于連接信號(hào)與槽的函數(shù)。它通常被用于將對(duì)象的信號(hào)與槽函數(shù)進(jìn)行連接。

列子:mapper = Qt.QSignalMapper() mapper.setMapping(button, button.clicked.connect(mapper.setCurrentIndex))

第一個(gè)參數(shù)是一個(gè)可選的參數(shù),用于指定要連接的信號(hào)源。如果該參數(shù)為 None,則表示連接的是系統(tǒng)提供的信號(hào)。如果該參數(shù)不為 None,則表示要連接自定義信號(hào)。

第二個(gè)參數(shù)是一個(gè)可選的參數(shù),用于指定要連接的槽函數(shù)。如果該參數(shù)為 None,則表示連接的是默認(rèn)槽函數(shù)。如果該參數(shù)不為 None,則表示要連接指定的槽函數(shù)。

第三個(gè)參數(shù)是一個(gè)字符串,用于指定信號(hào)與槽之間的映射關(guān)系。該字符串通常由信號(hào)名稱和槽函數(shù)名稱組成。例如,“clicked” 表示將按鈕的點(diǎn)擊信號(hào)與按鈕的 clicked 槽函數(shù)進(jìn)行連接。

第四個(gè)參數(shù)是一個(gè) PyQt5 中的 QSignalMapper 對(duì)象,用于指定信號(hào)與槽的匹配規(guī)則。該對(duì)象應(yīng)該實(shí)現(xiàn) QSignalMapper 類中的方法,例如 setMapping() 和 currentIndex() 等。

第五個(gè)參數(shù)是一個(gè)可選的參數(shù),用于指定信號(hào)中斷連接的函數(shù)。如果連接的信號(hào)源對(duì)象被刪除或重新分配,則連接將被中斷。默認(rèn)情況下,連接不會(huì)自動(dòng)中斷。

Qt connect 函數(shù)的連接方式

  1. 自動(dòng)連接Qt::AutoConnection
    默認(rèn)值,使用這個(gè)值則連接類型會(huì)在信號(hào)發(fā)送時(shí)決定。如果接收者和發(fā)送者在同一個(gè)線程,則自動(dòng)使用
    多線程時(shí)為隊(duì)列連接函數(shù),單線程時(shí)為直接連接函數(shù)。

  2. 直接連接Qt::DirectConnection
    == 如果接收者和發(fā)送者不在一個(gè)線程,則自動(dòng)使用Qt::QueuedConnection類型。==
    Qt::DirectConnection:槽函數(shù)會(huì)在信號(hào)發(fā)送的時(shí)候直接被調(diào)用,槽函數(shù)和信號(hào)發(fā)送者在同一線程。效果看上去就像是直接在信號(hào)發(fā)送位置調(diào)用了槽函數(shù),效果上看起來(lái)像函數(shù)調(diào)用,同步執(zhí)行。
    emit語(yǔ)句后面的代碼將在與信號(hào)關(guān)聯(lián)的所有槽函數(shù)執(zhí)行完畢后才被執(zhí)行。
    信號(hào)/槽在信號(hào)發(fā)出者所在的線程中執(zhí)行

  3. 隊(duì)列連接Qt::QueuedConnection
    信號(hào)發(fā)出后,信號(hào)會(huì)暫時(shí)被放到一個(gè)消息隊(duì)列中,需等到接收對(duì)象所屬線程的事件循環(huán)取得控制權(quán)時(shí)才取得該信號(hào),然后執(zhí)行和信號(hào)關(guān)聯(lián)的槽函數(shù),這種方式既可以在同一線程內(nèi)傳遞消息也可以跨線程操作。
    emit語(yǔ)句后的代碼將在發(fā)出信號(hào)后立即被執(zhí)行,無(wú)需等待槽函數(shù)執(zhí)行完畢
    信號(hào)在信號(hào)發(fā)出者所在的線程中執(zhí)行,槽函數(shù)在信號(hào)接收者所在的線程中執(zhí)行

  4. Qt::BlockingQueuedConnection
    槽函數(shù)的調(diào)用時(shí)機(jī)與Qt::QueuedConnection一致,不過(guò)發(fā)送完信號(hào)后發(fā)送者所在線程會(huì)阻塞,直到槽函數(shù)運(yùn)行完。而且接收者和發(fā)送者絕對(duì)不能在一個(gè)線程,否則程序會(huì)死鎖。在多線程間需要同步的場(chǎng)合可能需要這個(gè)。

  5. Qt::UniqueConnection:這個(gè)flag可以通過(guò)按位或(|)與以上四個(gè)結(jié)合在一起使用。當(dāng)這個(gè)flag設(shè)置時(shí),當(dāng)某個(gè)信號(hào)和槽已經(jīng)連接時(shí),再進(jìn)行重復(fù)的連接就會(huì)失敗。也就是為了避免重復(fù)連接。

PYQT5信號(hào)槽的鏈接方式

在 PyQt5 中,信號(hào)與槽的連接方式有兩種:1. 使用 connect() 函數(shù);2. 裝飾器@pyqtSlot() 。

@pyqtSlot()優(yōu)點(diǎn)是方式書寫比較簡(jiǎn)潔。缺點(diǎn)是但函數(shù)名稱不能自由定義,在想自定義參數(shù)時(shí)沒有詳細(xì)說(shuō)明。

connect()方式優(yōu)點(diǎn)是理解和學(xué)習(xí)起來(lái)比較簡(jiǎn)單,而且函數(shù)名稱可以自由定義。缺點(diǎn)是但如果信號(hào)比較多時(shí),書寫就比較混亂。

使用信號(hào)處理器的優(yōu)點(diǎn)是可以在信號(hào)發(fā)生時(shí)執(zhí)行復(fù)雜的操作,而缺點(diǎn)是連接信號(hào)處理器需要花費(fèi)更多的內(nèi)存和時(shí)間,并且連接信號(hào)處理器需要手動(dòng)管理連接關(guān)系。因此,使用信號(hào)處理器僅適用于需要執(zhí)行復(fù)雜操作的情況。

  1. 裝飾器方法:@pyqtSlot()裝飾器

    @pyqtSlot():修飾關(guān)鍵詞,表明下面是完整的信號(hào)槽函數(shù)

    # 需要引入 pyqtSlot 庫(kù)函數(shù)
    from PyQt5.QtCore import pyqtSlot@pyqtSlot() #裝飾器,此函數(shù)沒有connect直接通過(guò)裝飾器初始化連接槽函數(shù)
    def on_pushButton_clicked(self)print("我點(diǎn)擊了")
    

    在@pyqtSlot()方式里,函數(shù)名稱有特殊要求,如下:

    def  on_(控件對(duì)象名)_信號(hào)名(self,內(nèi)置參數(shù))

    @pyqtSlot()控制控件的多信號(hào)

    @pyqtSlot()
    def on_lineEdit_returnPressed(self):print('觸發(fā)了信號(hào) returnPressed')def on_lineEdit_textChanged(self):print('觸發(fā)了信號(hào) textChanged')
    

    注意:一個(gè)控件同時(shí)要寫多個(gè)信號(hào)與槽函數(shù)時(shí),只需要寫一遍@pyqtSlot()關(guān)鍵詞,中間可以有其他函數(shù)隔開。一定是一個(gè)類里面的,一個(gè)控件只寫一遍@pyqtSlot(),不是所有控件信號(hào)只寫一次@pyqtSlot(),有多少控件的信號(hào)還是要寫。

  2. connect連接法

    使用 connect() 函數(shù)將信號(hào)與槽函數(shù)連接起來(lái)。connect() 函數(shù)接受兩個(gè)參數(shù):要連接的信號(hào)和要連接的槽函數(shù)。連接成功后,當(dāng)信號(hào)發(fā)生時(shí),槽函數(shù)將被調(diào)用。

    # 在初始化函數(shù)中信號(hào)連接槽函數(shù)
    self.pushButton.clicked.connect(self.test)
    # 槽函數(shù)
    def test(self):print("點(diǎn)擊了一下")
    

    規(guī)則:

    • 語(yǔ)法規(guī)則:self.控件對(duì)象名稱.信號(hào)名稱.connect(self.槽函數(shù)名稱)
    • 有參數(shù)時(shí),槽函數(shù)名稱部分寫成lambda 參數(shù)名: 函數(shù)名(參數(shù)名)
    • 沒有參數(shù)時(shí),槽函數(shù)不用寫括號(hào)()

信號(hào)槽同步與異步/多線程下,信號(hào)槽分別在什么線程中執(zhí)行,如何控制——Qt connect 函數(shù)的連接方式來(lái)控制

可以通過(guò)QT的connect函數(shù)的第五個(gè)參數(shù)(PYQT5中是第四個(gè)參數(shù))來(lái)控制, 信號(hào)槽執(zhí)行時(shí)所在的線程。

通常使用的connect,實(shí)際上最后一個(gè)參數(shù)使用的是Qt::AutoConnection類型:Qt支持6種連接方式,其中3中最主要:

  1. Qt::AutoConnection(自動(dòng)方式)

    信號(hào)槽在信號(hào)發(fā)出者所在的線程中執(zhí)行

    Qt的默認(rèn)連接方式,如果信號(hào)的發(fā)出和接收這個(gè)信號(hào)的對(duì)象同屬一個(gè)線程,那個(gè)工作方式與直連方式相同(會(huì)自動(dòng)使用Qt::DirectConnection類型);否則工作方式與排隊(duì)方式相同(會(huì)自動(dòng)使用Qt::QueuedConnection類型)。

    即多線程時(shí)為隊(duì)列連接函數(shù),單線程時(shí)為直接連接函數(shù)。

  2. Qt::DirectConnection(直連方式)(信號(hào)與槽函數(shù)關(guān)系類似于函數(shù)調(diào)用,同步執(zhí)行)

    當(dāng)信號(hào)發(fā)出后,相應(yīng)的槽函數(shù)將立即被調(diào)用。emit語(yǔ)句后的代碼將在所有槽函數(shù)執(zhí)行完畢后被執(zhí)行。

  3. Qt::QueuedConnection(排隊(duì)方式)(此時(shí)信號(hào)被塞到信號(hào)隊(duì)列里了,信號(hào)與槽函數(shù)關(guān)系類似于消息通信,異步執(zhí)行)

    信號(hào)在信號(hào)發(fā)出者所在的線程中執(zhí)行,槽函數(shù)在信號(hào)接收者所在的線程中執(zhí)行

    當(dāng)信號(hào)發(fā)出后,排隊(duì)到信號(hào)隊(duì)列中,需等到接收對(duì)象所屬線程的事件循環(huán)取得控制權(quán)時(shí)才取得該信號(hào),調(diào)用相應(yīng)的槽函數(shù)。emit語(yǔ)句后的代碼將在發(fā)出信號(hào)后立即被執(zhí)行,無(wú)需等待槽函數(shù)執(zhí)行完畢。

  4. Qt::BlockingQueuedConnection(信號(hào)和槽必須在不同的線程中,否則就產(chǎn)生死鎖)

    這個(gè)是完全同步隊(duì)列只有槽線程執(zhí)行完成才會(huì)返回,否則發(fā)送線程也會(huì)一直等待,相當(dāng)于是不同的線程可以同步起來(lái)執(zhí)行

    與Qt::QueuedConnection相同,除了信號(hào)線程阻塞直到槽返回。如果接收方處于發(fā)送信號(hào)的線程中,則不能使用此連接,否則應(yīng)用程序?qū)⑺梨i。

  5. Qt::UniqueConnection

    與默認(rèn)工作方式相同,只是不能重復(fù)連接相同的信號(hào)和槽,因?yàn)槿绻貜?fù)連接就會(huì)導(dǎo)致一個(gè)信號(hào)發(fā)出,對(duì)應(yīng)槽函數(shù)就會(huì)執(zhí)行多次。

    這個(gè)flag可以通過(guò)按位或(|)與以上四個(gè)結(jié)合在一起使用。當(dāng)這個(gè)flag設(shè)置時(shí),當(dāng)某個(gè)信號(hào)和槽已經(jīng)連接時(shí),再進(jìn)行重復(fù)的連接就會(huì)失敗。也就是為了避免重復(fù)連接。

  6. Qt::AutoCompatConnection

    是為了連接Qt4與Qt3的信號(hào)槽機(jī)制兼容方式,工作方式與Qt::AutoConnection一樣。

3. 通訊流程

QT的TCP通訊流程

在這里插入圖片描述
QT如果要進(jìn)行網(wǎng)絡(luò)編程首先需要在.pro中添加如下代碼:QT += network

  • 服務(wù)端:(QTcpServer)
    ① 創(chuàng)建QTcpServer對(duì)象
    ② 監(jiān)聽list需要的參數(shù)是地址和端口號(hào)
    ③ 當(dāng)有新的客戶端連接成功回發(fā)送newConnect信號(hào)
    ④ 在newConnection信號(hào)槽函數(shù)中,調(diào)用nextPendingConnection函數(shù)獲取新連接QTcpSocket對(duì)象
    ⑤ 連接QTcpSocket對(duì)象的readRead信號(hào)
    ⑥ 在readRead信號(hào)的槽函數(shù)使用read接收數(shù)據(jù)
    ⑦ 調(diào)用write成員函數(shù)發(fā)送數(shù)據(jù)

  • 服務(wù)器端

    1. 創(chuàng)建用于監(jiān)聽的套接字

    2. 給套接字設(shè)置監(jiān)聽

    3. 如果有連接到來(lái), 監(jiān)聽的套接字會(huì)發(fā)出信號(hào)newConnected

    4. 接收連接, 通過(guò)nextPendingConnection()函數(shù), 返回一個(gè)QTcpSocket類型的套接字對(duì)象(用于通信)

    5. 使用用于通信的套接字對(duì)象通信 1>. 發(fā)送數(shù)據(jù): write 2>. 接收數(shù)據(jù): readAll/read

      • 代碼

        Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
        {ui->setupUi(this);tcpServer = new QTcpServer;tcpServer->listen(QHostAddress("192.168.0.111"),1234);connect(tcpServer,SIGNAL(newConnection()),this,SLOT(new_connect()));
        }Widget::~Widget()
        {delete ui;
        }void Widget::new_connect()
        {qDebug("--new connect--");QTcpSocket* tcpSocket = tcpServer->nextPendingConnection();connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(read_data()));socketArr.push_back(tcpSocket);}void Widget::read_data()
        {for(int i=0; i<socketArr.size(); i++){if(socketArr[i]->bytesAvailable()){char buf[256] = {};socketArr[i]->read(buf,sizeof(buf));qDebug("---read:%s---",buf);}}
        }
        
  • 客戶端:(QTcpSocket)
    ① 創(chuàng)建QTcpSocket對(duì)象
    ② 當(dāng)對(duì)象與Server連接成功時(shí)會(huì)發(fā)送connected 信號(hào)
    ③ 調(diào)用成員函數(shù)connectToHost連接服務(wù)器,需要的參數(shù)是地址和端口號(hào)
    ④ connected信號(hào)的槽函數(shù)開啟發(fā)送數(shù)據(jù)
    ⑤ 使用write發(fā)送數(shù)據(jù),read接收數(shù)據(jù)

  • 客戶端:

    1. 創(chuàng)建用于通信的套接字
    2. 連接服務(wù)器: connectToHost
    3. 連接成功與服務(wù)器通信
      1 >. 發(fā)送數(shù)據(jù): write 2>. 接收數(shù)據(jù): readAll/read
    • 代碼

      Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
      {ui->setupUi(this);tcpSocket = new QTcpSocket;connect(tcpSocket,SIGNAL(connected()),this,SLOT(connect_success()));tcpSocket->connectToHost("172.20.10.3",1234);
      }Widget::~Widget()
      {delete ui;
      }void Widget::on_send_clicked()
      {std::string msg = ui->msg->text().toStdString();int ret = tcpSocket->write(msg.c_str(),msg.size()+1);qDebug("--send:%d--",ret);
      }void Widget::connect_success()
      {ui->send->setEnabled(true);
      }
      

QT的UDP通訊流程

UDP(User Datagram Protocol即用戶數(shù)據(jù)報(bào)協(xié)議)是一個(gè)輕量級(jí)的,不可靠的,面向數(shù)據(jù)報(bào)的無(wú)連接協(xié)議。在網(wǎng)絡(luò)質(zhì)量令人十分不滿意的環(huán)境下,UDP協(xié)議數(shù)據(jù)包丟失嚴(yán)重。由于UDP的特性:它不屬于連接型協(xié)議,因而具有資源消耗小,處理速度快的優(yōu)點(diǎn),所以通常音頻、視頻和普通數(shù)據(jù)在傳送時(shí)使用UDP較多,因?yàn)樗鼈兗词古紶杹G失一兩個(gè)數(shù)據(jù)包,也不會(huì)對(duì)接收結(jié)果產(chǎn)生太大影響。所以QQ這種對(duì)保密要求并不太高的聊天程序就是使用的UDP協(xié)議。

在Qt中提供了QUdpSocket 類來(lái)進(jìn)行UDP數(shù)據(jù)報(bào)(datagrams)的發(fā)送和接收。Socket簡(jiǎn)單地說(shuō),就是一個(gè)IP地址加一個(gè)port端口 。

QT下UDP通信服務(wù)器端和客戶端的關(guān)系是對(duì)等的, 做的處理也是一樣的:

  1. 創(chuàng)建套接字對(duì)象 2. 如果需要接收數(shù)據(jù), 必須綁定端口 3. 發(fā)送數(shù)據(jù): writeDatagram 4. 接收數(shù)據(jù): readDatagram

流程:①創(chuàng)建QUdpSocket套接字對(duì)象 ②如果需要接收數(shù)據(jù),必須綁定端口 ③發(fā)送數(shù)據(jù)用writeDatagram,接收數(shù)據(jù)用 readDatagram 。

下一章筆記

下篇筆記鏈接:【QT的多線程以及QThread與QObject】
下篇筆記主要內(nèi)容:QT的多線程以及QThread與QObject

說(shuō)明

碼字不易,可能當(dāng)中存在某些字體錯(cuò)誤(筆者我沒有發(fā)現(xiàn)),如果有錯(cuò)誤,歡迎大家指正。🤗
另外因?yàn)楣P記是之前做的,這里我只把我之前做的搬移和重新排版過(guò)來(lái),如果有知識(shí)上的錯(cuò)誤也歡迎大家指正。

http://m.risenshineclean.com/news/62567.html

相關(guān)文章:

  • 網(wǎng)站修改標(biāo)題有影響嗎站長(zhǎng)工具seo綜合查詢columbu cat
  • 網(wǎng)站制作長(zhǎng)沙長(zhǎng)沙企業(yè)網(wǎng)站設(shè)計(jì)
  • 流量網(wǎng)站應(yīng)該怎么做seo分析seo診斷
  • wdcp網(wǎng)站遷移google play下載安卓
  • 廣州做網(wǎng)站哪家專業(yè)最近三天的新聞大事國(guó)內(nèi)
  • 建設(shè)一個(gè)看電影的網(wǎng)站營(yíng)銷軟文范例大全100
  • 個(gè)人備案網(wǎng)站做網(wǎng)購(gòu)網(wǎng)站購(gòu)買友情鏈接網(wǎng)站
  • html5可以做交互網(wǎng)站嗎成都抖音seo
  • 個(gè)別網(wǎng)站網(wǎng)速慢怎么做電商網(wǎng)站設(shè)計(jì)方案
  • 變態(tài)魔域游戲廣州seo推廣營(yíng)銷
  • 網(wǎng)站建設(shè)網(wǎng)站需要什么軟件有哪些營(yíng)銷網(wǎng)站建設(shè)多少錢
  • 住房和城鄉(xiāng)建設(shè)部網(wǎng)站主頁(yè)免費(fèi)關(guān)鍵詞挖掘工具
  • 代理平臺(tái)注冊(cè)網(wǎng)站建設(shè)腰椎間盤突出壓迫神經(jīng)腿疼怎么治
  • 企業(yè)門戶網(wǎng)站功能列表杭州seo 云優(yōu)化科技
  • b2c旅游網(wǎng)站管理系統(tǒng)seo短視頻入口引流
  • 網(wǎng)站建設(shè)服務(wù)器的選擇方式包括哪些免費(fèi)網(wǎng)絡(luò)推廣平臺(tái)有哪些
  • 企業(yè)網(wǎng)站內(nèi)容更新怎么操作網(wǎng)站收錄查詢?nèi)肟?/a>
  • 重慶網(wǎng)站建設(shè)重慶網(wǎng)站設(shè)計(jì)免費(fèi)入駐的賣貨平臺(tái)有哪些
  • 創(chuàng)新模式_提高質(zhì)量_建設(shè)一流的數(shù)學(xué)人才培養(yǎng)基地 教學(xué)成果獎(jiǎng)申報(bào)網(wǎng)站詳細(xì)描述如何進(jìn)行搜索引擎的優(yōu)化
  • 做網(wǎng)站只有域名哪個(gè)網(wǎng)站百度收錄快
  • 骨科醫(yī)院網(wǎng)站優(yōu)化服務(wù)商seo網(wǎng)絡(luò)推廣公司報(bào)價(jià)
  • 多語(yǔ)種網(wǎng)站營(yíng)銷溫州seo服務(wù)
  • 做網(wǎng)站商城怎么樣國(guó)產(chǎn)長(zhǎng)尾關(guān)鍵詞拘挖掘
  • 做網(wǎng)站銷售iis搭建網(wǎng)站
  • 找人做網(wǎng)站 優(yōu)幫云百度電話銷售
  • wordpress 微網(wǎng)站模板百度搜索平臺(tái)
  • wordpress網(wǎng)站插件軟文營(yíng)銷的概念
  • 平面設(shè)計(jì)有什么網(wǎng)站360推廣
  • wordpress怎么改變文章的域名網(wǎng)站推廣的優(yōu)化
  • 無(wú)錫做網(wǎng)站費(fèi)用北京百度推廣代理