QT入门(四)——初识信号与槽函数机制|界面之间的跳转|界面之间的数据传递


信号与槽函数,是QT中一种特有的通信机制,类似于中断和中断函数。

connect()函数

用connect将QMainwindow和PushBottom连接起来
在mainwindow.cpp中

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //通过clicked信号,进入clicked_fun这个信号,this就是这个界面
    connect(ui->bt1,&QPushButton::clicked,this,&MainWindow::clicked_fun);  //不要括号,是调用信号不是函数
}

connect(信号的发出者,发出什么样的信号,信号的接收对象,槽函数)
第一步:写出槽函数,槽函数就是信号的接收对象要做出的反映,注意,connect中的槽函数不带括号,
第二步:需要另外在这个mainwindow.cpp文件对应的mainwindow.h中,在专有槽函数中,做函数的声明。

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots://专有的槽函数
    void clicked_fun(); //槽函数的声明
    void on_pushButton_clicked();
    void on_bt2_clicked();
    void on_bt1_clicked();
    
private:
    Ui::MainWindow *ui;
};

第三步:光标放在函数上,右键——refactor——在mainwindow.cpp中定义
在这里插入图片描述
然后在mainwindow.cpp中,定义这个槽函数,里面就是要让信号的接受者做出的反应动作
如果账号和密码与设置的账号密码相同,那么就进入到第二个界面

void MainWindow::clicked_fun()  //函数的定义
{
    //点击登录按键就会到这里
    //qt里面输出一个函数qDebug()
    qDebug()<<"您点击了登录按钮";
    //登录按钮
    qDebug()<<"15";
    QString zhanghao = ui->zhanghao->text();  //申请的是栈空间
    QString mima = ui->mima->text();

    if (zhanghao == "123"&& mima=="123")  //要用双引号
    {

         //相等,那么点击登录就可以跳转到第二个界面loginwin
        //建立mainwindow和loginwin的连接
        //创建第二个窗口
        //因为include了loginwin.h,里面有loginWin这个类
        //这样写申请的是堆空间,不会被释放的
        //和main.cpp中的MainWindow w;相比,这种写法申请的是栈空间
        loginWin *w = new loginWin();
        //待下面的函数全部运行完了之后,就会跳到第二个界面的loginwin.cpp中,执行里面的所有内容
        //完成跳到第二个窗口之后,栈空间会消失,堆空间会保留
        w->show();

        //调用我们在login.h中写的setsetUname这个函数,
        //把原先在栈里面的zhanghao变量,运用setSetUname函数保存到堆中,由于w是推,所以保存在堆中了
        w->setSetUname(zhanghao);
        qDebug()<<"ok";
        //关闭当前Mainwindow这个窗口,由于它在main中申请的是栈空间,所以可以用close
        this->close();
    }
}

在ui界面中,转到槽函数

在ui界面中,放置好一个组件后(如按键),右键——转到槽——选择一种触发类型(如click())
在这里插入图片描述
在这里插入图片描述

点击ok之后,就会在mainwindow.cpp(就是当前这个ui界面对应的cpp文件)中,自动添加一个槽函数,其函数名为on_组件名_信号的操作,同时在对应的.h中的private slots中也会自动有这个函数的声明。然后就去槽函数中写触发的功能就行了。
这种方法建立的槽函数不用再写connect()这个函数了,因为系统会自动识别出on_组件名_信号的操作这个格式的。
在这里插入图片描述
在这里插入图片描述

新建界面

光标放在总工程文件夹上,右键——add new
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完成之后,就会出现loginwin.cpp loginwin.h loginwin.ui这三个文件

各个界面中的组件名字要不一样

界面的切换(单向)

第一个界面
在这里插入图片描述
第二个界面
在这里插入图片描述

从第一个界面mainwindow切换到第二个界面loginwin
在第一个界面中,按下登录按钮后,进入第二个界面,所以在按钮的槽函数中,写切换代码
1.当前文件中要include跳转到的界面的.h文件 (如loginwin.h),new一个第二个界面这个对象loginWin *w = new loginWin();
2.显示第二个界面w->show();
3.关闭当前窗口this->close();

注意:
mainwindow这个界面是在创建工程时,在main.cpp中自动有的mainWindow w ,所以申请的是栈空间,用this->close();去关闭窗口
但是
loginwin这个界面是loginWin *w = new loginWin();这样new出来的,手动申请的,所以申请的是堆空间,所以之后关闭这个界面是用delete this,而不是this->close();!!

