C++ for QWidget:自定义的信号和槽

使用mainwindow构建

Signal

在Qt中,信号(signals)是特殊的成员函数,它们用于对象间的通信,并且有一些特殊的规则:

  1. 没有返回值‌:信号不能有任何返回值。在您的例子中,void signalOne() 看起来是满足这个条件的,因为它没有返回值。但是,重要的是要注意信号的实现(即函数体)通常是不需要的,也是不允许的。信号的实现由Qt的元对象系统(通过MOC)自动处理。

  2. 不能有函数体‌:在Qt中,信号通常没有函数体。它们被声明为没有实现的函数原型,MOC工具会处理这些声明并生成必要的代码来连接信号和槽。然而,在您的代码片段中,signalOne() 有一个函数体 { qDebug("wanted"); },这是不允许的。

  3. 使用Q_OBJECT‌:包含信号的类必须继承自QObject(或其子类),并且必须在类的私有部分包含Q_OBJECT宏。这个宏为类启用了Qt的元对象系统,包括信号和槽的机制。 

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QPushButton>
#include<QApplication>
#include<QMessageBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include "wanted.h"
#include "foods.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    Foods *foods1;
    Wanted *wanted1;
    void emitSingal();//声明发射信号函数
};
#endif // MAINWINDOW_H
//mainwindoww.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    foods1 = new Foods(this);
    wanted1 = new Wanted();
    QObject::connect(wanted1, &Wanted::signalOne, foods1, &Foods::slotOne);//连接信号和槽函数
    emitSingal();//使用函数发射信号
}

void MainWindow::emitSingal(){
    emit wanted1->signalOne();
}//发射信号函数的具体实现

MainWindow::~MainWindow()
{
    delete ui;
}
//wanted.h
#ifndef WANTED_H
#define WANTED_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>

class Wanted:public QObject
{
    Q_OBJECT
public:
    Wanted(QMainWindow *parent = nullptr);
    ~Wanted();
signals:
    void signalOne();//声明了信号一
};

#endif // WANTED_H

//wanted.cpp
#include "wanted.h"

Wanted::Wanted(QMainWindow *parent) {

}//无需具体实现信号函数
Wanted::~Wanted()
{
}
//foods.h
#ifndef FOODS_H
#define FOODS_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>

class Foods:public QObject
{
    Q_OBJECT
public:
    Foods(QMainWindow *parent = nullptr);
    ~Foods();
    void slotOne();//定义了slotOne槽函数,在某些低版本Qt中,需要先声明public slots:
};

#endif // FOODS_H
//foods.cpp
#include "foods.h"

Foods::Foods(QMainWindow *parent) {
}//QMainWindow作为父类,而不是QWidget

Foods::~Foods()
{}
void Foods::slotOne(){
    qDebug("foods");
}//槽函数的具体实现

输出结果

重载函数的情况

//wanted.h
signals:
    void signalOne();
    void signalOne(QString a);//新增了一个重载函数
//foods.h
    void slotOne();
    void slotOne(QString a);//槽函数与信号函数同步,也声明一个返回值相同,形参相同的重载函数
//foods.cpp
void Foods::slotOne(){
    qDebug("foods");
}
void Foods::slotOne(QString a){
    qDebug()<< a;
}//槽重载函数的具体实现
//mainwindow.cpp
//
    foods1 = new Foods(this);
    wanted1 = new Wanted();
    void(Wanted:: *wanten1Signal)(QString)=&Wanted::signalOne;
    void(Foods:: *foodsSignal)(QString)=&Foods::slotOne;//当信号函数和槽函数有了重载函数以后,就要创建函数指针明确指向的是哪一个函数,否则原先的QObject::connect(wanted1, &Wanted::signalOne, foods1, &Foods::slotOne);编译会不通过

    QObject::connect(wanted1, wanten1Signal, foods1, foodsSignal);
    emitSingal();
}

void MainWindow::emitSingal(){
    emit wanted1->signalOne("coffee");
}

输出结果:

可以看到这里输出的不是字符串原本的内容,而是在原有的基础上加上了双引号

要解决这个问题,把qDebug()<< a改为qDebug()<< a.toUtf8().data(),既先把a转换成QByteArray再转换成char *

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值