Check for availabe services - qt

I'm writting a server app in Qt. and have Loader class that checks for available services. So, in order to launch server successful I need to check through Loader e.g. programmatically, whether MySQL service is functioning or not. I've found out that using QProcess is smth which is related to that but
when I coded the following:
QProcess mysql;
mysql.start("mysql", QStringList() << "-uroot -ppassword");
if(!mysql.waitForStarted())
qDebug() << "Not loaded...";
mysql.write("show databases;");
mysql.closeWriteChannel();
if(!mysql.waitForFinished())
qDebug() << "Haven't finished yet!";
QByteArray result = mysql.readAll();
QString str(result);
qDebug("%s", qPrintable(str));
I'm receiving an empty string, could you help to check whether services started or not?

I don't understand your problem. You have already in your code:
if(!mysql.waitForStarted())
qDebug() << "Not loaded...";
This tells you clearly whether or not your mysql program started.
But if I may give you an advice, drop your idea using mysql via QProcess. This is fine to start the mysql server, but nothing more. Look into the Qt docs for QSqlDatabase. This allows you to connect to the server directly. Trying to open() your database with QSqlDatabase can give you by far more information, than the QProcess crutch you try to use.
Edit: Change your 'readAll' into 'readAllStandardError'. You will see something interesting.

Related

QProcess executing a c++ file

In some places it suggests, I can't run a pre-built c++ binary with QProcess. at the same time there are other questions where people are executing shell scripts etc with QProcess so I am confused. Can I execute a pre-built c++ binary using QProcess.
This binary reads a text file and creates two text files in return.
I created a basic UI with GUI and have a button which when clicked calls the external binary.
Running this with execute gives me an error of QIODevice: read: device not open. When I use start, no errors are reported. But no output files are created either.
Any ideas whether this is permitted in qt or some other approach needs to be followed.
void MainWindow::on_startButton_clicked()
{
QString program = "./home/naveen/sdj";
QProcess *myProcess = new QProcess(this);
myProcess->start(program);
myProcess->waitForFinished();
qDebug() << myProcess->exitStatus();
qDebug() << myProcess->readAllStandardError();
}
First, QProcess::execute() is a static method -- there's no reason to create a QProcess instance to use it. If you use QProcess::start(), it will execute the process asynchronous. You have to listen for a finished signal before you can check for a return code.
Second, are you sure this is what you intended?
QString program = "./home/naveen/sdj";
In *nix file systems, ./ means start in the current directory. So QProcess won't look for /home/naveen/sdj, it will instead look for /yourProjectBuildPath/home/naveen/sdj. I'm guessing that's not what you want.

How do I get a signal from QNetworkAccessManager::networkAccessibleChanged()?

I am using the QNetworkAccessManager to do HTTP requests. We have found that the network connection we are using can go offline occasionally, and I want to actively detect when the link goes down.
I have connected a slot to the QNetworkAccessManager::networkAccessibleChanged() signal, but am not seeing any output from my slot.
In searching for a solution, the closest I come to an answer is the following discussion: http://www.qtcentre.org/threads/37514-use-of-QNetworkAccessManager-networkAccessible
However, the solutions suggested didn't resolve my problem.
Any suggestions on what I may be doing wrong?
Ok, after some more experimenting, I have found the answer...
Turns out my problem is that I have several Ethernet interfaces on my system.
In the discussion linked from my question, adding the following code was suggested:
QNetworkAccessManager* mNetworkAccessManager = new QNetworkAccessManager();
QNetworkConfigurationManager manager;
mNetworkAccessManager->setConfiguration(manager.defaultConfiguration());
The documentation for QNetworkAccessManager::setConfiguration() indicates the the default configuration is used automatically; so this is unnecessary, but it set me on the right track.
My problem is that the default configuration attaches to a different interface than the one my connection is going through; so I did the following:
QString ifName = "eth2";
QNetworkAccessManager* pNetworkAccessManager = new QNetworkAccessManager();
QNetworkConfigurationManager manager;
foreach(QNetworkConfiguration cfg, manager.allConfigurations()) {
if (cfg.name() == ifName) {
pNetworkAccessManager->setConfiguration(cfg);
break;
}
}
Now, my slot gets called.
I wish there were an easier way to get the desired configuration. Now, I have to figure out how to get the configuration starting with an IP address, instead of the interface name.

