신호 (시그널)와 슬롯 (슬롯)을 제어 매우 편리해진다 간의 통신을 허용 Qt는 유일한 메커니즘이다. 당신은 쉽게 여러 슬롯, 더 바인딩에 대한이 문서의 이야기를 결합하는 신호를 사용할 수있을 때 신호 슬롯, 슬롯의 실행 순서.
연결 기능
연결 신호 및 슬롯 커넥션을 통해, QObject를 상속 클래스는이 메커니즘을 사용할 수있다.
[static] QMetaObject::Connection QObject::connect(
const QObject *sender, const char *signal,
const QObject *receiver, const char *method,
Qt::ConnectionType type = Qt::AutoConnection)
그것은 발신자와 바인딩 방법의 신호, 당신은 발광 신호를 호출 할 때, 그것은 수신기의 트리거 메소드를 호출의 수신기. 그러나 그것은 또한 다섯 번째 매개 변수를 가지고, Qt는 :: ConnectionType 연결 유형은 , 당신은 그것에 대해 알 수 없습니다.
그루브 연결 종별 신호
QT : ConnectionType 연결 유형 (목록)을 열거하여 설명한다.
enum Qt::ConnectionType
이 트리거 될 때 즉시 슬롯 함수를 호출하거나 호출을 기다리는 큐를 입력 연결 신호를 결정한다. 다음과 같이 설명한다 :
일정한 | 값 | 기술 |
---|---|---|
Qt는 :: AutoConnection | 0 | 스레드에있는 신호 수신기를 전송, Qt의 :: DirectConnection를 사용하는 경우 (기본값), 그렇지 않으면 Qt는 :: QueuedConnection를 사용합니다. 하여 전송 신호의 특정 형태를 결정할 때. |
Qt는 :: DirectConnection | 1 | 신호 문제는, 슬롯을 즉시 호출 될 때. 슬롯 신호 스레드를 수행 |
Qt는 :: QueuedConnection | 이 | 수신기 스레드 제어 반환은, 슬롯가 호출됩니다. 실행 스레드 슬롯 수신기. |
Qt는 :: BlockingQueuedConnection | 삼 | 같은 Qt는 :: QueuedConnection, 그냥 슬롯 반환을 알고, 신호 스레드가 차단 발표했다. 당신이 신호 수신기에 위치해 스레드를 보낼 경우, 당신은이 연결, 그렇지 않으면 응용 프로그램의 교착 상태를 사용할 수 없습니다. |
Qt는 :: UniqueConnection | 0x80으로 | (비트 단위 OR) 조합 모드 (Qt4.6 소개) |
필요성이 백그라운드 이벤트에 저장할 Qt는 매개 변수를 복사 할 수 있기 때문에 연결 대기열 유형이 매개 변수는 시스템 Qt는 요소 객체 유형에 알고 있어야합니다. 알 수없는 형식을 사용하는 경우 다음과 같은 오류가보고됩니다.
QObject::connect: Cannot queue arguments of type 'MyType'
테스트 코드
사용 시나리오가 필요하기 때문에, 나는 여기에 대해 논의에만 단일 스레드 , 단일 신호 트리거 다수의 슬롯은 멀티 스레드 효과를 생성 할 수 있습니다.
Qt는 :: AutoConnection
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
void sig();
private slots:
void on_pushButton_clicked();
void slotA();
void slotB();
private:
Ui::MainWindow *ui;
int m_nT;
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_nT = 0;
connect(this, SIGNAL(sig()), SLOT(slotA()), Qt::AutoConnection);
connect(this, SIGNAL(sig()), SLOT(slotB()), Qt::AutoConnection);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
emit sig();
//QTimer::singleShot(0, this, SLOT(slotA1()));
//QTimer::singleShot(0, this, SLOT(slotA2()));
printf("cccc");
}
void MainWindow::slotA()
{
for (int i = 0; i < 10; i++)
printf("A%d", m_nT++);
}
void MainWindow::slotB()
{
for (int i = 0; i < 10; i++)
printf("B%d", m_nT++);
}
수술 후, 관찰 기록, sigA 신호 (), 몇 가지 테스트를 보낼 수있는 버튼을 클릭합니다.
항상 결과 다음과 같이
A0A1A2A3A4A5A6A7A8A9B10B11B12B13B14B15B16B17B18B19cccc
우리는 두 개의 슬롯이 운전 기능이 존재하지 않는 인터리빙 얻을 수 있습니다. QT 간격 :: DirectConnection를 사용하여 문서 송신기 스레드 수신 측과 관련하여 설명 当signal发出时,slot立即被调用。slot在signal线程中执行。
이 경우에, 및 slotB Slota 실행 스레드 (메인 스레드)으로하고, 그들은 순차적으로 실행된다 (단일 스레드) . SIG 즉시 전송 slotA 트리거된다 slotA를 실행 한 후, 다음 slotB 트리거 다음의 printf ( "CCCC")을 실행한다.
Qt는 :: QueuedConnection
위의 코드 slotA slotB 및 연결 유형은 Qt는 :: QueuedConnection를 변경하는 경우.
Qt::QueuedConnection,当控制返回到receiver的线程中时,slot被调用。slot执行在receiver的线程中。
다음과 같이 몇 가지 테스트 결과는 다음과 같습니다
ccccA0A1A2A3A4A5A6A7A8A9B10B11B12B13B14B15B16B17B18B19
또한 당신은 인터리빙 기능이 실행되는 두 개의 슬롯이 존재하지 않는 볼 수 있습니다. 그러나이 시간의 printf ( "CCCC")는 slotA 및 slotB 최대 전에 인쇄. SIG를 보낼 때 아마도 현재 기능은 아직 실행 메인 스레드, 현재 함수의 메인 쓰레드 slotA slotB 큐 및 대기에 들어간 후, 실행 한 후, 종료된다. 이 DirectConnection 즉시 다른 실행 연결되어 있습니다.
1.QueuedConnection 2.AutoConnection
다음과 같이 몇 가지 테스트 결과는 다음과 같습니다
B0B1B2B3B4B5B6B7B8B9ccccA10A11A12A13A14A15A16A17A18A19
QueuedConnection 우선 메인 쓰레드 후 메인 스레드가 현재 기능을 실행할 때까지,이 함수는 해당 슬롯을 수행 얻을 수있다.
1.AutoConnection 2.QueuedConnection
다음과 같이 몇 가지 테스트 결과는 다음과 같습니다
A0A1A2A3A4A5A6A7A8A9ccccB10B11B12B13B14B15B16B17B18B19
결론
하나의 신호를 이용하여 멀티 슬롯 결합 단일 스레드가 슬롯 트리거는 단일 스레드 실행 기능을 수행, 그 실행 순서를 갖는다.
슬롯 대응 단일 스레드 DirectConnection 현재 실행 함수보다 더 높은 우선 순위가 QueuedConnection는 (경우에 호출 한 후 상기 수신 개체 이벤트 루프 백하고) 현재 실행중인 기능이보다 낮은 우선 순위 슬롯 기능을 해당 즉시 호출 될 것이다.
참고 : 후자의 원인을 특정가 인증한다