You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QT Creator中如何将子窗口变量传递给生成它的父类

解决QT子窗口bar向父窗口foo传递浮点数值的问题

先修正原代码中的基础语法错误,再提供两种可行的数据传递方案:

一、原代码中的关键语法错误修正

  • foo_ui.h中varsToUpdate结构体定义末尾缺少分号,且Qstring应为QString(QT类名大小写敏感)
  • bar_ui.h中构造函数声明与bar_ui.cpp中的定义不匹配(声明无foo*参数,定义却添加了该参数)
  • bar_ui.cpp中ui->lineEdit_B-userData>setText是笔误,应为ui->lineEdit_B->setText
  • bar类未声明sig_UserDataUpdateBox信号和sl_UserDataUpdateBox槽函数,直接使用会触发编译错误
  • foo_ui.cpp中ClassB应为bar,且未定义returnedFloatValue变量,VarsToUpdate大小写与结构体定义不符

二、方案一:使用QT信号槽机制(推荐)

信号槽是QT组件通信的标准方式,耦合度低,符合QT设计理念。

1. 修改bar_ui.h,声明传递数据的信号

namespace Ui {
class bar;
}

class bar : public QWidget
{
    Q_OBJECT

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

// 声明传递配置数据的信号,参数对应两个浮点值
signals:
    void sendConfigData(float A, float B);

private slots:
    void on_btnSaveBar_clicked();
    void on_btnClose_clicked();

private:
    Ui::bar *ui;
    typedef struct {
        float A;
        float B;
    } userData;
};

2. 修改bar_ui.cpp,触发信号传递数据

#include "bar_ui.h"
#include "ui_bar_ui.h"

bar::bar(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::bar)
{
    ui->setupUi(this);
    ui->lineEdit_A->setText("0.0000");
    ui->lineEdit_B->setText("0.0000");
}

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

void bar::on_btnClose_clicked()
{
    this->close();
}

void bar::on_btnSaveBar_clicked()
{
    userData userdata;
    userdata.A = ui->lineEdit_A->text().toFloat();
    userdata.B = ui->lineEdit_B->text().toFloat();

    // 发送信号,将输入的浮点值传递给父窗口
    emit sendConfigData(userdata.A, userdata.B);
    this->close();
}

3. 修改foo_ui.h,声明接收数据的槽函数

#include "bar_ui.h"
namespace Ui {
class foo;
}

class foo : public QFrame
{
    Q_OBJECT

public:
    explicit foo(QWidget *parent = 0, instrument_class *instrument=0);
    ~foo();

private slots:
    void on_btnSaveFoo_clicked();
    // 声明接收数据的槽函数,参数类型与信号严格匹配
    void receiveConfigData(float A, float B);

private:
    Ui::foo *ui;
    struct varsToUpdate{
        float A;
        float B;
        QString D;
        int F;
    } m_vars; // 定义结构体实例,用于存储配置数据
};

4. 修改foo_ui.cpp,连接信号槽并处理数据

#include "foo_ui.h"
#include "ui_foo_ui.h"

foo::foo(QWidget *parent, instrument_class *instrument) :
    QFrame(parent),
    ui(new Ui::foo)
{
    ui->setupUi(this);
}

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

void foo::on_btnSaveFoo_clicked()
{
    bar *barWin = new bar(this);
    // 连接子窗口的信号与当前类的槽函数
    connect(barWin, &bar::sendConfigData, this, &foo::receiveConfigData);
    // 设置窗口关闭时自动销毁,避免内存泄漏
    barWin->setAttribute(Qt::WA_DeleteOnClose);
    barWin->show();
}

void foo::receiveConfigData(float A, float B)
{
    // 将接收到的数据保存到foo的结构体中
    m_vars.A = A;
    m_vars.B = B;
    // 可在此添加其他逻辑,比如更新UI或同步到设备
}

三、方案二:传递foo指针直接修改数据

若需直接在bar中操作foo的变量,可修改bar构造函数传入foo指针,通过setter方法更新数据(避免直接暴露私有成员)。

1. 修改foo_ui.h,添加setter方法

namespace Ui {
class foo;
}

class foo : public QFrame
{
    Q_OBJECT

public:
    explicit foo(QWidget *parent = 0, instrument_class *instrument=0);
    ~foo();
    // 添加setter方法,用于外部修改内部配置变量
    void setConfigVars(float A, float B) {
        m_vars.A = A;
        m_vars.B = B;
    }

private slots:
    void on_btnSaveFoo_clicked();

private:
    Ui::foo *ui;
    struct varsToUpdate{
        float A;
        float B;
        QString D;
        int F;
    } m_vars;
};

2. 修改bar_ui.h,构造函数接收foo指针

#include "foo_ui.h"
namespace Ui {
class bar;
}

class bar : public QWidget
{
    Q_OBJECT

public:
    // 修改构造函数,添加foo指针参数
    explicit bar(foo *fooObj, QWidget *parent = nullptr);
    ~bar();

private slots:
    void on_btnSaveBar_clicked();
    void on_btnClose_clicked();

private:
    Ui::bar *ui;
    foo *m_fooObj; // 保存foo类指针
    typedef struct {
        float A;
        float B;
    } userData;
};

3. 修改bar_ui.cpp,调用foo的setter方法

#include "bar_ui.h"
#include "ui_bar_ui.h"

bar::bar(foo *fooObj, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::bar),
    m_fooObj(fooObj) // 初始化foo指针
{
    ui->setupUi(this);
    ui->lineEdit_A->setText("0.0000");
    ui->lineEdit_B->setText("0.0000");
}

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

void bar::on_btnClose_clicked()
{
    this->close();
}

void bar::on_btnSaveBar_clicked()
{
    userData userdata;
    userdata.A = ui->lineEdit_A->text().toFloat();
    userdata.B = ui->lineEdit_B->text().toFloat();

    // 调用foo的setter方法保存数据
    if(m_fooObj) {
        m_fooObj->setConfigVars(userdata.A, userdata.B);
    }
    this->close();
}

4. 修改foo_ui.cpp,创建bar时传入自身指针

#include "foo_ui.h"
#include "ui_foo_ui.h"

foo::foo(QWidget *parent, instrument_class *instrument) :
    QFrame(parent),
    ui(new Ui::foo)
{
    ui->setupUi(this);
}

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

void foo::on_btnSaveFoo_clicked()
{
    bar *barWin = new bar(this, this); // 传入foo自身指针
    barWin->setAttribute(Qt::WA_DeleteOnClose);
    barWin->show();
}

关键注意事项

  • 所有使用Q_OBJECT宏的类,必须确保项目正确运行QT的MOC工具(Qt Creator中自动处理,手动编译需执行moc命令)
  • 信号槽的参数类型必须严格匹配,否则会触发编译或运行时错误
  • 使用Qt::WA_DeleteOnClose属性可自动销毁关闭的窗口,避免内存泄漏

内容的提问来源于stack exchange,提问作者jabroni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:55:04