Qt DBus registerService function call returns false on an embedded Linux device

I’m new to DBus, but I’m trying to use it in two Qt applications on an embedded device. I have a very simple interface that consists of one slot:
QString SendMessage(const QString &cmd);
The server application is then using the following code to start the connection:
DbusService* dBus = new DbusService;
new interfaceIfAdaptor(dBus);
QDBusConnection connection = QDBusConnection::sessionBus();
bool ret = connection.registerService("com.domain.project.interface");
qDebug() << "returns" << ret;
ret = connection.registerObject("/", dBus);
qDebug() << "returns" << ret;
This works fine on the desktop. In the embedded system, the connection.registerService function returns false. As a result, any messages to the server fail. I’m not sure why. Running ‘ps’ tells me that [dbus-daemon —system] and [dbus-daemon —sesson] are both running.
Finally, I have noticed that Qt Creator complains when I debug the application. I see the following warning messages:
Could not load shared library symbols for 10 libraries, e.g. /opt/arm/lib/libQtDBus.so.4.
Use the “info sharedlibrary” command to see the complete listing.
Do you need “set solib-search-path” or “set sysroot”?
Could not load shared library symbols for /usr/lib/libdbus-1.so.3.
Do you need “set solib-search-path” or “set sysroot”?
If additional information is required to debug this problem, please let me know. Or if there are useful dbus commands I could run to help figure this out. Thanks!
It turns out the session bus was not getting started on the device. I enabled it, but then I ran into the problem of the address not getting propagated to the environment variables. I can manually set it in a terminal, but I'm not sure how to do the same in Qt Creator.
Anyway, rather than spend more time figuring out the issues with the session bus, I switched to using the system bus. I just had to change the /etc/dbus-1/system.conf file to allow anyone to talk to the system bus and my applications work on the embedded device. I know that's probably not the long term solution, but it works for now.

Application is not restarting on device In Qt

I am developing an application on Qt symbian, in which I have to restart my application within my application, have used:
qApp->quit();
QProcess::startDetached(qApp->arguments()[0],qApp->arguments());
from a method in mainWindow. It is working fine on simulator but not on device, it closes but not restarting by itself, I have to restart it by myself, is there anything else I have to do to make it work on device.
One solution would be to create small console process that you can launch from your main program before closing it. Then this console process would just launch your program and close.
I have been using this kind of processes to keep track of my apps and restart them when they crash.
One minor but fundamental thing: on Symbian there is an emulator and not a simulator. The difference is that the later simulates the device on the assembly level while the former does it only on API support level. For example iPhone simulator simulates the phone on assembly level. Contrarily in Symbian the underlying API implementation might be and is completely different for the ARM and for the WINS architecture. Especially in such cases when you interact with the OS like exiting the application.
The application quit operation on Symbian is eventually implemented by throwing a special exception (I don't remember it's name, something like KExitException) that is caught by the main Active Scheduler loop that tells the kernel to shut down the process. In other words it means that it is a synchronous call. If you first call quit then startProcess then the later will be never executed. It is not that clear why does not it work if you first call startProcess and then quit: this might be an asynchronous call that can not complete before you exit, or you simple can not start the same (GUI) application in two instances. Anyway check the return value of startProcess to see whether it succeeded or not.
Your ultimate solution will be to create a watchdog process as #Riho suggested. You start the watchdog process before you call quit, in the watchdog main function you wait some seconds and restart your application. You will need SwEvent capability for your watchdog.
I have tried it with Qprocess() and it seems to be working fine (still testing for memory and thread issues)
in main.cpp I write this code (which I got from other link )
int main(int argc, char *argv[])
{
#define RESTART_CODE 1000
int return_from_event_loop_code;
QPointer<QApplication> app;
QPointer<MainWindow> main_window;
do
{
if(main_window) delete main_window;
if(app) delete app;
app = new QApplication(argc, argv);
main_window = new MainWindow;
QList<QString> lang = AppStatus::getCurrentLanguage();
QTranslator translator;
translator.load(lang.at(0));
app->installTranslator(&translator);
main_window->setOrientation(MainWindow::ScreenOrientationLockPortrait);
#if defined(Q_OS_SYMBIAN)
main_window->showMaximized();
#else
main_window->show();
#endif
return_from_event_loop_code = app->exec();
}
while(return_from_event_loop_code==RESTART_CODE);
return return_from_event_loop_code;
}
and in my method from where I have to restart my app I have written this.
QProcess::startDetached(qApp->applicationFilePath(),qApp->arguments());
qApp->exit(RESTART_CODE);
And my app is restarting like I wanted.. If any changes nedded plese let me know.

