How do I start an external process using Qt? - c++

FINAL EDIT: The code I've written below works, so disregard everything I've written. It seems that when I copied my input text file to the build directory, the file was somehow corrupted in process, which caused my external executable "prog" to break. Sorry for wasting your time and thanks to all of you who tried to help!
I've just started messing around with Qt and have a project called test_tiny. In the build folder of my project (where executable test_tiny is located), I have moved another little C++ executable called "prog" which reads from a file, does its thing, and outputs to a different file. The input file is also in the build directory.
I also have a window with a couple of text boxes and a few buttons. I would like to run my external program "prog" by pressing one of these buttons. This is what I've got so far:
void MainWindow::load2() {
QProcess *process = new QProcess(this);
process->start("./prog");
qDebug() << process->exitCode();
ui->textBrowser_2->clear();
ui->textBrowser_2->insertPlainText(read(":/File/out.txt"));
}
The second part works just fine - it reads from the out.txt file and loads it into the text browser. However, my process doesn't seem to run, and exitCode() always returns zero (I have changed it to 100 in "prog").
From what I've understood, the QProcess' working directory (unless otherwise specified) is set to its build folder, so calling process->start("./prog"); should work, but it doesn't. I've also tried calling it by referencing a QResource as well as giving the full path, but to no avail.
Any help would be appreciated, thanks!
I'm using Qt Creator 2.81 based on Qt 5.1.1 running on x64 Ubuntu 12.04.
EDIT: I forgot to mention that the executable "prog" only parses a few lines of text and outputs them to a file, which is then read and output to a text box. The external program "prog" doesn't actually seem to run, and I've already tried using process->waitForFinished().

You must wait till the process is finished before you check the exit code. You can wait by using the finised() signal or waitForFinished(). After waitForFinished succeeds or the finished signal is emitted it is safe to check the exit code. I almost always will use the finshed signal. However you should also make sure that the process started in the first place. Using the error() signal is how I detect if there is a problem starting the process. QProcess will emit this with a code describing the error. QProcess::FailedToStart will tell you that your application did not start in the first place.

You have two problems:
Are you on the correct path? while debugging using a full path, it make life easier.
You need to call QProcess::waitForFinished(LARGE_TIME) or connect to the finished() signal before you can check the error (the app starts asynchronously).

Related

Releasing file lock in Qt

I have a Qt program that works on Linux but not on Windows. It progressively downloads something from the internet, writes that into the file, and then tries to open that file using QDesktopServices::openUrl. This works fine under Linux (Fedora), but when I run under Windows, nothing happens - the file is never opened, but also no error is reported.
However if I try to manually open the downloaded file on Windows, I find the reason for this. I get the error Another program is currently using this file, meaning that Qt has not released its lock on the file. However I have already called file->close() on it.
How can I ensure that all locks on a QFile have been released?
Here's a fragment of code that runs after the file has been written:
QString filename = file->fileName();
if (!file->flush())
emit error("Could not finish writing file") // Not emitted
file->close();
QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
I don't think this is a Qt issue. I have seen similar behaviour on Windows systems before (with and without Qt), it might be that either the CRT or the OS still haven't finished their work on the file.
You might try to disable disk write caching in the OS to see, if things work as expected. I had to do this in a Windows-Embedded RT environment to get deterministic behaviour.
BTW: You can evaluate QFile::error() even after calling QFile::close() so you can skip your flush part completely.

Code Blocks - empty console

When I'm running any project in Code Blocks I see this:
or
What should i do?
Thank you for your question and for using CodeBlocks as IDE.
The error message you are getting is because codeBlocks has no 'write' privileges to the folder where it wants to place the binary (or executable). You need to change the privileges of the folder where you ave your projects stored to Read/Write/Execute for all.
If you need to know how to do that, you need to put the specs of your system in the comments, I will tell you here on how to.
KR
Hewi
You usually get this message when you try to recompile an executable that is already running.
If you got this error, you should simply close your application. If you can't see an application window and you're still getting the error, open Task manager (Ctrl+Shift+Esc), find your program in processes list and close it from here.

Starting with codeblocks, building a Hello world does not work (Permission denied)

