qt学习:多界面跳转+信号+槽函数

news2024/11/15 10:42:38

目录

概念

分类

多界面编程思路

新建界面

注意

头文件

无数据传输跳转界面

有数据传输跳转界面   对象公有接口

界面之间数据传输

信号与槽函数进行数据传输跳转界面

信号:

槽:

概念

格式1  关联信号和发送信号

格式2

通信步骤    自定义信号和槽函数

总结

实例  制作一个教务管理系统

第一步,新建一个Mainwindow类界面项目,配置ui,修改三个输入框的名字​编辑

第二步,设置Mainwindow类界面里的教师按钮的点击事件

第三步,新建一个teacherwindow类界面,配置ui界面和按钮点击事件,并在teacherwindow类界面里定义槽函数和自定义信号

第四步,新建一个setwindow类界面,配置ui界面和按钮点击事件,并在setwindow类界面里定义槽函数和自定义信号

第五步,定义Mainwindow类界面要发送的自定义信号和编写按钮点击事件

自定义信号

教师按钮点击事件

第六步,编写teacherwindow类界面和setwindow类界面里的槽函数和按钮点击事件

teacherwindow类界面

setwindow类界面


概念

实现多界面跳转

分类

  • 无数据传输跳转
  • 有数据传输跳转

多界面编程思路

  1. 创建另一个界面的对象
  2. 显示要跳转的界面
  3. 关闭或者隐藏当前的界面

一个界面的本质上就是一个类的对象,但是界面的显示和关闭完全由程序设计者维护,并不是由系统维护,所以界面对象的创建在堆空间上申请内存

新建界面

点击项目,右键,选择add new...,左边选择Qt,中间选择Qt设计师界面类,点击下一步,两个选一个,第一个首界面是QWidget,后面要跳转的界面都选QMainWindow

 再点击下一步,修改界面类名

注意

第一个设置的登录界面一定是 QWidget基类,否则界面跳转传递父窗口 一定会闪退。比如父窗口是QMainWindow,子窗口是QWidget,无法进行多界面跳转。而且建议第二个界面和后面的界面是QMainWindow基类

头文件

要包含新界面的头文件

无数据传输跳转界面

//跳转新界面不能回来原来界面
//先新建一个界面MWindow类
//跳转到另一个界面,然后关闭当前界面
void Loginwidget::on_btn1_clicked()//按钮点击函数
{
    //第一步:创建另一个界面的对象
    // new Mainwindow 说明创建新界面对象跟当前界面没有关联,不记录它是从哪个界面跳转而来 
    MainWindow *mainWidget = new MainWindow;
    //关闭之后自动销毁对象
    mainwidget->setAttribute(Qt::WA DeleteOnClose);
    //第二步:显示要跳转的界面
    mainWidget->show();
    //第三步:关闭当前的界面,跳转到另一个界面之后,就不能返回原来的界面了
    this->close();
}
//--------------------------------------
//跳转新界面能回来原来界面
//先新建一个界面MWindow类
//跳转到另一个界面,然后关闭当前界面
void Loginwidget::on_btn2_clicked()//按钮点击函数
{
    //第一步:创建另一个界面的对象
    // new MainWindow(this)把父窗口传递过去,记录从哪一个界面跳转
    //跳转的窗口可以设置按钮重新跳转回这个界面
    MainWindow *mainWidget = new MainWindow(this);
    //关闭之后自动销毁对象
    mainwidget->setAttribute(Qt::WA DeleteOnClose);
    //第二步:显示要跳转的界面
    mainWidget->show();
    //第三步:隐藏当前的界面,跳转到另一个界面之后,点击返回按钮还可以返回当前界面
    this->hide();
}

//新界面的返回按钮
void Mainwindow::on_backbtn_clicked()
{
    //因为在跳转时,记录了上一个界面
    //所以可以利用此函数获取当前窗口的父窗口对象指针
    Qwidget *parent = this->parentWidget();
    qDebug()<<"parent addr:"<<parent;
    //把之前父界面的隐藏状态改为显示状态,显示父界面
    parent->show();
    //关闭当前界面
    this->close();
    //销毁子界面
    //delete this; //如果设置了自动销毁,则不需要手动delete
}

