PDA

View Full Version : Why do I require a new event loop from a GUI?



pitonyak
14th February 2010, 22:31
I have some simple code to read a web page. You have seen the code before, it is very simple:

QNetworkRequest request;
QUrl hostUrl;
hostUrl.setUrl("http://qt.nokia.com");
request.setUrl(hostUrl);
QNetworkReply* reply = networkAccessManager->get(request);
Next, I connect more connections than seems reasonable. My question is, how should I do this in a GUI? My initial solution was to run this code in a slot that was called from a menu item. Of course, I have no response unless i start an event loop:

QEventLoop loop;
loop.exec();

I had expected that this would use the GUI's event loop (a GUI always has an event loop, right?) You know, started this way

QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
That said, I find it disturbing that I started an event loop in a handler for a menu command.

franz
15th February 2010, 06:33
You shouldn't have to create a new event loop unless you want to call slots in a different thread. I'm not sure what the problem is, but as far as I know the main event loop should take care of this.

pitonyak
15th February 2010, 13:49
It is useful to know that I should not need to manually start an event loop, especially if I am setting things from a handler already. I suppose that I should find some material on event loops and such. I did notice that some items may not be called until after I kill the application and things are shutting down.

I originally wrote my code in Java, where my calls to gather information are blocking, so the structure of my code is more suited for this scenario; for example, I make a call and I know how to parse the returned values because I know the context of the call. I loose this with the slots and call backs without seriously changing my logic.

I suppose that I must school myself more seriously in the inner works of the QT event loop, since I expected there to be an event loop in my GUI and for things called in the slots to be called from that event loop.

franz
16th February 2010, 10:28
Could you post the code you are using (you said it isn't much). Maybe I can pinpoint what the problem is. The code you posted before is for me not enough to determine what the exact problem is (i.e. what part of the documentation you need to read :)).

pitonyak
16th February 2010, 23:15
Based on your willingness to look at my code, I started to extract the small amount of working code for this particular piece. While performing this exercise, the solution hit me in the side of the head.

First, let me say that the code is really as simple as it looks. All of the displayed code sits in a class named SmugMugController. This is my code to connect:

void MainWindow::on_actionConnect_activated()
{
QString emailAddress = "andrew@pitonyak.org";
QString password = "fake_value";
SmugMugController controller;
SmugMugLoginEntity* login = controller.login(emailAddress, password);
}
My initial code was in Java, and everything was synchronous. The QT code is asynchronous, which means that the returned object is always NULL. That is not the problem, however. The problem is that my controller is a local variable, and the moment that I return from on_actionConnect_activated, the controller variable goes out of scope, its destructor is called, and all of the contained objects are destroyed. This includes my get request.

By adding an internal event loop, the loop is started before I return and the class can be destructed. Although this did work, it is the wrong solution.

Moving my controller variable out to the main class, solves the problem. That said, I will likely change the architecture so that it is more in line with the way that QT does things.

Thanks for the offer Franz. If you ever make it to Columbus, Ohio in the USA, let me know and I will provide you with a tasty beverage of your choice.

franz
17th February 2010, 07:13
Great. I'll try to remember that :).