QT进行两个窗口切换,理解信号与槽机制,总结一些点

QT进行两个窗口切换,理解信号与槽机制

主窗口和子窗口进行切换

子窗口头文件

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include <QString>
#include <QPushButton>

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

    // 发送信号函数,用于子窗口返回主窗口
    void sendSlot ();
    // 在子窗口定义一个按钮 B
    QPushButton B;

signals:
    void mysignal ();
    void mysignal (int a, QString str);

};

#endif // SUBWIDGET_H

主窗口头文件

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include "subwidget.h"
// 包含窗口的头文件
#include <QPushButton>

class MainWidget : public QWidget
{
    Q_OBJECT

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

public slots:
    void changeSubWidgets ();
    void changMainWidget ();
    void dubge_data (int a, QString str);

private:
    // 在主窗口定义按钮A1
    QPushButton A1;
	// 定义一个子窗口
    subwidget subw;

};
#endif // MAINWIDGET_H

子窗口函数实现

#include "subwidget.h"
#include <QString>

subwidget::subwidget(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("子窗口");
    this->resize(500, 500);

    B.setParent(this);
    B.setText("切换至主窗口");
    B.move(100, 100);

    connect (&B, &QPushButton::released, this, &subwidget::sendSlot);
}

void subwidget::sendSlot ()
{
    emit mysignal ();
    emit mysignal(250, "我是子窗口");
}

主窗口函数实现

#include "mainwidget.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    // 设置主窗口的大小
    this->resize(600, 600);
    // 设置主窗口的标题
    this->setWindowTitle("主窗口");

    A1.setParent(this);
    // 设置按钮标题
    A1.setText("切换至子窗口");
    A1.move(100, 100);

    // 切换到子窗口
    connect (&A1, &QPushButton::released, this, &MainWidget::changeSubWidgets);

    // 切换到主窗口
   // void (subwidget::*p1)() = &subwidget::mysignal;
   // connect (&subw, p1, this, &MainWidget::changMainWidget);

    //
    //void (subwidget::*p2)(int, QString) = &subwidget::mysignal;
    //connect (&subw, p2, this, &MainWidget::dubge_data);

    // 信号槽的调用方式2
    connect (&subw, SIGNAL(mysignal()), this, SLOT(changMainWidget ()));
    connect (&subw, SIGNAL(mysignal(int, QString)), this, SLOT(dubge_data()));
    // 但是这样的方式不太好,是QT4的语法,比较容易出错,是因为这样做如果将信号名写错,编译
    // 阶段不会报错,只有运行阶段才能进行报错


}

MainWidget::~MainWidget()
{
}

void MainWidget::changeSubWidgets()
{
    // 让子窗口出来
    subw.show();
    // 让主窗口退出
    this->hide();
}

void MainWidget::changMainWidget ()
{
    // 让主窗口出来
    this->show();
    // 让子窗口退出
    subw.hide();
}

void MainWidget::dubge_data (int a, QString str)
{
    // 打印
    qDebug () << a << endl << str << endl;
}

主函数:

#include "mainwidget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w;
    w.show();
    return a.exec();
}

总结:
(1)两个窗口进行切换,主窗口包含子窗口。
(2)主窗口上边有一个切换至子窗口的按钮,直接在主窗口写信号与槽函数就可以实现主窗口切换到子窗口了。
(3)子窗口要想切换回主窗口,直接写信号与槽函数是不行的,因为主窗口包含子窗口,但是子窗口没有包含主窗口。因此,直接写connect函数行不通,因此要用到信号函数

因此,在子窗口写信号函数 signals:
void mysignal ();
void mysignal (int a, QString str);
并且写一个发送信号函数:
void sendSlot ();
在子窗口函数实现模块将 sendSlot(); 函数写出来
sendSlot()
{
emit mysignal ();
emit mysignal(250, “我是子窗口”); // 这里写这个的目的是为了后边讨论信号函数重载
}

该怎么用?
(1)想要让子窗口切换会主窗口,肯定是将切换至主窗口的按钮点击一下,才会切换至主窗口。
因此,要在子窗口中写一个connect()信号与槽函数
所以
connect (&B, &QPushButton::released, this, &subwidget::sendSlot);
这个函数,就表示,B按钮发信号,子窗口接这个信号,完了调用sendSlot这个函数

(2)调用sendSlot函数之后,就产生一个信号,而这个信号让主窗口来接,在主窗口写一个connect信号与槽函数来接受这个信号,再进行窗口切换

(3)在主窗口当中:
connect (&subw, &subwidget::mysignal, this, &MainWidget::changeSubWidgets);

意思是子窗口发送mysignal信号,主窗口来接,调用changeSubWiagets函数,进行窗口切换

(4)总结:
子窗口不能直接写一个connect信号与槽函数,因为子窗口中没有包含主窗口,而是被包含,因此,需要借助信号来实现信号传递到主函数,然后进行窗口的切换。

信号与槽

// 切换到主窗口
void (subwidget::*p1)() = &subwidget::mysignal;
connect (&subw, p1, this, &MainWidget::changMainWidget);

// 打印输出
void (subwidget::*p2)(int, QString) = &subwidget::mysignal;
connect (&subw, p2, this, &MainWidget::dubge_data);

// 信号槽的调用方式2
connect (&subw, SIGNAL(mysignal()), this, SLOT(changMainWidget ()));
connect (&subw, SIGNAL(mysignal(int, QString)), this, SLOT(dubge_data()));
// 但是这样的方式不太好,是QT4的语法,比较容易出错,是因为这样做如果将信号名写错,编译
// 阶段不会报错,只有运行阶段才能进行报错

上边两种方式,是利用函数指针来解决信号函数二义性的问题
下边两行是采用QT4的语法来进行解决
但是一般采用上边的方式比下边这两行的要好。因为下边这两行如果信号函数名写错了,在编译阶段不会被发现,这样是不太好的。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值