有数据传输跳转界面   对象公有接口

界面之间数据传输

原理:就是不同界面本质上就是不同的类对象,也就是说不同类对象之间的数据传输。在一个类中定义一个公有的接口,在另一个类的接口函数中,通过类对象调用公有接口,传入对应的参数值

//新建一个界面MainWindow类
//跳转到新界面
void Loginwidget::on_btn1_clicked()
{
    //第一步:创建另一个界面的对象,并把本身界面的地址传给新界面
    MainWindow *mainWindow = new MainWindow(this);
    //关闭界面的时候自动释放内存
    mainWindow->setAttribute(Qt::WA DeleteOnClose):
    //传输数据 --调用公有函数成员实现数据传输
    mainWindow->setIP(ui->iplineEdit->text());//获取本界面的输入框的数据并传输
    mainWindow->setPort(ui->portlineEdit->text());//获取本界面的输入框的数据并传输
    //第二步:显示要跳转的界面
    mainWindow->show();
    //第三步:隐藏当前的界面
    this->hide();
}

//新界面
//这个函数是在另一个类中被调用 用来传输数据
void Mainwindow::setIP(QString ip) 
{
    ui->iplabel->setText(ip);//当前界面的输入框写入数据
}
//这个函数是在另一个类中被调用 用来传输数据
void Mainwindow::setPort(QString port)
{
    ui->portlabel->setText(port);//当前界面的输入框写入数据
}
//返回按钮
void Mainwindow::on_pushButton_clicked()
{
    //获取原先界面的地址
    Qwidget *parent = this->parentwidget();
    //显示原先界面
    parent->show();
    //关闭当前界面
    this->close();
}

信号与槽函数进行数据传输跳转界面

信号:

本质上也是一个函数,可以使用系统预定义的信号,开发者也可以自定义信号,如果自定义信号,该信号只需要声明(类中),并不需要实现

槽:

本质上也是一个函数,可以使用系统预定义的槽,开发者也可以自定义槽,如果自定义槽,该槽需要声明(类中)并需要实现

概念

  • 信号与槽函数机制是QT编程的基础也是QT的一大创新,是通过QT的元对象系统实现。
  • 信号(Signal)就是在特定条件下被发射的事件。比如QPushButton 最常见的信号就是鼠标单击时发射clicked()信号。当信号被发射出去之后,很多时候我们需要对这个信号进行响应处理,对信号进行响应的函数称之为 槽函数,槽函数跟一般的函数用法一样,只不过槽函数可以跟信号进行关联。当信号被发射时,槽函数将会自动执行。
  1. 信号-----------函数,该函数不需要实现
  2. 槽函数----------函数,该函数需要实现,实现自己的功能

格式1  关联信号和发送信号

QMetaObject::Connection QObject::connect
(
    const QObject *sender,//信号的发送者
    const char *signal,//发送什么信号
    const QObect *receiver,//接收者
    const char *method,//接收者的槽函数(信号响应函数)
    Qt::ConnectionType = Qt::AutoConnection//连接的类型,默认自动连接
)

Connection 函数是QObject类的一个静态函数,不过QObject类是所有Qt类的基类,在实际调用时可以忽略前面的限定符。        

//当你在本界面新建一个按钮,然后建立点击函数,会自动关联点击信号
//也可以手动关联
connect
(
    ui->btn1,//信号发送者指针,本界面的按钮发送的信号
    &QPushButton::clicked,//按钮发送的信号,点击信号,已经定义好了
    this,//接收者对象指针,自己接收
    &Widget::on_btn1_clicked//接受者的槽函数,点击事件函数
);

void Widget::on_btn1_clicked()
{
    qDebug()<<"1";
    //也可以自己发送自定义信号,sendSignals是自定义信号,
    //格式如下,emit 信号;
    emit sendSignals("自定义数据");
}

格式2

