C++ Qt4:访问父类的最佳方式(向上1级,向上2级…)

C++ Qt4:访问父类的最佳方式(向上1级,向上2级…),c++,oop,qt,qt4,C++,Oop,Qt,Qt4,我想知道如何在我的Qt应用程序中访问父类。 假设我的项目具有以下结构: mainWindow: MainWindow tabWidget: QTabWidget tab1: MySubClass1 tab2: MySubClass2 tabWidget: QTabWidget xtab1: MySubSubClass1 xtab2: MySubSubClass2 它有

我想知道如何在我的Qt应用程序中访问父类。 假设我的项目具有以下结构:

mainWindow: MainWindow
    tabWidget: QTabWidget
        tab1: MySubClass1
        tab2: MySubClass2
            tabWidget: QTabWidget
                xtab1: MySubSubClass1
                xtab2: MySubSubClass2
它有点简化。 我想做的是从xtab2插槽函数之一访问mainWindows对象

(1) 最好的方法是什么? 我试图沿着树传递指向mainWindow的指针,但出现运行时错误

(2) 我应该在xtab.h文件中包含mainwindow.h,还是应该在xtab.cpp文件中包含mainwindow.h


感谢您的帮助:)

您可以在MainWindow中创建一个静态方法和对象,该方法和对象将返回MainWindow对象

大概是这样的:

private:
     static MainWindow* _windowInstance

public:
     static MainWindow* windowInstance()
     {
          return _windowInstance;
     }
在大多数情况下,这似乎是最简单的解决方案。现在,只要在需要访问此对象时包含mainwindow.h即可

不要忘记在构造函数中初始化_windowInstance,如下所示

_windowInstance = this;

您可以在MainWindow内创建一个静态方法和对象,该方法和对象将返回MainWindow对象

大概是这样的:

private:
     static MainWindow* _windowInstance

public:
     static MainWindow* windowInstance()
     {
          return _windowInstance;
     }
在大多数情况下,这似乎是最简单的解决方案。现在,只要在需要访问此对象时包含mainwindow.h即可

不要忘记在构造函数中初始化_windowInstance,如下所示

_windowInstance = this;

关于父类,我想你指的是父窗口小部件

如果您想找到顶级小部件,将指向它。使用
dynamic\u cast
或将其转换为主窗口对象


如果你想升级到任意级别,可以按父类使用。

,我想你指的是父窗口小部件

如果您想找到顶级小部件,将指向它。使用
dynamic\u cast
或将其转换为主窗口对象


如果您想升级到任意级别,请使用。

如果您确实需要mainwindow,传递mainwindow指针是最好的方法。静态方法的缺点是它将停止使用多个主窗口

我建议避免从包含的小部件访问主窗口,而是使用信号。例如:

class MainWindow {
    public:
        explicit MainWindow( QWidget* parent=0 ) {
            tab = new TabWidget;
            ...
            MySubSubClass1* ssw1 = new MySubSubClass;
            connect( ssw1, SIGNAL(textChanged(QString)), this, SLOT(page1TextChanged(QString));
            tab->addWidget( ssw1 );
        }

   private Q_SLOTS:
         void page1TextChanged( const QString& ) {
             //do something...
         }  
};

然后,MySubSubClass1会发出textChanged()、addresseeChanged()(例如在Addressbook中),或更高级别上有意义的任何抽象或细节级别。这样,mySubClass是通用的,根本不需要了解MainWindow。它可以在任何其他上下文中重用。如果mySubclass本身包含其他小部件,它可以再次连接到它们的信号。

如果您确实需要mainwindow,传递mainwindow指针是最好的方法。静态方法的缺点是它将停止使用多个主窗口

QWidget* parent = this ;
while (parent -> parentWidget()) parent = parent -> parentWidget() ;
我建议避免从包含的小部件访问主窗口,而是使用信号。例如:

class MainWindow {
    public:
        explicit MainWindow( QWidget* parent=0 ) {
            tab = new TabWidget;
            ...
            MySubSubClass1* ssw1 = new MySubSubClass;
            connect( ssw1, SIGNAL(textChanged(QString)), this, SLOT(page1TextChanged(QString));
            tab->addWidget( ssw1 );
        }

   private Q_SLOTS:
         void page1TextChanged( const QString& ) {
             //do something...
         }  
};

然后,MySubSubClass1会发出textChanged()、addresseeChanged()(例如在Addressbook中),或更高级别上有意义的任何抽象或细节级别。这样,mySubClass是通用的,根本不需要了解MainWindow。它可以在任何其他上下文中重用。如果mySubclass本身包含其他小部件,它可以再次连接到它们的信号。

这个问题有多种不同的解决方案,您选择的解决方案是面向对象和封装,这是最糟糕的解决方案之一。一些想法

QWidget* parent = this ;
while (parent -> parentWidget()) parent = parent -> parentWidget() ;
  • 封装:如果您发现自己必须提供跨越一段距离的访问权限(沿着一长串容器或子类),那么您可能需要查看您试图分发的功能。我可能认为它应该单独封装在一个类中,这个类可以比它当前所在的位置(您的案例中的主窗口)更容易传递

  • 抽象:除非您需要访问QMainWindow的实际功能,否则不要传递指向
    MainWindow
    类的指针,为您需要的功能创建一个接口,让您的MainWindow实现该接口,并传递接口类型的对象,而不是您的MainWindow类型

  • 信号和插槽:正如Frank所指出的,使用Qt的信号机制实现适当的功能,这使得调用者和被调用者之间的连接成为动态连接,再次将其与实际的MainWindow类分离

  • QApplication:如果您必须让全局信息限制入口点,那么您已经有一个单一的QApplication对象,使其成为需要全局访问的所有其他对象的维护者,派生您自己的QApplication类并在其中维护全局引用。然后,QApplication类可以创建或销毁所需的全局对象


有了关于您需要对MainWindow实例执行什么操作或需要传达什么内容的更多信息,您也会得到更好的答案

这个问题有多种不同的解决方案,您选择的解决方案是面向对象和封装,其中一种更糟糕。一些想法

  • 封装:如果您发现自己必须提供跨越一段距离的访问权限(沿着一长串容器或子类),那么您可能需要查看您试图分发的功能。我可能认为它应该单独封装在一个类中,这个类可以比它当前所在的位置(您的案例中的主窗口)更容易传递

  • 抽象:除非您需要访问QMainWindow的实际功能,否则不要传递指向
    MainWindow
    类的指针,为您需要的功能创建一个接口,让您的MainWindow实现该接口,并传递接口类型的对象,而不是您的MainWindow类型

  • 信号和插槽:正如Frank指出的,使用Qt的信号机制实现适当的功能,这使得连接