Reply
Thread Tools
Posts: 22 | Thanked: 9 times | Joined on Jun 2012
#1
Hi

I am creating an application for Nokia N9 and stuck into a problem with UI opening. In my application, my requirement is to open UI when click the feeditem on home screen. For this i have defined following in main() something like that

int main()
{
QApplication app ();
QDeclarativeView view;

MyApplication application(&view);

registering DBus etc.
return app.exec();
}

In MyApplication, i have a method openFeed() that opens UI when a feeditem is clicked on homescree

void MyApplication:penFeed()
{
here i am loading UI ap like

QString mainQmlFile =
qApp->applicationDirPath() + "/../qml/main.qml";

QDeclarativeComponent component(m_View->engine(),
QUrl::fromLocalFile(mainQmlFile));

if (component.status() == QDeclarativeComponent::Error) {
qDebug() << "Error(s): " << component.errors();
return;
}

QObject * object = component.create();

m_MainItem = qobject_cast<QDeclarativeItem*>(object);

if (m_MainItem == NULL) {
qDebug() << "MainItem is NULL";
return;
}

m_View->scene()->addItem(m_MainItem);

m_View->setGeometry(QApplication::desktop()->screenGeometry());
m_View->showFullScreen();

}

the problem is that when i click the feed item on home screen, 1st time it opens very fast and load my UI. When i close the UI and click someother feeditem, UI takes a long time to load like 15-20sec which is not acceptable.

Can you please help me out of this problem? I will be highly thankful to you.
 
Copernicus's Avatar
Posts: 1,986 | Thanked: 7,698 times | Joined on Dec 2010 @ Dayton, Ohio
#2
Hmm. My first concern when I see my code performing a task the second time much worse than the first time, is that something that I did the first time is still around and messing things up. Usually, this means I haven't cleaned up some objects after the first call. I don't see anything in the code fragment that would cause this problem, though.

The Qt docs also mention that mixing QWidgets and QML can lead to performance degradation. I doubt it could lead to this much performance degradation, but it's something to check.
 

The Following User Says Thank You to Copernicus For This Useful Post:
Posts: 22 | Thanked: 9 times | Joined on Jun 2012
#3
what will be your recommendations in this case. Actually when i close the feeditem UI 1st time, it causes crashing the DBus service as QDeclarativeView quits the applications when UI is closed and then service registers automatically, application starts again and so on which explain the delay for 2nd time.

Why QDeclarativeView dont work if defined in someother method instead of main() method. Like if i define QDeclarativeView in openFeed(), UI is not loaded when clicking the feeditem.
 
Copernicus's Avatar
Posts: 1,986 | Thanked: 7,698 times | Joined on Dec 2010 @ Dayton, Ohio
#4
Originally Posted by nauman.altaf View Post
Actually when i close the feeditem UI 1st time, it causes crashing the DBus service as QDeclarativeView quits the applications when UI is closed and then service registers automatically, application starts again and so on which explain the delay for 2nd time.
Aha, yeah that would explain the delay.

Why QDeclarativeView dont work if defined in someother method instead of main() method. Like if i define QDeclarativeView in openFeed(), UI is not loaded when clicking the feeditem.
I really don't use QML myself (I do pretty much all my Qt with straight up QWidgets), but I'll take a crack at it here. Lets see... The QDeclarativeView is one way of loading QML components from a C++ object; its benefit is that it loads the QML directly into a QGraphicsView. (The QGraphicsView / QGraphicsScene is a QWidget mechanism used for displaying complex graphics.) There shouldn't be any need to tie QGraphicsView or QDeclarativeView to the main() method, so presumably there's something about how it's being used outside of the main() routine that is going wrong.

Hmm. You're declaring your QDeclarativeView as an "automatic" variable; this only works as long as you don't set a parent for it. Qt always wants to take ownership of child QObject itself, so that it can call their destructors at an appropriate time. If you are setting a parent, you'll want to construct it on the heap instead:

Code:
QDeclarativeView view = new QDeclarativeView(parent);
Actually, before going any deeper into this, I should ask: for what purpose are you trying to combine C++ and QML? (Could you implement your program just using one or the other? It might make things simpler, and possibly provide better performance as well...)
 

The Following User Says Thank You to Copernicus For This Useful Post:
Posts: 22 | Thanked: 9 times | Joined on Jun 2012
#5
The only purpose of combining C++ and QML is to load my custom UI when a feeditem is clicked. But the problem now is that quitting the UI quits my application. My requirement is that closing the UI should not quit my application. Is there a way to fix it?
 