Continuous uploading causes QNetworkReply error "Cannot allocate memory"

I have an Qt application for symbian that receives gps data, stores it into a database and tries to post it to a server. First two steps work fine but continuous posting either crashes my application or kills my internet connection.
I have modified my application for debugging purposes so it only does post data to a server in every 10th second. Application runs fine for about 45-90min without any significant memory increase.
After that that I'll get an error from QNetworkReply saying "Cannot allocate memory".
Same time memory usage increases approximately 63500(bytes?).
On next upload I'll get reply that says "Invalid socket descriptor" and after that my QtCreator debug output is filled with "exception on 7 [will do setdefaultif(0) - hack]"
Anyone know what is going wrong here? I can't find errors from my upload code that could be causing this.
Here is my upload script.
void MainWindow::upload() {
//Content of postData below. Using same data on every upload now when tracking the bug
//[{"timestamp":"2010-10-01T17:10:27","latitude":62.1823321,"longitude":25.73226825,"user":6}]
QByteArray postData;
QNetworkRequest request;
request.setUrl(uploadUrl);
this->qnam->post(request, postData);
}
void MainWindow::serviceRequestFinished(QNetworkReply* reply) {
QByteArray bytes = reply->readAll();
if (reply->error() == QNetworkReply::NoError)
{
//nothing in here when debugging
} else {
qDebug() << "-------Reply error: " + reply->errorString();
}
reply->deleteLater();
updateHeapStats();
}
void MainWindow::updateHeapStats() {
#ifdef Q_OS_SYMBIAN
TInt mem, size, limit;
User::Heap().AllocSize(mem);
size = User::Heap().Size();
limit = User::Heap().MaxLength();
qDebug() << "**DEBUG MEMORY - > Memory: " << QString::number(mem);
qDebug() << "**DEBUG MEMORY - > Heap limit: " << QString::number(limit);
qDebug() << "**DEBUG MEMORY - > Heap size: " << QString::number(size);
#endif
}
Allmost forgot, I have tested this with Nokia N97mini, 5230 and 5800 and they all behave same way.
edit. Forgot to mention that when internet connection "dies" I still can see that 3G is on but connecting to internet with web-browser fails. When I close the application and try to connect to internet with browser it says "Web: Memory full, ..."(web requests from apps works fine) I'm using Nokia Energy profiler and it doesn't show any signs of memory being full. Even tested this and started 2 games, ovi maps and tons of other applications and they worked fine even though they consumed over 40MB of memory.
With the caveat that the only networking code I do in Qt is on a desktop platform and even then I need to look it up, I don't see anything obvious. I also know that in my own code deletelater() sometimes has a different idea of what "later" is than I do. I don't have time to look it up and may be wrong here, but I think deletelater() actually runs on the event thread, and if your event thread is always busy, when will it have time to delete the object? For debug purposes, I would replace deletelater() with delete (and really, there's no reason to use deletelater() unless you've got a parent/child relationship that you need to clean up, and there might be a way to manually remove the child from the parent so you don't need to worry about dangling pointers when you call delete).
I also don't know the accuracy of your memory consumption test. Does the allocated memory test refer to the current thread? The current process? Does a program received a "chunk" of memory from the heap that it simply managers on its own and it isn't permitted to use more than? I think you know this framework much better than I do; these are just some thoughts for you to try.

Resources