天天看點

Qt學習之信号和槽機制

  1. 概念

    信号和槽是Qt中自行定義一種通信機制,實作對象之間的互動;當對象的狀态發生改變,将會發送信号,該信号可以被其它對象所接收,接收到信号後會執行一個指定操作函數(槽)。

  2. 定義
    class XX:public QObject{
    	Q_OBJECT //moc元對象編譯器
    signals:
    	void sig_func(...);//信号
    public slots:
    	void slot_func(...){...}//槽	
    };
               

    注:信号函數隻需聲明,不能寫定義

    注:槽函數可以連接配接到某個信号上,通過信号可以觸發槽函數的執行;另外槽函數也可以當做一個普通成員函數,直接調用.

  3. 信号和槽連接配接
    QObject::connect(
    	const QObject* sender,//信号發送對象 
    	const char* signal, //信号函數
    	const QObject* receiver,//信号的接收對象 
    	const char* method)//槽函數
               

    SIGNAL(信号函數(參數表))//将信号函數轉換為const char*

    SLOT(槽函數(參數表))//将槽函數轉換為const char*

    案例:建立Qt應用程式,裡面包含一個标簽(QLabel)和一個按鈕(QPushButton),實作點選按鈕關閉标簽功能.

    #include <QApplication>
    #include <QLabel>
    #include <QPushButton>
    #include <QFont>
    #include <QDialog>
    
    int main(int argc,char** argv){
        QApplication app(argc,argv);
        QDialog parent;//父視窗
        parent.resize(480,320);
        //建立按鈕和标簽控件
        QPushButton button("關閉标簽",&parent);
        QLabel label("我是标簽",&parent);
        //調整大小和位置
        button.move(50,200);
        label.move(50,50);
        button.resize(150,50);
        label.resize(150,50);
        //設定字型大小
        QFont font;
        font.setPointSize(20);
        parent.setFont(font);
        
        //動态建立按鈕對象
        QPushButton* button2 = 
            new QPushButton("退出",&parent);
        button2->move(300,200);
        button2->resize(150,50);
    
        //顯示父視窗
        parent.show();
        
        //點選按鈕關閉标簽
        QObject::connect(
            &button,SIGNAL(clicked(void)),
            &label,SLOT(close(void)));
        //練習:使用new操作動态建立一個按鈕對象,文本顯
        //示"退出",實作點選該按鈕退出應用程式功能.
        QObject::connect(
            button2,SIGNAL(clicked(void)),
            //&app,SLOT(closeAllWindows(void)));
            &app,SLOT(quit(void)));
            //&parent,SLOT(close(void)));
    
        return app.exec();
    }
               
  4. 信号和槽連接配接的文法要求

    1)信号和槽參數要一緻

    QObject::connect(A,SIGNAL(sigfun(int)), B,SLOT(slotfun(int)));//ok
    QObject::connect(A,SIGNAL(sigfun(void)), B,SLOT(slotfun(int)));//error
               
    2)可以有預設參數
    class B:public QObject{
    	Q_OBJECT
    public slots:
    	void slotfun(int = 0){}
    };
    QObject::connect(A,SIGNAL(sigfun(void)), B,SLOT(slotfun(void)));//ok
               
    3)信号的參數可以多于槽,多餘參數将被忽略

    QObject::connect(A,SIGNAL(sigfun(int)),B,SLOT(slotfun(void)));//ok

    4)一個信号可以同時連接配接多個槽(一對多)

    QObject::connect(A,SIGNAL(sigfun(int)),B1,SLOT(slotfun1(int)));

    QObject::connect(A,SIGNAL(sigfun(int)),B2,SLOT(slotfun2(int)));

    注:當A發送信号,B1和B2的槽函數都将被執行,但是多線程下執行順序不确定.

    5)多個信号可以同時連接配接同一個槽(多對1)

    QObject::connect(A1,SIGNAL(sigfun1(int)), B,SLOT(slotfun(int)));

    QObject::connect(A2,SIGNAL(sigfun2(int)), B,SLOT(slotfun(int)));

    注:無論A1還是A2發送信号,B的槽函數都會被執行

    6)兩個信号可以直接連接配接(信号串聯)

    QObject::connect(A1,SIGNAL(sigfun1(int)), A2,SIGNAL(sigfun2(int)));

    A1–A2–>B

    注:如果A1發送信号,A2的信号也将随之發送

    案例:事件同步,實作滑塊(QSlider)和選值框(QSpinBox)同步運作

    1)滑塊:QSlider

    QSlider(垂直/水準,父視窗指針);//構造函數

    void setRange(int min,int max);//設定滑動範圍

    void valueChanged(int value);//滑塊滑動時發送的信号

    void setValue(int value);//設定目前滑塊位置槽函數

    2)選值框:QSpinBox

    QSpinBox(父視窗指針);//構造函數

    void setRange(int min,int max);//設定選值框數值範圍

    void valueChanged(int value);//數值改變時發送的信号

    void setValue(int value);//設定目前目前數值槽函數

    #include <QApplication>
    #include <QSlider>//滑塊
    #include <QSpinBox>//選值框
    #include <QDialog>
    #include <QFont>
    int main(int argc,char** argv){
        QApplication app(argc,argv);
        //父視窗
        QDialog parent;
        parent.resize(480,320);
        QFont font;
        font.setPointSize(20);
        parent.setFont(font);
        //滑塊
        QSlider slider(Qt::Horizontal,&parent);
        slider.setRange(1,100);
        slider.move(100,50);
        //選值框
        QSpinBox spin(&parent);
        spin.setRange(1,100);
        spin.move(100,200);
        //顯示父視窗
        parent.show();
        //滑塊滑動,選值框數值随之改變
        QObject::connect(
            &slider,SIGNAL(valueChanged(int)),
            &spin,SLOT(setValue(int)));
        //選值框數值改變,滑塊随之滑動
        QObject::connect(
            &spin,SIGNAL(valueChanged(int)),
            &slider,SLOT(setValue(int)));
    
        return app.exec();
    }
               

注意以上代碼編譯時要按照qmake -project qmeke make …

繼續閱讀