Copernicus's Avatar
Posts: 1,986 | Thanked: 7,698 times | Joined on Dec 2010 @ Dayton, Ohio
#6
Originally Posted by nauman.altaf View Post
The only purpose of combining C++ and QML is to load my custom UI when a feeditem is clicked. But the problem now is that quitting the UI quits my application. My requirement is that closing the UI should not quit my application. Is there a way to fix it?
Well, in your main() routine, you're creating a QApplication object, and then calling "app.exec()" on it as the last command in that routine. (Which is how the Qt SDK normally sets up the default main() routine for a Qt Widgets app.) The QApplication object creates an "event loop" to handle the user interface, and when the user closes the UI, the event loop ends, and the "exec()" routine returns. Therefore, since the main routine ends when "exec()" returns, the application quits.

If you want your program to continue to run, you will either need to ensure that the event loop does not exit when your UI is closed, or not exit the main() routine when "app.exec()" returns, or something like that.

I guess what you're aiming at here is a program that sits and listens for DBUS requests, popping up the QML UI whenever it receives one?
 

The Following User Says Thank You to Copernicus For This Useful Post:
Posts: 22 | Thanked: 9 times | Joined on Jun 2012
#7
"I guess what you're aiming at here is a program that sits and listens for DBUS requests, popping up the QML UI whenever it receives one?"

Yes this is the exact requirement of my application. If i don't put "app.exec()" at end of main method, application don't load at all. I am unable to figure out any alternative way.
 
Copernicus's Avatar
Posts: 1,986 | Thanked: 7,698 times | Joined on Dec 2010 @ Dayton, Ohio
#8
Originally Posted by nauman.altaf View Post
Yes this is the exact requirement of my application. If i don't put "app.exec()" at end of main method, application don't load at all. I am unable to figure out any alternative way.
Well, let's step back a moment here. In C and C++, the function main() is used as the basis to create an executable program. The program begins by executing the first statement within main(), and ends when it finishes the last statement within main().

There's no need for the call to app.exec() to be that last statement. For example, if you've got your own custom DBUS handler, you could have something like:

Code:
int main()
{
  while(TRUE)
  {
    waitForDBUSRequest();

    processDBUSRequest();
  }
}

void waitForDBUSRequest()
{
  // listen for DBUS requests here
}

void processDBUSRequest()
{
  QApplication app;

  app.exec();
}
This would create a new Qt UI every time a new DBUS request comes in.

On the other hand, if you're using Qt itself to process DBUS requests, you could use two event loops, the outer one to catch the requests, and the inner one to display the user interface.

Even better, just have Qt "hide" the UI when the user is done with it, rather than close the event loop entirely. It's a real pain to completely shut down and then completely recreate a GUI interface; it'd be nicer to leave the UI up and running if you're expecting the user to come back to it frequently. This way, you only need to use one event loop; just have Qt "show" the UI again when another DBUS signal comes in...

Last edited by Copernicus; 2013-04-19 at 16:40. Reason: clean up example code
 

The Following 2 Users Say Thank You to Copernicus For This Useful Post:
bibek's Avatar
Posts: 368 | Thanked: 826 times | Joined on May 2012 @ India
#9
I'm not sure if it's feasible or useful doing here, you can register a url mime type in ur UI's .desktop file. Then you could pass that url mime in feeditem's urls. Doing that would invoke your UI automatically whenever items are clicked, along with the url as argument to ur exec specified in that desktop file

And probably you need to separate your UI and daemon. Daemon should be running in back, UI should open and close but not access backend tasks as long as daemon is running.

Not sure if there is an way to synchronise the resources loaded by daemon to make UI startup faster (was it booster's purpose?) , but I think I read it somewhere.
__________________
Blob | ClipBook | Qcal | DoMee | ShareBoard | TMO Forum App
 

The Following User Says Thank You to bibek For This Useful Post:
Posts: 22 | Thanked: 9 times | Joined on Jun 2012
#10
The problem is that QDesktopServices::setUrlHandler() never worked for me. Now if i use Bibek approach, i will be having two main methods, one to register DBus service and other one to handle the Url.

int Main()
{
QApplication app();
DBus Service regiteration
return app.exec();
}

int main()
{
QDeclarativeView view;
MyHandler object(&view);
QDesktopServices::setUrlHandler("myscheme", &object, "openUrl")
return app.exec()
}

in my desktop file

[Desktop Entry]
Type=Application
Name=My Application
MimeType=x-maemo-urischeme/myscheme;
Exec=/opt/myapplication/bin/myapplication %U
OnlyShowIn=X-MeeGo;

when i click the feeditem, openurl() is never executed.
 
Reply


 
Forum Jump


All times are GMT. The time now is 10:31.