如何在 Qt 中将消息从子窗口小部件发送到父窗口?

Posted

技术标签:

【中文标题】如何在 Qt 中将消息从子窗口小部件发送到父窗口?【英文标题】:How to send message from child widget to parent window in Qt? 【发布时间】:2020-03-12 21:57:42 【问题描述】:

如何在 qt 中将消息从子窗口小部件发送到父窗口? 我尝试将信号从子小部件发送到 qt 中的父窗口。当我在 subwidget.cpp 中调用函数测试时,会发送信号但主窗口插槽不执行。如何发送消息?

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QStackedWidget>
#include <QPushButton>
#include <QProcess>
#include <QDebug>
#include <subwidget.h>

QT_BEGIN_NAMESPACE
namespace Ui  class MainWindow; 
QT_END_NAMESPACE

class MainWindow : public QMainWindow

   Q_OBJECT

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

   private:
       Ui::MainWindow *ui;
       QStackedWidget *stack;
       QPushButton *start_btn;
       SubWidget *f2;

   private slots:
       void StartApplication();
       void ReceiveCustomMessage(const QString &msg);

;
#endif // MAINWINDOW_H

subwidget.h

#define SUBWIDGET_H

#include <QWidget>

namespace Ui 
class SubWidget;


class SubWidget : public QWidget

    Q_OBJECT

public:
    explicit SubWidget(QWidget *parent);
    ~SubWidget();
    void test();

private:
    Ui::SubWidget *ui;

signals:
    void SendCustomMessage(const QString& msg);
;

#endif // SUBWIDGET_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
// #include <formcustomnew.h>
#include <subwidget.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

    ui->setupUi(this);
    stack = MainWindow::findChild<QStackedWidget *>("stackedWidget");
    start_btn = MainWindow::findChild<QPushButton *>("start_btn");
    stack->setCurrentIndex(0);
    connect(start_btn,SIGNAL(released()),this,SLOT(StartApplication()));
    f2 = new SubWidget(this);
    //connect(f2,SIGNAL(SendCustomMessage(QString)),this,SLOT(ReceiveCustomMessage(QString)));
    //f2->test();
    //auto f1 = new FormCustomNew(this);
    //connect(f1,SIGNAL(sendMessageNewMessage(QString)),this,SLOT(receiveMessage(QString)));
    //f1->test();


MainWindow::~MainWindow()

    delete ui;


void MainWindow::StartApplication()
    //check_adb_exists();
    f2->test();


void MainWindow::ReceiveCustomMessage(const QString &msg)
    qDebug("Recieved message from child");
    qDebug("Message: " + msg.toLatin1());


void MainWindow::check_adb_exists()
    QProcess *p = new QProcess();
    connect(p,&QProcess::readyReadStandardOutput,[&]()
        auto data = p->readAllStandardOutput();
        qDebug("Stdout: " + data);
    );
    connect(p,&QProcess::readyReadStandardError,[&]()
        auto data = p->readAllStandardError();
        qDebug("Error: " + data);
        if(data.toStdString().compare("File Not Found"))
            qDebug("File Not Found is the error");
        
    );
    QStringList args;
    args << "/c dir C:\\Users\\%USERNAME%\\AppData\\Local\\android\\Sdk";
    p->setArguments(args);
    p->setProgram("C:\\Windows\\System32\\cmd.exe");
    p->start();


subwidget.cpp

#include "subwidget.h"
#include "ui_subwidget.h"

SubWidget::SubWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SubWidget)

    ui->setupUi(this);
    qDebug("parent: " + parent->objectName().toLatin1());
    connect(this,SIGNAL(SendCustomMessage(QString)),parent,SLOT(ReceiveCustomMessage(QString)));


SubWidget::~SubWidget()

    delete ui;


void SubWidget::test()
    emit SendCustomMessage("trial message");


void SubWidget::SendCustomMessage(const QString &msg)
    qDebug("Sending Message: " + msg.toLatin1());


【问题讨论】:

【参考方案1】:

信号不能在 Qt 中定义。

来自 Qt wiki 关于 Signal & Slots:

信号由 moc 自动生成,不得在 .cpp 文件中实现

删除您的实现,这应该可以工作。但是,您不应该在subclass 中绑定信号,因为这会降低封装性和可重用性(父级必须有ReceiveCustomMessage(QString) 插槽)。而是将其绑定到外部,就像您在注释掉的代码中所做的那样。

【讨论】:

谢谢。我从 cpp 文件中删除了信号的定义,并将连接更改回窗口类并且它起作用了。

以上是关于如何在 Qt 中将消息从子窗口小部件发送到父窗口?的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应中将数组从子组件发送到父组件?

如何在Qt中将点击事件传递给下面的兄弟?

在不关闭子窗口的情况下从子窗口返回焦点到父窗口(在mfc visual studio中)

Java SWing中如何通过双击使子对话框从父窗口中弹出并嵌入到父窗口中?

QT:如何关闭同一个小部件的多个窗口?

如何在 Qt Creator 的主窗口中添加自定义小部件