格式
Connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
SIGNAL表示宏函数,括号里是信号,信号有参数就要加参数
SLOT表示槽函数,括号里是槽函数,槽函数有参数就要加参数

//比如
Connect(this,SIGNAL(sendIPSignal(QString)),mainWindow,SLOT(on_getIP(QString)));
//sendIPSignal(QString)是自定义信号
//on_getIP(QString)是自定义槽函数

通信步骤    自定义信号和槽函数

第一步:在LoginWidget类(旧界面)中自定义 或者 使用系统预定义好的信号,谁发送信号就在哪定义

class LoginWidget:public QWidget
{
    Q_OBJECT//如果是自定义的类,想要支持信号和槽的操作,必须要加上宏
            //[2] 声明这个宏,来说明要使用信号和槽
public:
    LoginWidget(QWidget *parent = nullptr);
    ~LoginWidget();

private slots://代表下面是槽函数
    void on_btn1_clicked();

signals://表示下面是自定义信号  不需要实现,只用声明,可以发送数据
    void sendIPSignal(QString ip);

private:
    Ui::sendIPSignal(QString ip);
}

第二步:在MainWindow类(新界面)中定义槽函数(类内声明类外实现),谁接收就在谁那定义槽函数

class MainWindow : public QMainWindow
{
    Q_OBJECT//如果是自定义的类,想要支持信号和槽的操作,必须要加上宏
            //[2] 声明这个宏,来说明要使用信号和槽

private slots://表示下面是槽函数
    void on_getIP(QString ip);//类内声明类外定义
}

//类外实现
void on_getIP(QString ip)
{
    qDebug()<<ip;
}

第三步:在LoginWidget类(旧界面)中关联信号

connect(this,&LoginWidget::sendIPSignal,widget,MainWindow::on_getIP);
//this表示是自己发送信号
//&LoginWidget::sendIPSignal表示发送的是什么信号,LoginWidget是旧界面
//widget是MainWindow *widget定义的对象,就是新界面的对象
//MainWindow::on_getIP表示槽函数,定义在新界面里

第四步:在LoginWidget类(旧界面)中发送自定义信号

//发送名为sendIPSignal的信号,信号有参数
emit sendIPSignal("想要传的数据");

总结

  • 信号和槽中,槽函数的调用是通过信号来完成,所以槽函数的参数类型要跟信号函数的参数类型保持一致,槽的参数个数不大于信号的参数个数
  • 槽函数的调用,必须要跟对应的信号建立连接关系,通过connect函数来实现连接
  • 个信号可以跟多个槽函数相关联
  • 多个信号可以执行同一个槽函数
  • 个信号可以跟另一个信号相关联
  • 使用信号与槽函数机制必须在类的声明中添加Q OBJECT宏,因为只有标记该宏的头文件才能让元对象编译器去处理。

实例  制作一个教务管理系统

教务管理系统需求描述: 教务管理系统,用户可以选择教师或者学生角色进行系统,当教师登录时,可以将教师信息传输到教师界面显示,同时,程序还可以对教师信息可进行修改设置并保存,将保存的信息显示在教师界面。

第一步,新建一个Mainwindow类界面项目,配置ui,修改三个输入框的名字

 

第二步,设置Mainwindow类界面里的教师按钮的点击事件

第三步,新建一个teacherwindow类界面,配置ui界面和按钮点击事件,并在teacherwindow类界面里定义槽函数和自定义信号

//槽函数
public slots:
    void onRecvDataSlot(QString name,QString classes,QString works);
//自定义信号
signals:
    void sendDataSignal(QString name,QString classes,QString works);

第四步,新建一个setwindow类界面,配置ui界面和按钮点击事件,并在setwindow类界面里定义槽函数和自定义信号

//槽函数
public slots:
    void onRecvDataSlot(QString name,QString classes,QString works);
//自定义信号
signals:
    void sendDataSignal(QString name,QString classes,QString works);

第五步,定义Mainwindow类界面要发送的自定义信号和编写按钮点击事件

自定义信号

signals:
    void sendDataSignal(QString name,QString classes,QString works);

教师按钮点击事件

