淺談Qt信號-槽機制

最近在學習Qt,暫時涉獵還不深,現將學習過程中的一點想法記錄下來。(信號-槽機制)
學習Qt的這段時間,有一種觀點隨處可見,即:信號-槽機制是Qt的核心特徵。對於這個讓Qt引以爲傲的機制,我們是必須熟悉的。
相關的資料也是很多的,尤其是對信號-槽機制的幾種關聯模式,以及connect函數的幾種重載等方面的資料特別多也特別詳細,感謝前人的分享!
但是不久我就發現這種想法是錯誤的,因爲這樣就將信號-槽機制的在兩個對象之間通信的主要作用給忽視了。信號的真正奧義是要傳統數據的!
想到這裏,就值得思考一下如何正確的在信號和槽之間傳遞參數了,於是我動手寫了一個小程序進行檢驗,
結果表明:如果要正確的將參數在信號和槽之間傳遞,需要滿足以下條件之一:
1、信號的參數與槽的參數完全相對應。(就像平時我們寫函數的聲明和定義一樣)
2、信號的參數多於槽的參數。(這種請況怎麼解釋呢,可以將信號和槽的連接看成用信號“調用”槽函數,如果信號的參數多於槽函數的需要,
槽會默認將多餘的參數“丟棄”。)
(注意,本示例在界面文件上,有兩個QPushButton)

mainwindow.h

#ifndef MAINWINDOW_H
     #define MAINWINDOW_H
     #include <QMainWindow>
     #include <QPushButton>
     namespace Ui {
     class MainWindow;
     }
     class MainWindow : public QMainWindow
     {
     Q_OBJECT
     public:
        explicit MainWindow(QWidget *parent = 0);
        void Signal_Slot();
        ~MainWindow();
     private:
        Ui::MainWindow *ui;
     signals:
        void SignalZero();//不帶參數
        void SignalOne(int i);//帶一個參數
        void SignalTwo(int i,long l);//帶兩個參數
     public slots:
        void SlotZero();
        void SlotOne(int i);
        void SlotTwo(int i,long l);
        void SlotOne(float f);
     private slots:
        void on_MyButton_clicked();
        void on_MyButton2_clicked();
        };
     #endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Signal_Slot();
    emit SignalZero();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Signal_Slot()//連接信號和槽
{
    connect(this,SIGNAL(SignalZero()),SLOT(SlotZero()));
    connect(this,SIGNAL(SignalOne(int)),SLOT(SlotOne(int)));
    connect(this,SIGNAL(SignalTwo(int,long)),SLOT(SlotTwo(int,long)));//前三個是信號和槽的參數完全相對應的

    //這兩種調用時可以的
    connect(this,SIGNAL(SignalOne(int)),SLOT(SlotZero()));//帶一個參數的信號,連接不帶參數的槽
    connect(this,SIGNAL(SignalTwo(int,long)),SLOT(SlotOne(int)));//帶兩個參數的信號,連接帶一個參數的槽

    //下面的兩個調用時不正確的
//    connect(this,SIGNAL(SignalOne(int)),SLOT(SlotOne(float)));
//    connect(this,SIGNAL(SignalOne(int)),SLOT(SlotTwo(int,long)));
}

void MainWindow::SlotZero()
{
    qDebug()<<"success"<<endl;
    QMessageBox::about(this,"TEG_for_Signal_Slot", "You have called the Slot function with none parameter");
}

void MainWindow::SlotOne(int i)
{
    qDebug()<<"success:"<<i<<endl;
    QMessageBox::about(this,"TEG_for_Signal_Slot", "You have called the Slot function with one parameter");
}

void MainWindow::SlotTwo(int i, long l)
{
    qDebug()<<"i: "<<i<<"l: "<<l<<endl;
    QMessageBox::about(this,"TEG_for_Signal_Slot", "You have called the Slot function with two parameters");
}

void MainWindow::SlotOne(float f)
{
    qDebug()<<"success:"<<f<<endl;
    QMessageBox::about(this,"TEG_for_Signal_Slot", "You have called the Slot function with float parameters");
}


void MainWindow::on_MyButton_clicked()
{
    int i=520;
    emit SignalOne(i);
}

void MainWindow::on_MyButton2_clicked()
{
    int i = 219;
    long l = 1314;
    emit SignalTwo(i,l);
}
總結:談談對信號和槽函數的理解,信號是一個特殊的成員函數,特殊在它只有聲明,返回類型只能是void。槽函就是普通的成員函數,
與其他成員函數的唯一不同就是它能夠被connect調用,並與信號綁定,像普通成員函數那樣調用槽函數是完全可以的!
connect的幾種重載需要熟悉,這是保證正確實現信號-槽機制的關鍵之一。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章