PDA

View Full Version : QAbstractEventDispatcher for external event loop integration



vkincaid
28th August 2009, 22:11
I'm writing an application, which has already it's own main event loop that calls other libraries. Now I want to use Qt as a widget library, and am trying to setup the Qt library for being capable to be called from my own main loop.

After doing some research, I think the right way to achieve this is to use QAbstractEventDispatcher ("allows the integration of an external event loop with the Qt event loop"). However I'm still not sure how to tie this with my own main loop, and also, I don't know exactly what's needed for the pure virtual functions implementation.

Hope someone could shed some lights for the newbie here. Thanks in advance.


class MyEventDispatcher : public QAbstractEventDispatcher {
protected:
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
void interrupt();
void registerTimer(int timerId, int interval, QObject* obj);
QList<TimerInfo> registerTimers(QObject* obj) const;
bool unregisterTimer(int timerId);
bool unregisterTimers(QObject* obj);
void wakeUp();
void flush();
void registerSocketNotifier(QSocketNotifier* notifier) {
int sockFd = notifier->socket();
int type = notifier->type();

if (type == QSocketNotifier::Read)
connect(notifier, SIGNAL(activated(int)), this, (SLOT(handleRead(int)));
else if (type == QSocketNotifier::Write)
connect(notifier, SIGNAL(activated(int)), this, SLOT(handleWrite(int)));
else if (type == QSocketNotifier::Exception)
// handle exception
}
void unregisterSocketNotifier(QSocketNotifier*);

private Q_SLOTS:
void handleRead(int sock);
void handleWrite(int sock);
};


My main function would look something like this:


int main(int argc, char *argv[]) {
MyEventDispatcher* dispatcher("mainwindow");
QApplication app(argc, argv);
MainWindow *mainWindow = new MainWindow();
mainWindow->show();
//MyApp::getInstance().run(argc, argv);
//return 0;
return app.exec();
}


Sudo code of my own main event loop:


class MyApp {
public:
static MyApp& getInstance();
...
void run(int argc, char* argv[]) {
while (mShouldRun)
runOnce();
}
protected:
void runOnce() {
int rc = select(size, &readFds, &writeFds, 0, &timeout);
if (rc > 0) {
for (int i = 0; i < mFdSet.size(); i++) {
int fd = mFdSet.at(i);
if (FD_ISSET(fd, &readFds)) read();
}
for (int i = 0; i < mFdSet.size(); i++) {
int fd = mFdSet.at(i);
if (FD_ISSET(fd, &writeFds)) write();
}
}
}
};


My Qt widget app


class MainWindow : public QMainWindow {
// GUI stuff
}

vkincaid
31st August 2009, 16:27
Sorry for pulling this topic up again, but I seem to be in a dead end for the last couple of days :( Any pointers about this will greatly be appreciated!

wysota
31st August 2009, 18:51
If all your loop does is to call select() on a bunch of descriptors and do something based on the result then maybe it might be easier to integrate your loop with Qt's loop and not the other way round. It would be trivial by using QSocketNotifier.

vkincaid
31st August 2009, 22:50
Thanks a lot wysota! I receive socket notification via activated signals now and still use app.exec(). This is a lot easier to understand than using QAbstractEventDispatcher.