#include <QMessageBox>//弹窗头文件
#include "teacherwindow.h"//教师界面头文件
//教师按钮信号
void MainWindow::on_btn_teacher_clicked()
{
    //1、获取当前界面上输入框的数据
    QString name = ui->lineEdit_name->text();
    QString classes = ui->lineEdit_classes->text();
    QString works = ui->lineEdit_work->text();

    //2、判断数据是否为空,空就弹窗
    if(name.isEmpty() || classes.isEmpty() || works.isEmpty())
    {
        //加入头文件
        //设置弹窗
        QMessageBox::warning(this,"消息","不能为空");
        return;
    }

    //3、创建教师界面对象,并设置退出自动释放
    teacherWindow *teawidget = new teacherWindow(this);
    teawidget->setAttribute(Qt::WA_DeleteOnClose);
    
    //信号在当前界面定义,槽函数在教室界面定义
    //4.1、在教师界面定义槽函数进行关联,
    //this本界面发送
    //&MainWindow::sendDataSignal当前界面定义的信号
    //teawidget接收的界面
    //&teacherWindow::onRecvDataSlot接收界面的槽函数
    connect(this,&MainWindow::sendDataSignal,teawidget,&teacherWindow::onRecvDataSlot);
    //4.2、发送当前界面的数据传输到教师界面,发送sendDataSignal自定义信号,在当前界面定义
    emit sendDataSignal(name,classes,works);

    //5、显示另一个界面
    teawidget->show();

    //6、隐藏当前界面
    this->hide();
}

第六步,编写teacherwindow类界面和setwindow类界面里的槽函数和按钮点击事件

teacherwindow类界面

//头文件
#include <QMessageBox>//弹窗头文件
#include "setwindow.h"//设置界面头文件

//槽函数
void teacherWindow::onRecvDataSlot(QString name, QString classes, QString works)
{
    //将数据显示到输入框里
    ui->lineEdit_name->setText(name);
    ui->lineEdit_classes->setText(classes);
    ui->lineEdit_work->setText(works);
}

//按钮点击事件
void teacherWindow::on_SetButton_clicked()
{
    //1、获取当前界面上的数据
    QString name = ui->lineEdit_name->text();
    QString classes = ui->lineEdit_classes->text();
    QString works = ui->lineEdit_work->text();

    //2、判断数据是否为空,空就弹窗
    if(name.isEmpty() || classes.isEmpty() || works.isEmpty())
    {
        //加入头文件#include <QMessageBox>//弹窗头文件
        //设置弹窗
        QMessageBox::warning(this,"消息","不能为空");
        return;
    }
    //3、创建设置界面对象,并设置退出自动释放
    setWindow *setwidget = new setWindow(this);
    setwidget->setAttribute(Qt::WA_DeleteOnClose);
    //4.1、在设置界面定义槽函数进行关联
    connect
    (
        this,//当前界面发送的数据
        SIGNAL(sendDataSignal(QString,QString,QString)),//用宏来表示发送什么信号
        setwidget,//接收的界面
        SLOT(onRecvDataSlot(QString,QString,QString))//接收界面的槽函数
    );
    //4.2、发送当前界面的数据传输到设置界面,发送sendDataSignal自定义信号,在当前界面定义
    emit sendDataSignal(name,classes,works);
    //5、显示另一个界面
    setwidget->show();
    //6、隐藏当前界面
    this->hide();
}

setwindow类界面

//槽函数
void setWindow::onRecvDataSlot(QString name, QString classes, QString works)
{
    ui->lineEdit_name->setText(name);
    ui->lineEdit_classes->setText(classes);
    ui->lineEdit_work->setText(works);
}

