QProcess with GUI not freezing - qt

I would like to launch mysql from GUI using QProcess. I've tried the following:
QStringList arguments;
arguments << QString("-u%1").arg("myaccount")<< QString("-p%2").arg("password");
QProcess *mysql = new QProcess;
mysql->setReadChannelMode(QProcess::ForwardedChannels);
mysql->execute("mysql", arguments);
if(mysql->waitForReadyRead(-1))
qDebug(mysql->readAllStandardOutput());
But, there is big problem as it's mentioned in Qt Documentation, it's gonna freeze.
How can I solve this? Many advised to use QThread but I don't have any idea how to do that?
Thanks beforehand!

The problem is that you call the QProcess::execute() function and it waits until the process is finished. If you need to avoid freezing you can use readyReadStandardOutput() signal and do the following:
[..]
connect(mysql, SIGNAL(readyReadStandardOutput()), this, SLOT(readOutput()));
mysql->start("mysql", arguments);
if (!mysql->waitForStarted()) {
// report error
}

This link may help you:
QProcess fails to execute external executable
Calling MySQL :
c:\mysql\mysql.exe -u MYUSERNAME -pMYPassword
There is no space between -p and password.
Set MySQL Path.

Related

Uninstall flow or callback in Qt Installer Framework 3.0.2

Is there any way to call a windows cmd command at uninstall process (maintainancetool.exe) of Qt installer framework? I tried to connect the
installer.uninstallationFinished signal but no results.
+1 Bancha's answer. Also if you are executing the windows command as part of uninstalling a component, it might be better to use the UNDOEXECUTE component of the Execute operation since it will execute along with the other uninstall operations for the component.
example:
component.addOperation("Execute", "touch", "test.txt", "UNDOEXECUTE", "rm", "test.txt")
You can check whether you are in the uninstall mode by installer.isUninstaller()
Below code snippet, may give you a clue.
function Controller() {
if(installer.isUninstaller()) {
installer.uninstallationFinished.connect(this, this.uninstallationFinished);
}
}
Controller.prototype.uninstallationFinished = function() {
//Put you cmd that need to execute after uninstalling finish here
}
installer QML Type
Controller Script

Start both applications and scripts using QProcess

I have written this function to run scripts or applications:
void TerminalRun (QString command)
{
QProcess process;
process.start("sh",QStringList() << "-c" << command);
process.waitForFinished(-1); // will wait forever until finished
}
It works just fine if I use it for applications like:
TerminalRun("geany &")
However, it can't execute scripts like:
TerminalRun("/path/to/script.sh &")
I don't get any error, but it just does not execute the script.
What is the issue and how can I fix it?
The script executes just fine directly in terminal.
I am using Qt 4.8 in Ubuntu 16.04.
I suggest you to not use "waitForFinished" but "start" and then the signals:
connect(&Process, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()));
connect(&Process, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()));
connect(&Process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus)));

Need to quit a process from inside Qt GUI, just as it is started

