user660975
user660975

Reputation:

Qt4: The best way to access parent class (1 level up, 2 levels up .... )

I'm wondering how to access parent class in my Qt application. Lets say my project has following structure:

mainWindow: MainWindow
    tabWidget: QTabWidget
        tab1: MySubClass1
        tab2: MySubClass2
            tabWidget: QTabWidget
                xtab1: MySubSubClass1
                xtab2: MySubSubClass2

It is a little simplified. What I want to do is to access mainWindows object from one of xtab2 slot functions.

(1) What would be the best method ? I tried to pass the pointer to mainWindow along the tree but I get runtime errors.

(2) Should I include mainwindow.h in xtab.h file or should I do it in xtab.cpp file ?

Thanks for help :)

Upvotes: 1

Views: 918

Answers (5)

Harald Scheirich
Harald Scheirich

Reputation: 9764

There are a variety of different solutions to this problem, the one you chose as the answer is in terms of object orientation and encapsulation one of the worse ones. Some thoughts

  • Encapsulation: if you find yourself having to provide access accross a large distance in relation (down a long chain of containers or subclasses) you might want to look at the functionality that you are trying to distribute. I might be that it should be encapsulated in a class by itself that can passed around easier than where it is currently located (the main window in your case).

  • Abstraction: Unless it is actually functionality of QMainWindow that you need to access don't pass a pointer to your MainWindow class, create an interface for the functionality that you need, have your MainWindow implement that interface and pass around and object of the interface type instead of your MainWindow type.

  • Signals and Slots: As Frank noted, implement the appropriate functionality using Qt's signalling mechanism, this makes the connection between the caller and callee into a dynamic one, again separating it from the actual MainWindow class

  • QApplication: If you absolutely have to have global information restrict the entry point, you already have one singleton the QApplication object, make it the maintainer of all the other objects that need to be globally accessible, derive your own QApplication class and maintain global references in there. Your QApplication class can then create or destroy the needed global objects.

With more information about what you need to do with the MainWindow instance or what needs to be communicated you will also get better answers

Upvotes: 1

Stephen Chu
Stephen Chu

Reputation: 12832

By parent class, I assume you mean parent widget?

If you want to find the top level widget, QWidget::window() will point you to it. Use dynamic_cast or qobject_cast to turn it into your MainWindow object.

If you want to go up some arbitrary level, use paerntWidget().

Upvotes: 1

TonyK
TonyK

Reputation: 17114

QWidget* parent = this ;
while (parent -> parentWidget()) parent = parent -> parentWidget() ;

Upvotes: 0

Frank Osterfeld
Frank Osterfeld

Reputation: 25155

If you really need the mainwindow, passing the MainWindow pointer is the best way to do it. A static method has the drawback that it will stop working with more than one mainwindow.

I would suggest to avoid accessing the mainwindow from the contained widgets though and use signals instead. E.g.:

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 then emits textChanged(), addresseeChanged() (e.g. in Addressbook), or whatever level of abstraction or detail makes sense on the higher level. That way MySubSubClass is generic and doesn't have to know about MainWindow at all. It can be reused in any other context. If MySubSubClass itself contains other widgets, it can again connect to their signals.

Upvotes: 3

Sebastian Dusza
Sebastian Dusza

Reputation: 2528

You could create a static method and object inside MainWindow that would return mainwindow object.

Something like this:

private:
     static MainWindow* _windowInstance

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

This seems to be the simples solution in most cases. Now you just have to include mainwindow.h whenever you need to access this object.

And don't forget to initialize _windowInstance in the contructor, like this;

_windowInstance = this;

Upvotes: 2

Related Questions