4
votes

I need a QDialog to send a signal to redraw the main window.
But connect needs an object to connect to.
So I must create each dialog with new and explicitly put a connect() every time.

What I really need is a way of just sending MainWindow::Redraw() from inside any function and having a single connect() inside Mainwindow to receive them.

But you can't make a signal static and dialogs obviously don't inherit from MainWindow.

edit:
Thanks - I don't want to bypass signal/slots. I want to bypass having a main app pointer singleton, like afxGetApp(). But I don't understand how to just send out a signal and have it funnel up (or down?) to mainwindow where I catch it. I was picturing signals/slots as like exceptions

3
You misunderstand how signals/slots work. There is no concept of "catching" unhandled signals as though they were exceptions. Why do you want to avoid using a static method to get back to the main window? In this case it's a lot easier and that's what it's there for...Stu Mackellar
Thanks that was where I was going wrong. I though a signal was more Qt-ish than just a global getApp::redraw()user280760
@Downvoter: Don't downvote just for missing knowledge.Georg Fritzsche

3 Answers

3
votes

Let clients post CustomRedrawEvents to the QCoreApplication.

class CustomRedrawEvent : public QEvent
{
public:
    static Type registeredEventType() { 
        static Type myType 
            = static_cast<QEvent::Type>(QEvent::registerEventType());
        return myType;
    }    

    CustomRedrawEvent() : QEvent(registeredEventType()) {
    }
};

void redrawEvent() {
    QCoreApplication::postEvent(
        QCoreApplication::instance(), 
        new CustomRedrawEvent());
}

Install an event on the CoreApplication instance and connect to the redraw signal:

class CustomRedrawEventFilter : public QObject
{
    Q_OBJECT
public:
    CustomRedrawEventFilter(QObject *const parent) : QObject(parent) {
    }

signals:
    void redraw();

protected:
    bool eventFilter(QObject *obj, QEvent *event) {
        if( event && (event->type()==CustomRedrawEvent::registeredEventType())) {
            emit redraw();
            return true;
        } 
        return QObject::eventFilter(obj, event);
    }
};

//main()
QMainWindow mainWindow;
QCoreApplication *const coreApp = QCoreApplication::instance();
CustomRedrawEventFilter *const eventFilter(new CustomRedrawEventFilter(coreApp));
coreApp->installEventFilter(eventFilter);
mainWindow.connect(eventFilter, SIGNAL(redraw()), SLOT(update()));
1
votes

An easy way to do this would be to simply call repaint() on all of the widgets returned by the static method QApplication::topLevelWidgets(). This avoids the need to use signals and slots.

0
votes

If you are looking to side-step the normal Qt idiom, then you can provide a global pointer to the mainwindow. That ought to give you the functionality you need, if I understand you correctly.