Использование родительского указателя Qt4

У меня возникли проблемы с пониманием использования указателя parent в QT4.

class firstClass : public QWidget
{
    Q_OBJECT

public:
     firstClass(QWidget *parent = 0);
    ~firstClass();

    void doSomething();

private:
    secondClass * myClass;
};

class secondClass : public QWidget
{
    Q_OBJECT

public:
    secondClass(QWidget *parent = 0);
    void doSomethingElse();
};

Я хочу вызвать метод doSomething() во время работы doSomethingElse(). Есть ли способ сделать это с помощью указателя parent?

Я пробовал parent->doSomething(), но это не работает. Кажется, что Qt Creator предлагает только методы из класса QObject после parent->.

С другой стороны, я не могу написать это как secondClass(firstClass *parent = 0); - компилятор возвращает ошибку:

Спасибо за любые предложения.


person Moomin    schedule 18.02.2010    source источник
comment
Пока определение firstClass включено перед определением secondClass, ваше определение альтернативного конструктора должно скомпилироваться: secondClass::secondClass(firstClass *parent = 0) : QWidget(parent) { } Какую ошибку компилятора вы получаете?   -  person Gareth Stockwell    schedule 19.02.2010
comment
Я не понимаю, почему компилятор не позволяет передать указатель firstClass в конструктор secondClass.   -  person Caleb Huitt - cjhuitt    schedule 19.02.2010
comment
Оба класса определены в разных файлах, и я получаю сообщение об ошибке от secondClass.h - firstClass не был объявлен (то же самое с #include firstClass.h и без него)   -  person Moomin    schedule 19.02.2010
comment
Для меня это указывает на другую проблему где-то - возможно, включенные охранники одинаковы? Кроме того, он потенциально может быть предварительно объявлен в заголовочном файле.   -  person Caleb Huitt - cjhuitt    schedule 19.02.2010


Ответы (2)


Если вы уверены, что родителем secondClass всегда будет firstClass, вы можете сделать это:

static_cast<firstClass *>(parent)->doSomething();

В качестве альтернативы вы можете использовать qobject_cast и убедиться, что parent действительно является экземпляром firstClass:

firstClass *myParent = qobject_cast<firstClass *>(parent);
if(myParent){
    myParent->doSomething();
}
person Kyle Lutz    schedule 18.02.2010
comment
Символ «родительский» должен быть заменен вызовом либо parentWidget(), либо parent(), чтобы этот код скомпилировался. Это связано с тем, что «родительский» действителен только в области действия конструктора, а вопрос спрашивает, как вызвать doSomething() из secondClass::doSomethingElse(). - person Gareth Stockwell; 19.02.2010

Более похожим на Qt способом сделать это было бы использование сигналов и слотов вместо того, чтобы пытаться напрямую вызывать другую функцию.

class firstClass : public QWidget
{
    Q_OBJECT

public:
     firstClass(QWidget *parent = 0);
    ~firstClass();

public slot:
    void doSomething();

private:
    secondClass * myClass;
};

class secondClass : public QWidget
{
    Q_OBJECT

public:
    secondClass(QWidget *parent = 0);
    void doSomethingElse()
    {
        // ...
        emit ( triggerDoSomething() );
        // ...
    }

signal:
    void triggerDoSomething();
};

firstClass::firstClass(QWidget *parent) : 
    QWidget(parent), myClass(new secondClass(this))
{
    // ...
    bool connected = connect(myClass, SIGNAL(triggerDoSomething()),
        SLOT(doSomething()));
    assert( connected );
}
person Caleb Huitt - cjhuitt    schedule 19.02.2010