//按钮点击事件,返回上一级或者上上一级的界面
void setWindow::on_SuccessButton_clicked()
{
    //返回教师界面
    //获取教师界面对象
    QWidget *widget = this->parentWidget();
    
    //获取当前界面上的数据
    QString name = ui->lineEdit_name->text();
    QString classes = ui->lineEdit_classes->text();
    QString works = ui->lineEdit_work->text();
    
    //关联 在上一个界面关联返回的信号,写在上一个界面的点击按钮事件里
    //connect(setwidget,&setWindow::sendDataSignal,this,&teacherWindow::onRecvDataSlot);    
    //发送信号
    emit sendDataSignal(name,classes,works);
    widget->show();
    this->close();
    
    //返回第一个界面
    //获取第一个界面对象
//    QWidget *widget1 = this->parentWidget()->parentWidget();
//    widget1->show();
//    this->close();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1381418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++/WinRT 入门

本主题将会根据新的 Windows 控制台应用程序 (C/WinRT) 项目演练一个简单的代码示例。 C/WinRT 快速入门 创建一个新的 Windows 控制台应用程序(C/WinRT) 项目。 根据实际选择平台 如果出现如下错误&#xff0c;需要安装正确的SDK。 找不到 Windows SDK 版本 10.0.17134.0 (o…

Seata TM管理分支事务源码

TM相当于一个中间商&#xff0c;是没有涉及到任何数据库底层操作的。 TransactionalTemplate 1、TM向TC端发起一次开启全局事务的请求 io.seata.tm.api.TransactionalTemplate#beginTransaction --> io.seata.tm.api.DefaultGlobalTransaction#begin(int, java.lang.Strin…

scroll-view在小程序页面里实现滚动,uniapp项目

要实现红框中的区域进行滚动,scroll-view必须写高 <template><!-- 合同-待确认 --><view class"viewport"><!-- 上 --><view class"top-box"><!-- tab --><view class"tabs"><textv-for"(ite…

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力…

Fabric2.2:在有系统通道的情况下搭建应用通道

写在最前 在使用Fabric-SDK-Go1.0.0操作Fabric网络时遇到了bug。Fabric-SDK-GO的当前版本没有办法在没有系统通道的情况下创建应用通道&#xff0c;而Fabric的最新几个版本允许在没有系统通道的情况下搭建应用通道。为了解决这个矛盾并使用Fabric-SDK-GO完成后续的项目开发&…

Hive命令行运行SQL将数据保存到本地如何去除日志信息

1.场景分析 先有需求需要查询hive数仓数据并将结果保存到本地&#xff0c;但是在操作过程中总会有日志信息和表头信息一起保存到本地&#xff0c;不符合业务需要&#xff0c;那如何才能解决该问题呢&#xff1f; 废话不多少&#xff0c;直接上代码介绍&#xff1a; 2.问题解决…

HarmonyOS应用开发学习笔记 arkTS自定义弹窗(CustomDialog)简单使用 arkTS弹出框回调、监听

HarmonyOS应用开发学习笔记 arkTS自定义弹窗&#xff08;CustomDialog&#xff09;简单使用 1、CustomDialog装饰器用于装饰自定义弹框 1、定义弹出框 CustomDialog CustomDialog export struct CustomDialogExample {controller: CustomDialogControllerbuild() {Column() {…

基于反卷积方法的重大突破:结构光系统中的测量误差降低3倍

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 结构光三维测量技术在工业自动化、逆向工程和图形学领域越来越受欢迎。然而&#xff0c;现有的测量系统在成像过程中存在不完美&#xff0c;会导致在不连续边缘周…

Nacos注册中心-安装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、认识Nacos二、安装Nacos1.直接方法nacos.io&#xff0c;点击view onGithub2.点击Releases3、点击Tags&#xff0c;可以看见所有版本&#xff0c;建议下载1.…

Linux 系统编程:文件系统的底层逻辑 - inode

《Linux 程序设计》的第三章讲文件操作。在提到 目录 时有这么一段文字&#xff1a; 文件&#xff0c;除了本身包含的 内容 以外&#xff0c;它还会有一个 名字 和一些 属性&#xff0c;即“管理信息”&#xff0c;包括文件的创建 / 修改日期和它的访问权限。这些属性被保存在文…

【LabVIEW FPGA入门】使用CompactRIO进行SPI和I2C通信

NI提供了 SPI and I2C Driver API&#xff1a;下载SPI and I2C Driver API - NI 该API使用FPGA数字I / O线与SPI或I2C设备进行通信。 选择数字硬件时&#xff0c;要考虑三个选项&#xff1a; NI Single-Board RIO硬件可同时使用SPI和I2C驱动程序。NI 9401 C系列模块与SPI驱动程…

阅读文献-胃癌

写在前面 今天先不阅读肺癌的了&#xff0c;先读一篇胃癌的文章 文献 An individualized stemness-related signature to predict prognosis and immunotherapy responses for gastric cancer using single-cell and bulk tissue transcriptomes IF:4.0 中科院分区:2区 医学…

用通俗易懂的方式讲解:大模型微调方法总结

大家好&#xff0c;今天给大家分享大模型微调方法&#xff1a;LoRA,Adapter,Prefix-tuning&#xff0c;P-tuning&#xff0c;Prompt-tuning。 文末有大模型一系列文章及技术交流方式&#xff0c;传统美德不要忘了&#xff0c;喜欢本文记得收藏、关注、点赞。 文章目录 1、LoRA…

vivado 指定顶部模块和重新排序源

指定顶部模块和重新排序源 文件夹默认情况下&#xff0c;Vivado Design Suite会自动确定设计的顶层添加到的源文件的层次结构和细化、合成和模拟的顺序项目这可以通过右键单击中的“层次更新”设置进行控制“源”窗口的菜单。请参阅中的“源”窗口中的“层次更新”命令Vivado …

AI芯片:神经网络研发加速器、神经网络压缩简化、通用芯片 CPU 加速、专用芯片 GPU 加速

AI芯片&#xff1a; 神经网络研发加速器、神经网络压缩简化、通用芯片 CPU 加速、专用芯片 GPU 加速 神经网络研发加速器神经网络编译器各自实现的神经网络编译器 神经网络加速与压缩&#xff08;算法层面&#xff09;知识蒸馏低秩分解轻量化网络剪枝量化 通用芯片 CPU 加速x86…

PEFT(高效微调)方法一览

PEFT论文解读2019-2023 2019-Adapter Tuning2019-PALs2020-Adapter-Fusion2021-Adapter-Drop2021-Diff-Pruning2021-Prefix-Tuning2021-Prompt-Tuning2021-WARP2021-LoRA2021-P-Tuning2021-P-Tuning-V22022-BitFit2022-MAM-Adpater2022-UniPELT2023-AdaLoRA总结 本文旨在梳理20…

C++标准学习--多线程

在以往多线程的实现的时候&#xff0c;都是自己去亲自创建线程&#xff0c;采用特殊flag 及锁控制线程的运转状态。这无可厚非&#xff0c;但又似乎有重复造轮子的嫌疑。最近发现了一个线程池的轮子&#xff0c;很不错&#xff0c;ZZ一下。 C多线程线程池&#xff08;全详解&a…

计算机体系结构----缓存一致性/多处理机

本文严禁转载&#xff0c;仅供学习使用。参考资料来自中国科学院大学计算机体系结构课程PPT以及《Digital Design and Computer Architecture》、《超标量处理器设计》、同济大学张晨曦教授资料。如有侵权&#xff0c;联系本人修改。 本文衔接上文计算机体系结构----存储系统 …

Leetcode18-算术三元组的数目(2367)

1、题目 给你一个下标从 0 开始、严格递增 的整数数组 nums 和一个正整数 diff 。如果满足下述全部条件&#xff0c;则三元组 (i, j, k) 就是一个 算术三元组 &#xff1a; i < j < k &#xff0c; nums[j] - nums[i] diff 且 nums[k] - nums[j] diff 返回不同 算术三…

【 ATU 随笔记 - Inverter 】PV Inverter 太阳能逆变器市场分析

一、简介 在上一篇的介绍中与大家分享了Micro Inverter ( 微型逆变器 )的用途与特色&#xff0c;也提到 Micro Inverter 适合家庭或是一些小型企业的需求。太阳能作为再生能源的代表&#xff0c;在当今能源转型中扮演着重要角色&#xff0c;也是有大型企业、大型能源站的需求&a…