void MainWindow::clicked_fun()  //函数的定义
{
    //点击登录按键就会到这里
    //qt里面输出一个函数qDebug()
    qDebug()<<"您点击了登录按钮";
    //登录按钮
    qDebug()<<"15";
    QString zhanghao = ui->zhanghao->text();  //申请的是栈空间
    QString mima = ui->mima->text();

    if (zhanghao == "123"&& mima=="123")  //要用双引号
    {

         //相等,那么点击登录就可以跳转到第二个界面loginwin
        //建立mainwindow和loginwin的连接
        //创建第二个窗口
        //因为include了loginwin.h,里面有loginWin这个类
        //这样写申请的是堆空间,不会被释放的
        //和main.cpp中的MainWindow w;相比,这种写法申请的是栈空间
        loginWin *w = new loginWin();
        //待下面的函数全部运行完了之后,就会跳到第二个界面的loginwin.cpp中,执行里面的所有内容
        //完成跳到第二个窗口之后,栈空间会消失,堆空间会保留
        w->show();

        //调用我们在login.h中写的setsetUname这个函数,
        //把原先在栈里面的zhanghao变量,运用setSetUname函数保存到堆中,由于w是推,所以保存在堆中了
        w->setSetUname(zhanghao);
        qDebug()<<"ok";
        //关闭当前Mainwindow这个窗口,由于它在main中申请的是栈空间,所以可以用close
        this->close();
    }
}

待以上所有程序执行完之后,就会跳到第二个界面,去执行的loginwin.cpp中的所有内容,完成跳到第二个窗口之后,由于写了 this->close();这个,所以栈空间会消失,堆空间会保留。

loginwin.cpp中的所有内容,和第一个界面的程序类似

#include "loginwin.h"
#include "ui_loginwin.h"
#include "mainwindow.h"
#include "gongneng.h"
#include<QDebug>

loginWin::loginWin(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::loginWin)
{
    ui->setupUi(this);
}

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


//点击开灯会跳转到功能界面3
void loginWin::on_pushButton_clicked()
{
    //也可以在这里写显示第一个界面给我们发过来的信息



    //创建界面3gongneng
    //下一个窗口3gongneng要回到这个窗口2loginwin的时候一定要加this,即下一个窗口中用了用parentWidget(显示隐藏窗口的时候
      GongNeng *ww = new GongNeng(this);  //申请一个堆空间
      //在第二个界面中点一下出现第三个窗口
      ww->show(); //执行完下面的代码后,跳转到gongneng.cpp中
      this->hide();//隐藏当前界面2

}

void loginWin::setSetUname(const QString &value)
{
    //把使用这个函数时,括号里的字符串拿出来
    setUname = value;
    //显示第一个界面给我们发过来的信息
    ui->labelz->setText(setUname);
     qDebug()<<"nan";
}

界面的切换(双向)

从第二个loginwin界面切换到第三个界面gongneng界面,然后再从第三个界面切换回来
在这里插入图片描述
在这里插入图片描述

1.同样的方法先新建第三个界面,然后在ui界面中放置按钮组件‘
2.在第二个界面的按钮上,右键——转到槽——click(),在这个槽函数中编写进入第三个界面的函数
记得要在第二个界面的.cpp文件中include第三个界面的.h文件

//点击开灯会跳转到功能界面3
void loginWin::on_pushButton_clicked()
{
    //也可以在这里写显示第一个界面给我们发过来的信息
    //创建界面3gongneng
    //下一个窗口3gongneng要回到这个窗口2loginwin的时候一定要加this,即下一个窗口中用了用parentWidget(显示隐藏窗口的时候
      GongNeng *ww = new GongNeng(this);  //申请一个堆空间
      //在第二个界面中点一下出现第三个窗口
      ww->show(); //执行完下面的代码后,跳转到gongneng.cpp中
      this->hide();//隐藏当前界面2

}

由于还要从第三个界面回到第二个界面,所以,在new第三个界面对象的时候,括号中要加this,GongNeng *ww = new GongNeng(this);因为在第三个界面中要显示出隐藏的第二个界面,
然后显示第三个刚刚new的对象界面ww->show();
隐藏当前界面this->hide();//隐藏当前界面2
执行完上述函数之后,程序就会跳转到gongneng.cpp文件中,去执行那个里面的内容

3.在第三个界面中,点击按钮返回到第二个界面
即 显示刚刚隐藏的第二个界面this->parentWidget()->show();
然后关掉当前的界面
用parentWidget()的时候一定要在跳转前先关联,就是在loginwin.cpp中申请gongneng这个空间的时候要加this

