Qt5教程: (3) 自定義信號與槽


1. 自定義槽

  • 槽可以是任何成員函數、普通全局函數、靜態函數
  • 槽函數和信號的參數和返回值要一致
  • 由於信號是沒有返回值的, 槽函數也一定沒有返回值
    首先在mainwidget.h中添加槽函數:
public slots:
    void mySlot();

之后在mainwidget.cpp文件中定義槽函數:

void MainWidget::mySlot()
{
    b2->setText("^_^");
}

現在, 我們希望當Button2按下時, Button2顯示的文本變成笑臉, 就需要將Button2的信號和我們自定義的槽函數連接:

connect(b2, &QPushButton::clicked, this, &MainWidget::mySlot);

保存后運行, 點擊Button2就會變成笑臉了:

附錄

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QPushButton>

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();

public slots:
    void mySlot();

private:
    QPushButton b1;
    QPushButton *b2;
};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    b1.setParent(this);
    b1.setText("Close");
    b1.move(50, 50);

    b2 = new QPushButton(this);
    b2->setText("Button2");
    b2->move(150, 50);

    connect(&b1, &QPushButton::clicked, this, &MainWidget::close);

    connect(b2, &QPushButton::clicked, this, &MainWidget::mySlot);

}

void MainWidget::mySlot()
{
    b2->setText("^_^");
}

MainWidget::~MainWidget()
{

}

2. 自定義信號

目標: 實現兩個獨立窗口之間的切換, 點擊"Next" 跳到下一個窗口, 點擊"Back" 返回到上一個窗口.

  • 信號沒有返回值, 但可以有參數
  • 信號只有函數聲明, 無需定義
  • 使用emit 發送信號
    首先修改當前窗口標題為"Window1", 並設置窗口大小:
    this->setWindowTitle("Window1");  // this->可以省略
    this->resize(300, 200);  // 長300, 寬200

之后修改Button2的文本"Button2"為"Next"
新建一個窗口
右鍵工程目錄"SignalAndSlot" --> Add New:

選擇 C++ --> C++ Class --> Choose:

輸入Class name為SubWidget, Base class為QWidget, 點擊Next, 點擊Finish:

之后一個新的窗口類就新建好了:

修改新窗口的標題:
在subwidget.cpp中構造函數下, 設置窗口的標題為"Window2", 大小和Windows1一樣:

    this->setWindowTitle("Windows2");
    this->resize(300, 200);

在新窗口中加入按鍵:
首先, 在subwidget.h中添加 頭文件, 然后聲明按鈕 b:

private:
    QPushButton b;

在subwidget.cpp中, 對按鈕進行編輯:

    b.setParent(this);
    b.setText("Back");
    b.move(150, 50);

實例化SubWidget:
但是, 我們僅僅是寫了一個新窗口的類, 還沒有實例化, 所以我們在mainwidget.h中先包含subwidget的頭文件, 然后實例化一個副窗口subWin對象:

    SubWidget subWin;

建立信號與槽的連接:
接下來, 我們來實現點擊"Next"顯示Windows2功能, 其實就是b2點擊這個信號, 觸發副窗口的show(), 並隱藏主窗口.
將mainwidget.h和mainwidget.cpp中所有的mySlot改為nextSlot. (共三處)
我們修改mainwidget.cpp中nextSlot()的定義:

void MainWidget::nextSlot()
{
    //  刪除 b2->setText("^_^");
    subWin.show();
    this->hide();
}

connect(b2, &QPushButton::clicked, this, &MainWidget::nextSlot);不變. 保存並運行, 就可以實現切換到Window2窗口了. 但是還沒有返回主窗口功能.
信號的創建和發送:
要實現Back功能, 就需要在"Back"按鈕按下后, 副窗口發送一個信號, 然后主窗口收到這個信號后, 顯示自己, 隱藏副窗口, 邏輯如下:
Back按下的信號 ----> 副窗口發送信號
副窗口的信號 ----> 主窗口show, 副窗口hide
下面看代碼怎么寫:
在subwidget.h中聲明一個自定義的信號, 和用於發送該信號的槽函數:

signals:
    void backSignal();

public slots:
    void sendSignal();

由於信號只需聲明, 無需定義, 所以只要在subwidget.cpp定義槽函數來發送信號:

void SubWidget::sendSignal()
{
    emit backSignal();
}

之后在Back按鈕按下后, 通過這個槽函數發送返回信號:

connect(&b, &QPushButton::clicked, this, &SubWidget::sendSignal);

在mainwidget中需要再定義一個槽函數來處理back信號:
在mainwidget.h中聲明槽函數

    void backSlot();

之后在mainwidget.cpp中定義:

void MainWidget::backSlot()
{
    this->show();
    subWin.hide();
}

之后connect信號與槽, 收到副窗口發送的信號后返回主窗口:

    connect(&subWin, &SubWidget::backSignal, this, &MainWidget::backSlot);

保存后運行, 現在可以在兩個界面中切換了.

附錄

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QPushButton>
#include "subwidget.h"

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();

public slots:
    void nextSlot();
    void backSlot();

private:
    QPushButton b1;
    QPushButton *b2;

    SubWidget subWin;
};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowTitle("Window1");
    this->resize(300, 200);
    b1.setParent(this);
    b1.setText("Close");
    b1.move(50, 50);

    b2 = new QPushButton(this);
    b2->setText("Next");
    b2->move(150, 50);

    connect(&b1, &QPushButton::clicked, this, &MainWidget::close);
    connect(b2, &QPushButton::clicked, this, &MainWidget::nextSlot);
    connect(&subWin, &SubWidget::backSignal, this, &MainWidget::backSlot);

}

void MainWidget::nextSlot()
{
    subWin.show();
    this->hide();
}

void MainWidget::backSlot()
{
    subWin.hide();
    this->show();
}

MainWidget::~MainWidget()
{

}

subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include <QPushButton>

class SubWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SubWidget(QWidget *parent = nullptr);

signals:
    void backSignal();

public slots:
    void sendSignal();

private:
    QPushButton b;
};

#endif // SUBWIDGET_H

subwidget.cpp

#include "subwidget.h"

SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("Windows2");
    this->resize(300, 200);

    b.setParent(this);
    b.setText("Back");
    b.move(150, 50);

    connect(&b, &QPushButton::clicked, this, &SubWidget::sendSignal);
}

void SubWidget::sendSignal()
{
    emit backSignal();
}


此文原創禁止轉載,轉載文章請聯系博主並注明來源和出處,謝謝!
作者: Raina_RLN https://www.cnblogs.com/raina/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM