【问题标题】:Qt4: The best way to access parent class (1 level up, 2 levels up .... )Qt4:访问父类的最佳方式(1 级,2 级......)
【发布时间】:2011-03-25 00:43:50
【问题描述】:

我想知道如何在我的 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 文件中包含它?

感谢您的帮助:)

【问题讨论】:

    标签: c++ oop qt qt4


    【解决方案1】:

    如果你真的需要主窗口,传递 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 中)或任何在更高级别上有意义的抽象或细节级别。这样 MySubSubClass 是通用的,根本不需要了解 MainWindow。它可以在任何其他上下文中重复使用。如果 MySubSubClass 本身包含其他小部件,它可以再次连接到它们的信号。

    【讨论】:

      【解决方案2】:

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

      类似这样的:

      private:
           static MainWindow* _windowInstance
      
      public:
           static MainWindow* windowInstance()
           {
                return _windowInstance;
           }
      

      在大多数情况下,这似乎是最简单的解决方案。现在,您只需在需要访问此对象时包含 mainwindow.h。

      并且不要忘记在构造函数中初始化_windowInstance,像这样;

      _windowInstance = this;
      

      【讨论】:

      • 这是一个非常糟糕的习惯,进入(-1)
      【解决方案3】:

      通过父类,我假设您的意思是父小部件?

      如果您想找到顶级小部件,QWidget::window() 将指向您。使用dynamic_castqobject_cast 将其转换为您的MainWindow 对象。

      如果您想提升任意级别,请使用paerntWidget()

      【讨论】:

        【解决方案4】:

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

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

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

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

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

        有了更多关于你需要对 MainWindow 实例做什么或需要传达什么的信息,你也会得到更好的答案

        【讨论】:

        • 感谢您的回答。我决定使用静态函数方法只是因为在我的项目中只有一个 QMainWindow。但现在我开始看到将应用程序逻辑与窗口实现分开可能会更好。
        【解决方案5】:
        QWidget* parent = this ;
        while (parent -> parentWidget()) parent = parent -> parentWidget() ;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-12
          • 1970-01-01
          • 1970-01-01
          • 2014-07-13
          • 2020-09-10
          • 2017-01-28
          • 2013-07-20
          • 2015-04-23
          相关资源
          最近更新 更多