【问题标题】:How to call to non-static parent function from within child function in Qt/C++?如何从 Qt/C++ 的子函数中调用非静态父函数?
【发布时间】:2016-04-20 18:10:08
【问题描述】:

我很难理解如何将父对象传递给子对象。 在 Qt 中,我有一个 MainWindow 类和一个 DoSomething() 函数。然后我在 MainWindow 中创建了一个 Job 对象,并尝试在 Job 的 DoItNow() 函数中调用 DoSomething。但我就是不知道该怎么做。

MainWindow.h

class Job;
class MainWindow : public QMainWindow
{
  Q_OBJECT

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

    int value;
    void DoSomething();

  private:
  Job *job;
}

MainWindow.cpp

#include "mainwindow.h"
#include "job.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    job = new Job(this);   // passing this pointer to child
}

void MainWindow::DoSomething() {  // do something }

工作.h

class Job : public QObject
{
  Q_OBJECT

  private:
    void DoItNow();

  public:
    explicit CDMcommand(QObject *parent = 0);
}

Job.cpp

#include "job.h"
#include "mainwindow.h"

Job::Job(QObject *parent) : QObject(parent)
{
  // some setups
  parent->value = 0;    // this is not working
}

void Job::DoItNow()
{
  parent->DoSomething();  // What is the pointer to MainWindow instance?
}
  • 如何访问 *parent 中的非静态公共寄存器?

  • 如何将 *parent 传递给作业实例中的函数?

【问题讨论】:

  • Qt 中,您通常使用信号和插槽来执行此操作。
  • c# 跟这个问题有什么关系?
  • QObject 没有名为“value”的公共字段,也没有名为“DoSomething”的方法。这些是您在 MainWindow 类中定义的内容。要访问它们,必须将“父级”声明为 MainWindow 的实例,而不是 QObject。
  • 也许我应该重新表述我的问题。我想在 MainWindow 中创建一个对象 Job 并且通过 Job 的一个函数来调用 MainWindow 的函数。这样做的正确方法是什么?

标签: c++ qt qt4


【解决方案1】:

也许我误解了这个问题,但我认为您对继承有点困惑。您的JobQObject 的子类,MainWindow 也间接继承自QObject,但MainWindowJob 之间没有直接关系。我对Qts的信号槽机制不是很熟悉,这里大概是走的路,但也许我可以为你提供一个不同的解决方案:

Job::Job(QObject *parent) : QObject(parent)
{
  // some setups
  parent->value = 0;    // this is not working
}

这不起作用,因为QObject 没有名为value 的成员。如果您可以使用 Jobs 构造函数而不以 QObject* 作为参数,那么只需声明一个

MainWindow* parentWindow;

作为Job 中的私有成员并将构造函数更改为

Job::Job(MainWindow *parentWindow) : QObject(parentWindow)
{
  // some setups
  parentWindow->value = 0;    // this will work now
}

然后也

void Job::DoItNow()
{
  parentWindow->DoSomething();  
}

可以正常工作。

【讨论】:

  • 那是全局变量方式? parentWindow 在一个块中是一个参数,在另一个块中是一个全局变量。没有办法通过严格的代码审查。
  • @AlexanderVX 没有全局变量。如果你仔细阅读,我建议在Job 类中声明parentWindow inside。但是我会编辑以消除任何歧义
【解决方案2】:

如何从“子”调用 Qt“父”对象方法 对象方法?

安全又简单的方法:

void Job::DoItNow()
{
   // first evaluate the pointer: is that of type we expect?
   MainWindow* pMainWindow = qobject_cast<MainWindow*>(parent());
   if (pMainWindow)
       pMainWindow->DoSomething();  // MainWindow::DoSomething must be exposed to class Job
}

当然,让两个类相互依赖太多是违反 OOP 原则的:这两个对象现在变得紧密耦合。在 cmets 中已经有一个很好的建议:为此使用显式的信号槽机制或提供接口以在解耦对象之间进行交互。

【讨论】:

  • 也许我应该重新提出我的问题。我想在 MainWindow 中创建一个对象 Job 并且通过 Job 的一个函数来调用 MainWindow 的函数。这样做的正确方法是什么?
  • 我发布的那个。但仍然考虑信号槽。我们两者都做。我们做我懒惰时发布的那个。
猜你喜欢
  • 2011-10-04
  • 1970-01-01
  • 2022-01-13
  • 2011-09-08
  • 1970-01-01
  • 2011-07-18
相关资源
最近更新 更多