views:

141

answers:

1

I can set the parent's status bar text with this function I wrote

void EditorWindow::setStatusBarText(const QString& text) {
    statusBar()->showMessage(text);
}

Called like this (from child)

((EditorWindow*) parent())->setStatusBarText(tr("%1, %2").arg(mousePos.x(), 0, 'f', 2).arg(mousePos.y(), 0, 'f', 2));

But I'm pretty sure that breaks a few design principles. For instance, what if parent() is not an EditorWindow*?

So what's the workaround for this? Force the user to pass a reference to an EditorWindow upon creation to ensure parent is of the correct type?

+5  A: 

Use signals and slots;

Make EditorWindow::setStatusBarText a slot. Give the child a signal when it wants to change status, and connect that to the setStatusBarText slot.

// make setStatusBarText a slot...
class EditorWindow : public QWidget {
    Q_OBJECT
    ...
    public slots:
        void setStatusBarText(const QString&);
}

// make a signal to be emitted when status should change:
class SomeChildWidget : public QWidget {
    Q_OBJECT
    ...
    signals:
        void statusEvent(const QString&);
}

// connect them up when appropriate
EditorWindow::EditorWindow()
 : QWidget()
{
    ...
    m_childWidget = new SomeChildWidget(this);
    connect(m_childWidget, SIGNAL(statusEvent(QString)),
            this,          SLOT(setStatusBarText(QString)));
    ...
}

Then the child would emit statusEvent(somestring) when the status should be updated.

This scales well, you can have as many child widgets as you like with the ability to change the status text, they don't know anything about their parent widget, and you can implement a policy in the parent widget for accepting or refusing status updates from child widgets.

Intransigent Parsnip
Oh! I was just starting to think about signals/slots but I had it backwards in my head. I can connect it in the parent and that alleviates the problem. Brilliant! Thanks :)
Mark
You don't actually need the setStatusBarText function, you can use showMessage directly: connect(editorView, SIGNAL(statusBarUpdate(QString)), statusBar(), SLOT(showMessage(QString)));
Mark