1. 程式人生 > >訊號與槽連線方式(同步和非同步)

訊號與槽連線方式(同步和非同步)

事先宣告:此篇部落格非完全原創

一. 同步
synchronous.h

#ifndef SYNC_H
#define SYNC_H

#include <QObject>
#include <QDebug>

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called."
; } signals: void signalMyTestA(); }; class MyTestB : public QObject { Q_OBJECT public slots: void slotMyTestB() { qDebug()<<"slotMyTestB is called."; } signals: void signalMyTestB(); }; #endif // SYNC_H

main.cpp

#include <QApplication>

#include "synchronous.h"
#include "asynchronous.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MyTestA a; MyTestB b; QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));//a和b都在主執行緒中--> // a.emitSignal();// <--並且發訊號也在主執行緒中,同步呼叫 return app.exec(); }

二. 非同步
場景一:
asynchronous.h

#當sender和receiver在同一執行緒時,就是同步模式,而在不同執行緒時,則是非同步模式,其實這是錯誤的觀念。

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA();
};


class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB()
    {
        qDebug()<<"slotMyTestB is called.";
    }
signals:
    void signalMyTestB();
};


extern MyTestB *g_pMyTestB;
class MyTestC : public QThread
{
    Q_OBJECT
public:

    void run()
    {
        MyTestA a;
        connect(&a,SIGNAL(signalMyTestA()),g_pMyTestB,SLOT(slotMyTestB()));//a在子執行緒中,b在主執行緒中-->
        a.emitSignal();// <--發訊號在子執行緒中,非同步呼叫
        exec();

    }

public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();

};

main.cpp

#include <QApplication>

#include "synchronous.h"
#include "asynchronous.h"

MyTestB *g_pMyTestB = NULL;

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MyTestB b;
    g_pMyTestB = &b;
    MyTestC c;
    c.start();

    return app.exec();
}

場景二:
asynchronous.h

//在Auto模式下,如果sender的觸發時所處的執行緒和receiver不同,也會是非同步呼叫。

class MyTestA : public QObject
{
    Q_OBJECT
public:
    void emitSignal()
    {
        signalMyTestA();
    }

public slots:
    void slotMyTestA()
    {
        qDebug()<<"slotMyTestA is called.";
    }
signals:
    void signalMyTestA();
};

class MyTestB : public QObject
{
    Q_OBJECT
public slots:
    void slotMyTestB()
    {
        qDebug()<<"slotMyTestB is called.";
    }
signals:
    void signalMyTestB();
};

extern MyTestB *g_pMyTestB;
extern MyTestA *g_pMyTestA;
class MyTestC : public QThread
{
    Q_OBJECT
public:

    void run()
    {
        g_pMyTestA->emitSignal();//<--但是發訊號在子執行緒中,非同步呼叫
        exec();
    }

public slots:
    void slotMyTestC()
    {
        qDebug()<<"slotMyTestC is called.";
    }
signals:
    void signalMyTestC();
};

main.cpp

#include <QApplication>

#include "synchronous.h"
#include "asynchronous.h"

MyTestB *g_pMyTestB = NULL;
MyTestA *g_pMyTestA = NULL;
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MyTestA a;
    g_pMyTestA = &a;
    MyTestB b;
    g_pMyTestB = &b;
    QObject::connect(&a,SIGNAL(signalMyTestA()),&b,SLOT(slotMyTestB()));//a和b都在主執行緒中-->
    MyTestC c;
    c.start();

    return app.exec();
}

最終得出的結論:只有當訊號的傳送者和接收者處於同一個執行緒,並且傳送者觸發訊號時和接收者處於同一個執行緒,才會是同步呼叫。

determine if this connection should be sent immediately or put into
the event queue
if ((c->connectionType == Qt::AutoConnection
&& (currentThreadData != sender->d_func()->threadData
|| receiver->d_func()->threadData != sender->d_func()->threadData))
|| (c->connectionType == Qt::QueuedConnection)) {
queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
continue;
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
blocking_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv);
continue;
}

摘自qobject.cpp

相關推薦

訊號連線方式同步非同步

事先宣告:此篇部落格非完全原創 一. 同步 synchronous.h #ifndef SYNC_H #define SYNC_H #include <QObject> #include <QDebug> class MyT

深入理解JavaScript的執行機制同步非同步

不論是面試求職,還是日常開發工作,我們經常會遇到這樣的情況:給定的幾行程式碼,我們需要知道其輸出內容和順序。因為JavaScript是一門單執行緒語言,所以我們可以得出結論: JavaScript是按照語句出現的順序執行的 所以我們以為JS都是這樣的:

QT多執行緒中,物件訊號連線不上的解決辦法

1、在接收者建立執行緒中,把接收者移動到主執行緒中: pReceiverObj->moveToThread(QApplication::instance()->thread()); 2、這樣傳送訊號的時候,就會在主執行緒事件佇列處理中來處理了。 把connect的最

PyQt訊號之多執行緒中訊號的使用