I am trying to run C++ executables placed inside SBC6845 [inside /ftest as shown ]. Now these executables are running with
while(1){
// around 250-300 lines of code here
}
infinite loop. Now when I run only the codes from terminal, I can kill them whenever I want to. But I am unable to kill them while running from inside the gui. I execute these codes with Qprocess like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow){
ui->setupUi(this);
connect(ui->pushButton, SIGNAL(pressed()), SLOT(vcm_test()));
connect(ui->pushButton_2, SIGNAL(pressed()), SLOT(offloader_test()));
connect(ui->pushButton_3, SIGNAL(pressed()), SLOT(quit_vcm()));
connect(ui->pushButton_4, SIGNAL(pressed()), SLOT(quit_offloader()));}
void MainWindow::vcm_test(){
QProcess::execute("/ftest/vcm_test_2 \r\n");
}
void MainWindow::offloader_test(){
QProcess::execute("/ftest/off_test_2 \r\n");
}
void MainWindow::quit_vcm(){
QProcess::execute("\x001a \r\n");
}
void MainWindow::quit_offloader(){
QProcess::execute("\x001a \r\n");
}
Now the problem is when the pushbutton or pushbutton_2 i.e. vcm_test() or offloader_test() is invoked the gui becomes unresponsive. Since the gui keeps waiting for the code in /ftest to finish quit option does not work and I have to quit it from the terminal again. Also quitting from terminal closes both the code and the gui.
I have tried searching solutions and used threads too. But I get segmentation error while starting a thread from pushbutton.
I need to be able to quit the process while it is being executed (modification of this code or any new idea is very much appreciated). I am a newbie so please ignore my poor coding skills. Thanks.
QProcess::execute(..) waits for the process to finish, that is why your GUI is freezing. Use QProcess::start(..) instead. To quit the process use the QProcess::close() function
Try this:
QProcess *myProcess = new QProcess(this);
myProcess->start("/ftest/vcm_test_2");
And when you want to close the process:
myProcess->close();
You can also connect your pushbutton's clicked signal to the process' kill slot:
connect(ui->pushButton_3, SIGNAL(clicked()), myProcess, SLOT(kill());
You can make a QProcess object and call start() on it. That way the code doesn't get blocked when you execute the process untill it is finished.
QProcess* myprocess=new QProcess();
myprocess->start("/ftest/vcm_test_2");
You can if you want get a signal from myprocess to know if the process is finished. Which is in your case not usefull.
You can also close the process by invoking
myprocess->close();
Hope that helpes.

Run a program from Qt

I am working with Qt in Linux. I need to run the "evince" pdf reader from Qt.
I have been searching and as I understand I can use Qprocess to make it work. Something like this:
QStringList args;
args.append("/home/user/presentacion0.pdf");
QProcess p(this);
p.start("/usr/bin/evince", args, QIODevice::ReadWrite);
p.waitForFinished();
QString p_stdout = p.readAllStandardOutput();
QString p_stderr = p.readAllStandardError();
But I always get the following error:
No protocol specified
Cannot parse arguments: Cannot open display:
So I tried the system(char *cmd) from stdlib.h and does not work
system("/usr/bin/evince /home/user/presentacion0.pdf");
I think system() does not work because "evince" is a graphical application. However I can run "ls", "mkdir", etc. commands with system() without problems.
Please I need help with this topic.
I Really appreciate your help in advance.
Thank you.
You're running your Qt app from an application (most likely shell) that doesn't have DISPLAY environment variable set properly (it's usually :0). QProcess uses environment of the calling process.
If you're not really interested in grabbing evince's stdout and stderr, and you don't need to wait for its finish, then I would go with QProcess::startDetached().

How can I see qDebug messages while debugging in QtCreator

I'm making the transition from Eclipse CDT (with Qt integration plugin) to QtCreator 2.0 but there is still one thing that bother me with QtCreator :
When I debug in QtCreator, I don't see my qDebug messages inside the Application output tab until I stop the application I'm debugging... Then they are all displayed at once which is not very useful.
With Eclipse, I don't have this problem : the qDebug messages are displayed correctly when encountered while stepping through the source code.
I'm using both Eclipse CDT and Qt Creator under Windows. I didn't try under Linux (which is not an option right now).
While not a complete answer, you can install DebugView (If you're on an XP machine) to view the qDebug output while you try to figure this out.
Another solution might be considered a hack, but works quite nicely, is to simply hijack debug messages yourself:
#include <QtCore/QCoreApplication>
#include <QDebug>
#include <iostream>
void msgHandler( QtMsgType type, const char* msg )
{
const char symbols[] = { 'I', 'E', '!', 'X' };
QString output = QString("[%1] %2").arg( symbols[type] ).arg( msg );
std::cerr << output.toStdString() << std::endl;
if( type == QtFatalMsg ) abort();
}
int main(int argc, char *argv[])
{
qInstallMsgHandler( msgHandler );
QCoreApplication a(argc, argv);
qDebug() << "Hello world.";
qWarning() << "Uh, oh...";
qCritical() << "Oh, noes!";
qFatal( "AAAAAAAAAH!" );
return a.exec();
}
Which would output:
[I] Hello world.
[E] Uh, oh...
[!] Oh, noes!
[X] AAAAAAAAAH!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
This is actually a modification of some code that I use myself to send qDebug, qWarning, etc., to a log file.
You don't have to close the application to see qDebug() messages.
There is a tab named 3 - Application output at the very bottom of the Qt Creator. Clicking that window will show you the Application output window at the bottom of Qt Creator.
That particular window will display the qDebug() messages as soon as they get called while the application is still running.
Hope it helps.
Edit:
I am not sure whether this is an answer but it might be a good valid cause.
From qDebug() documentation,
The Qt implementation of these
functions prints the text to the
stderr output under Unix/X11 and Mac
OS X. With Windows, if it is a console
application, the text is sent to
console; otherwise, it is sent to the
debugger.
Now Qt Creator doesn't have it's own debugger attached to it.
From Qt Creator documentation, we have to manually install the debugger. Since you are using Windows, you need to install Debugging tools for Windows manually.. More documentation can be found here...
Though am not used to Eclipse CDT, I assume there might be a Debugger attached to it and hence it displays the Debugging output correctly..
Since there isn't a Debugger attached to the Qt Creator, it might be behaving strangely..
Just give it a try..
To add to the above answers..
Always make sure to build in debug mode and not in release mode..
As qDebug() , only works with the debug build.
This was the silly mistake i made, before my search for the led me here, and i wanted to add this fine but important point, to the list of other answers.
Have you tried to add the following line to your .pro?
OUTPUT += Console
Then you can output on std::cout.
Let me tell you something:
Once I have developed a c++ console application on linux. During running the application it was reading a file and starting to process some logic by printing out some status messages. When I run that application the output was OK. So for convenient debugging I have decided to run the application like this:
./a.out |& tee log
This command redirects standard output (may be also standard error I don't remember) into a file named "log". So when I run with this option I saw that it writes in the log file exactly the same as in std out only there are some displacements like this:
in std out - desired output
A
operation 1 success
B
operation 2 success
C
operation 3 success
D
operation 4 success
in the log file - output with displacement (this is not correct)
A
B
C
D
operation 1 success
operation 2 success
operation 3 success
operation 4 success
I guess your problem is this kind of one... I have taken a look at QDebug and have not seen any function that frees the buffer (something like operation called flush). So I recommend you to not waist your time on this kind of small issue (I also consider that Qt Creator 2.0 is release as a beta version and it may appear a bug) and use one of the following:
qFatal()
qCritical()
qWarning()
QMessageBox
I personally use QMessageBox::about in order to debug as you can stop the screan and read the value in a very usefull places that with debugger you can't (I mean you can but you can't see the current state of you GUI application as debugger have taken the control).
Hope helps.
This is a workaround, but you could probably install your own message handler. Take a look at qInstallMsgHandler in the documentation if you have not done so already.
I have a similar issue on Ubuntu 9.10 with Qt Creator 2.0 and Qt 4.7.0, though I don't see stdout output until the application is closed. It is as if the buffer isn't flushed.
Printing to stderr shows the output in the Application output window immediately though.
fprintf(stderr, "Test1 \n"); // Prints immediately
fprintf(stderr, "Test2 \n\r"); // Prints immediately
fprintf(stdout, "Test3 \n"); // Delayed until app termination
fprintf(stdout, "Test4 \n\r"); // Delayed until app termination
qDebug() << "Test6 \n\r"; // Does not print at all
None of these answers were right for me (Arch linux user). Rather than try to explain my troubles, here is a .pro file that worked. I'm not using the QT thread loop, purely just a simple main() that does stuff and exists. I'm using cout for my output:
QT += core
QT -= gui
CONFIG += c++14
TARGET = evo
#CONFIG += console
CONFIG -= app_bundle
#CONFIG += qt
#OUTPUT += console
TEMPLATE = app
SOURCES += main.cpp \
individual.cpp \
node.cpp \
tree.cpp
HEADERS += \
individual.h \
node.h \
tree.h
If Anyone is still looking for an answer, this is what I did:
In Debug tab go to build
under build select debug not release or profile
While running your application click the Application Output tab
Then you will see all your debugs message if you used a "qDebug()" macro.
my 2 cents contrib, in your main, just before a.exec :
qputenv("QT_ASSUME_STDERR_HAS_CONSOLE", "1");

Resources