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.
Related
I am using QProcess to run other programs. But when I exit my app after calling QProcess.start() it says in debug console:
QProcess: Destroyed while process is still running.
and the process closes.
But I want to keep this process running after closing my app. How I start new process:
QProcess p;
p.start("ssu.exe", QStringList() << "-instantinstall");
How do I do that?
You need to use QProcess::startDetached. See the docs:
If the calling process exits, the detached process will continue to live.
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.
I have 2 processes.
The first one creates a QSharedMemory, with a key.
The creation is successful, as no error is returned.
In the second process, I try and attach to the shared memory, having done setKey() with the same key name as the first process, and then try and attach() to the memory.
The attach() fails. Using errorString() on the shared memory, the following string is returned :
QSharedMemory::handle: doesn't exist
Platform is Windows.
What could I be missing here? Kindly advise, thanks.
Have you looked at the shared memory example?
http://doc-snapshot.qt-project.org/4.8/ipc-sharedmemory.html
Below are some code snippets from that example.
Here is what the first process does to put a buffer of "size" into the shared memory:
if (!sharedMemory.create(size)) {
ui.label->setText(tr("Unable to create shared memory segment."));
return;
}
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(sharedMemory.size(), size));
sharedMemory.unlock();
Here is what happens when the second process wants to access the shared memory:
if (!sharedMemory.attach()) {
ui.label->setText(tr("Unable to attach to shared memory segment.\n" \
"Load an image first."));
return;
}
QBuffer buffer;
QDataStream in(&buffer);
QImage image;
sharedMemory.lock();
buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
buffer.open(QBuffer::ReadOnly);
in >> image;
sharedMemory.unlock();
sharedMemory.detach();
ui.label->setPixmap(QPixmap::fromImage(image));
Note also that in the example, both processes must be running and still have their instance of QSharedMemory. Here is how it is described in the documentation:
Windows: QSharedMemory does not "own" the shared memory segment. When
all threads or processes that have an instance of QSharedMemory
attached to a particular shared memory segment have either destroyed
their instance of QSharedMemory or exited, the Windows kernel releases
the shared memory segment automatically.
Hope that helps.
Encountered same problem. Make sure that QSharedMemory object still lives when second binary tries to attach.
If you want to block ability to run 2 instances of same QT binary, just make QSharedMemory object using dynamic memory which will live until app exit.
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.
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.