簡單多執行緒訊號與槽的使用 最簡單的多執行緒使用方法是利用QThread函式,展示QThread函式和訊號簡單結合的方法 import sys from PyQt5.QtCore import

Pyqt/Qt訊號的理解

訊號與槽有三種使用方法:內建訊號與槽,自定義訊號與槽和裝飾器的訊號與槽。 內建訊號與槽 內建訊號與槽是指在發射訊號時,使用視窗控制元件的函式,而不是自定義的函式,可通過QObject.signal.connect將一個QObject的訊號連線到另一個QO

Pyqt/Qt訊號的理解

使用自定義引數 在PyQt程式設計過程中,經常會遇到給槽函式傳遞自定義引數的情況,比如有一個訊號與槽函式的連線是 button1.clicked.connect(show_page) 我們知道對於clicked訊號來說,它是沒有引數的;對於show_p

linux下qt5.7訊號之文字框同步

#include "signal.h" #include "ui_signal.h" signal::signal(QWidget *parent) :     QMainWindow(parent),     ui(new Ui::signal)//建立 {     ui->setupUi(this)

C# 用配置檔案連線資料庫WinformWebform

Winform中用配置檔案連線資料庫 資料庫連線類YSqlHelper程式碼: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst

Python之日期時間處理模組datedatetime

本節內容 前言 相關術語的解釋 時間的表現形式 time模組 datetime模組 時間格式碼 總結 前言 在開發工作中,我們經常需要用到日期與時間,如: 作為日誌資訊的內容輸出 計算某個功能的執行時間 用日期命名一個日誌檔案的名稱 記錄或展示某文章的釋出或修改

獲取IOC容器中的bean的兩種方式idclass的區別

// ClassPathXmlApplicationContext: 是 ApplicationContext的實現類,從類路徑下來載入配置檔案 ApplicationContext ctx=new ClassPathXmlApplicationContext("a

執行緒間機制同步互斥

執行緒間機制 { 多執行緒共享同一個程序子地址空間 優點: 執行緒間很容易進行通訊 1、 通過全域性變數實現資料共享和交換 缺點: 多個執行緒同時訪問共享物件時需要引入同步和互斥機制 }

Android使用HttpClient以Post、Get請求伺服器傳送資料的方式普通json

HttpParams params = new BasicHttpParams();//建立一個引數物件,用來儲存設定的各個引數 HttpProtocolParams.setContentCharset(params, "UTF-8");// 設定訊息所用的字符集 HttpProtocolParams.s

Android中BroadcastReceiver的兩種註冊方式靜態動態詳解

今天我們一起來探討下安卓中BroadcastReceiver元件以及詳細分析下它的兩種註冊方式。 BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來接收來自系統和應用中的廣播。在Android系統中,廣播體現在方方面面,例如當開機完成後系統會

RTSP流媒體資料傳輸的兩種方式TCPUDP

通常情況下rtsp協議中資料傳輸的實現是UDP,因工作需要,想讓rtsp的資料傳輸部分用TCP實現。DarwinStreamingServer伺服器能自適應客戶端發起的資料傳輸請求是用TCP方式,還是用UDP方式,這裡唯一需要解決的是客戶端協議的發起問題,而vlc支援RTS

工作總結之----java程式碼連線資料庫SqlServeroracle

程式碼:import java.sql.*; public class JDBCUtil { private static final String DBDRIVERSQLSWRVER = "c

微控制器通訊方式——序列通訊同步非同步、並行通訊

微控制器各種通訊方式的特點和主要應用場合 微控制器的埠按通訊方式分,可以分成哪兩種? 答:【序列通訊、並行通訊】 串列埠用的比較多: RS232,用於與標準的RS232裝置通訊 網絡卡,用於網際網路或採用網絡卡埠的裝置通訊 I2C,用於微控制器自己外設或多個微控制器之間通

c 開啟檔案方式二進位制文字

c語言檔案操作的一個問題:    c語言中開啟檔案有兩種方式,一種是二進位制方式,另一種是文字方式(ASCII碼方式)。這兩種方式有什麼區別?(對於Linux這種只有一種檔案型別的作業系統來說是沒有區別的)    我們就以windows為例說說區別:    a.以文

瀏覽器常見攻擊方式XSSCSRF

常見的瀏覽器攻擊分為兩種,一種為XSS(跨站指令碼攻擊),另一種則為CSRF(跨站請求偽造)。 XSS(跨站指令碼攻擊) 定義 XSS 全稱是 Cross Site Scripting,為了與“CSS”區分開來,故簡稱 XSS,翻譯過來就是“跨站指令碼”。X

C#、Asp.net 使用 WebClient Get Post同步非同步

一、C#、Asp.net 下使用WebClient Get Post 同步 非同步請求,直接貼程式碼 1、通用Http類 using System; using System.Globalization; using System.Net; using System.T

Qt 筆記:訊號連線方式

深入訊號與槽的連線方式 -Qt::DirectConnection(立即呼叫) -Qt::QueuedConnection(非同步呼叫) -Qt::BlockingQueuedConnection(同步呼叫) -Qt::AutoConnection(預設連線) -Q