void GongNeng::on_fanhui_clicked()
{
    //返回上一层的函数
    this->parentWidget()->show();//显示隐藏的窗口界面
    //关掉当前的窗口
    delete this;        //自己手动申请的空间必须用delete,不能用close

}

界面之间的数据传递

将第一个界面mainwindow中输入的用户名,在第二个界面loginwin中显示
1.mainwindow.cpp和loginwin.cpp中都包含loginwin.h这个头文件,所以在loginwin.h这个头文件的private中定义一个私有变量
在这里插入图片描述
2.然后光标放在这个变量上,右键——refacotor——create setter member function
在这里插入图片描述
然后就会在logwin.h中产生一个公有函数的声明,让私有变量变成公有函数,就是去别人可以去设置这个私有变量的函数,一般情况下,这个函数名是set加变量名,声明完了这个设置函数之后,就在loginwin.cpp函数中去编写这个设置函数
就是显示第一个界面传来的内容


void loginWin::setSetUname(const QString &value)
{
    //把使用这个函数时,括号里的字符串拿出来
    setUname = value;
    //显示第一个界面给我们发过来的信息
    ui->labelz->setText(setUname);
     qDebug()<<"nan";
}

自己创建的变量都放类的private中,public中放的是函数,供外界去设置(set get)这些私有变量

3.在第一个界面的mainwindow.cpp文件中,的点击按钮跳转到第二个界面去的那个槽函数汇总,调用刚刚声明的函数
w->setSetUname(zhanghao);
将要传递的内容放在括号中

void MainWindow::clicked_fun()  //函数的定义
{
    //点击登录按键就会到这里
    //qt里面输出一个函数qDebug()
    qDebug()<<"您点击了登录按钮";
    //登录按钮
    qDebug()<<"15";
    QString zhanghao = ui->zhanghao->text();  //申请的是栈空间
    QString mima = ui->mima->text();

    if (zhanghao == "123"&& mima=="123")  //要用双引号
    {

         //相等,那么点击登录就可以跳转到第二个界面loginwin
        //建立mainwindow和loginwin的连接
        //创建第二个窗口
        //因为include了loginwin.h,里面有loginWin这个类
        //这样写申请的是堆空间,不会被释放的
        //和main.cpp中的MainWindow w;相比,这种写法申请的是栈空间
        loginWin *w = new loginWin();
        //待下面的函数全部运行完了之后,就会跳到第二个界面的loginwin.cpp中,执行里面的所有内容
        //完成跳到第二个窗口之后,栈空间会消失,堆空间会保留
        w->show();

        //调用我们在login.h中写的setsetUname这个函数,
        //把原先在栈里面的zhanghao变量,运用setSetUname函数保存到堆中,由于w是推,所以保存在堆中了
        w->setSetUname(zhanghao);
        qDebug()<<"ok";
        //关闭当前Mainwindow这个窗口,由于它在main中申请的是栈空间,所以可以用close
        this->close();
    }
}

当程序执行第二个界面的.cpp文件时,由于在刚刚调用了set这个函数,所以就会去执行set函数

Qt ,如果你需要在不同线程传递指针,可以使用 `QMetaObject::invokeMethod()` 方法来实现。这个方法可以在一个对象的线程上异步调用一个函数,同时将指定的参数传递给它。 具体来说,你需要在信号连接时指定连接类型为 `Qt::QueuedConnection`,这样就可以确保函数在接收到信号时在目标线程执行。然后,在函数使用 `QMetaObject::invokeMethod()` 方法异步地调用目标函数,将指针参数传递给它。 下面是一个示例代码: ```c++ // 定义一个自定义信号,其参数为指针类型 class MyObject : public QObject { Q_OBJECT signals: void mySignal(MyObject* obj); }; // 定义一个函数,其参数为指针类型 void MyObject::mySlot(MyObject* obj) { // 在函数使用 QMetaObject::invokeMethod() 方法异步地调用目标函数 QMetaObject::invokeMethod(this, "myTargetFunction", Qt::QueuedConnection, Q_ARG(MyObject*, obj)); } // 定义一个目标函数,其参数为指针类型 void MyObject::myTargetFunction(MyObject* obj) { // 处理接收到的指针参数 // ... } ``` 在这个示例,当信号 `mySignal` 被发射时,函数 `mySlot` 将被调用,并在其使用 `QMetaObject::invokeMethod()` 方法异步地调用目标函数 `myTargetFunction`,将指针参数传递给它。注意,这里指针类型的参数需要使用 `Q_ARG()` 宏进行包装,以便正确地传递给 `QMetaObject::invokeMethod()` 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值