If I have just run CodeBlocks, I can build and run the Hello world and I the prompt shows and everything is fine. I close it, change what is written, and this message appears:
ld.exe||cannot open output file bin\Debug\HellowWorld.exe Permission denied|
I need to do way more difficults programs than a helloworld, and I've seen in several webs this problem addressed, but nothing works:
http://forums.codeblocks.org/index.php/topic,15047.30.html[1]
ld.exe: cannot open output file ... : Permission denied
After much reading, I understand it has something to do with how the program handles memory. It's something like, if it thinks there's still a process in execution, it does not let me build it again. But I do close it. I've tried everything: input any text so the windows closes (and it does), going to window task manager and finishing the process itself. It does not work. The kicker is that, if I let a few minutes pass, I can indeed build again and run it again. It's kinda stupid and I need help to fix this.
Even more links: The first one I don't get it. I downloaded it and checked as it's said in the wiki:
http://wiki.codeblocks.org/index.php?title=Creating_a_new_project[3]
The link:
http://www.reddit.com/r/learnprogramming/comments/1rvmhx/i_just_started_programming_and_stuck_from/[4]
I mean, I can have done wrong even that. But it does compile and build and run the first time arround...
Most likely the program is still running. Then you can't replace its executable.
If it doesn't have a visible user interface then you can forcefully terminate it via Task Manager Shift+Ctrl+Esc.
Or simpler, always build as console program, because then you can just close the program's console window.

Why would a program run when launch from windows but not the command prompt?

I wrote a small C++ program in VS2k8. When I launch it from windows (double click the exe file) it runs fine. When I go to the command prompt and try to run it it will hang and eventually crash. I've created test programs with simple outputs that work fine both ways.
Is there something I'm missing? I'm relatively new to programming. I'm trying to launch this program using the VBA shell command but it produces the same outcome as the command prompt.
The funny thing is it was working fine at first until I went in to change the value of a constant variable and rebuilt it (I didn't think that had anything to do with it but I changed it back with no success). No settings where changed.
Edit: I've name it time.exe and than copies.exe (when I tried copying and pasting the code into a new project). The actual code is about 250 lines, not sure what part of it would be causing the issue. It opens a .csv file, loads the information into vectors, and then compares the vectors to each other (adding something to the end of it if it meets certain conditions). It than outputs the file to another .csv file.
Might suggest that the current directory on start up is different and this is causing your issue as you make some assumptions about the current path or drive?

Control multiple program instances - open multiple files problem

This shouldn't be an unusual problem, but I cannot find anything about it at google or at other search machine.
So, I've made an application using C++ and QtCreator. I 've made a new mime type for application's project files.
My system (ubuntu 10.10), when I right click a file and I choose "Open With 'Default Application'" the it runs
Code:
default_application path/to/the/selected/file1
So, if you select multiple files and select "Open With 'Default Application'" the system will call
Code:
default_application path/to/the/selected/file1
default_application path/to/the/selected/file2
default_application path/to/the/selected/file3
So, this is a big problem for me, because I handle the concurrent processes from inside the program, so when another instance of the program is running, a warning message is appeared. So, each application's call will recognize the others as currently running applications and so it'll show the message. I'll end up with 3 Messages saying that another process of the program is running --_--'
My application handles multiple URLs this way:
Code:
myapp path/to/the/selected/file1 path/to/the/selected/file2 path/to/the/selected/file3
How can I make my code handle all these multiple instances at the same time? Everything I've tried fails, because everything I've tried requires a check from the first instance called, which is too slow and other instances come app and all together are warning about concurrent processes of the same program
So, how can I fix this? is it system depended, or can I do something with the code?
The way is to make your application recognize that there is already an instance running and make the new instance just forward a request to the first instance before dying :)
EDIT:
The way to do that is to have your first application instance behave as a server. The pseudo algo is something like :
start();
try_to_contact_master_server_instance();
if(no_master())
{
I_am_master();
start_listening_server_that_wait_for_requests();
}
else
{
send_request_to_master("open file path/to/the/selected/file1");
send_request_to_master("open file path/to/the/selected/file2");
send_request_to_master("open file path/to/the/selected/file3");
die();
}
handle_incoming_requests();
I hope it's clearer ? Tell me if you need more precisions ...
For the server part, you can do your own or use some software bus provided by the OS like dbus or whatever, but it makes your application dependent, of course.
my2c