Qprocess and avrdude - qt

i'm trying to create a simple QT program that allows me to launch avrdude without using command line operations.
I saw that with Qprocess it's easy to launch any kind of program and I tried succesfully with simple programs like Explorer Word and Others.
The problem is that when i try to open cmd.exe nothing happens, even if i try to pass a batch file containing all the information to launch correctly avrdude.
Here's the code
QProcess *process = new QProcess(this);
process->startDetached("cmd.exe",QStringList()<<"C:/avrdude/avr.bat");

I wrote a minimal sample application which shows how to start cmd with a command using QProcess::startDetached() (on button click):
// standard C++ header:
#include <iostream>
// Qt header:
#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QProcess>
int main(int argc, char **argv)
{
// main application
#undef qApp // undef macro qApp out of the way
QApplication qApp(argc, argv);
QMainWindow qWin;
QPushButton qBtn(QString::fromLatin1("Start cmd"));
QObject::connect(&qBtn, &QPushButton::clicked,
[](bool) {
bool ret = QProcess::startDetached(
#if 1 // let Windows search for cmd.exe in %PATH%
QString::fromLatin1("cmd.exe"),
#else // define exact path of cmd.exe
QString::fromLatin1("C:\\Windows\\system32\\cmd.exe"),
#endif // 1
QStringList()
<< QString::fromLatin1("/K")
<< QString::fromLatin1("echo Hello"));
std::cout << "QProcess::startDetached():"
<< (ret ? "OK." : "Failed!") << std::endl;
});
qWin.setCentralWidget(&qBtn);
qWin.show();
return qApp.exec();
}
The Qt project file is left as exercise. (Sorry, I used CMake for this.)
Please, note the #if 1. If 1 is replaced by 0 the alternative code with full path is used. (During chat session we examined special problems with starting the cmd.exe.) On my system, both alternatives did as well.
(My system: Windows 10, VS2013, Qt 5.7)

I too have been working on a Qt program where there are a couple calls to AVRDUDE. This is what worked for me. Here's the code I made for a read of the AVR device through AVRDUDE, followed by a couple of comments.
void MainWindow::call_AVRDUDE_read() //AVR READ
{
QProcess CommandPrompt;
QStringList Arguments;
QString COMPortUsed = (ui->COM_Port_Used->text()); // get the COM port from the user off UI
Arguments << "/C avrdude -c arduino -P "+ COMPortUsed +" -b 115200 -p ATmega328P -e -U eeprom:r:fromEEPROM.bin:r";
CommandPrompt.start("cmd",Arguments);
CommandPrompt.waitForFinished();
}
Here's something else which may well influence things in your application. In my case, I am reading the AVR's EEPROM. There is another routine that writes the EEPROM, but it is essentially the same as above, but a different script is sent.
In BOTH these cases, the AVRDUDE operation takes a few seconds to perform its task. When you use the QProcess::startDetached(), it has the disadvantage that control will return IMMEDIATELY after the AVRDUDE script is called through the QProcess. This can cause problems, if for instance you wanted to (as in my case) read the contents of the EEPROM and try to do so before the read actually completes.
An alternative to startDetached() you might consider trying is shown below. This will retain control until the process is finished, which may be pretty important to you. Use these two lines to replace the startDetached() call you are currently using.
CommandPrompt.start("cmd",Arguments);
CommandPrompt.waitForFinished();
This will wait for the AVRDUDE process to finish before control is returned.
The take away here though is that QProces::startDetached() may return prematurely in your application. Just beware of that.

Related

catch that new QApplication failed and try something else

I have two programs. One call SelectScreen and another called RadioPanel.
SelectScreen sends a message to RadioPanel telling it what screen its supposed to display the gui on.
RadioPanel uses setenv("DISPLAY", myHostslist[hostId].c_str(),true); to set the DISPLAY environment variable. Then a mQtApplication = new QApplication(mArgc, mArgv); to start the gui.
This works as long as the host info is correct. However if it is not correct QApplication causes the program to end. What I want to do is catch the fact that QApplication failed and try to run the gui on ":0"
I tried using a try catch block but it will not catch. My guess is that QApplication just ends the process and does not throw an exception in this case.
Does anyone know if there is a way to determine if QApplication is going to fail or respond to that failure.
The message I get from QApplication when it fails is:
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, xcb.```
I found a solution. If you use XOpenDisplay you can check the return to confirm that the X Server display is working before you attempt to create the QApplication.
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
void myUiApplication::qtGuiThread()
{
Display *dis;
dis=XOpenDisplay((char *)0);
if(dis!=nullptr)
{
XCloseDisplay(dis);
mQtApplication = new QApplication(mArgc, mArgv);
} else
{
CCS_ERR("Failed to display on host:" << cds::toString(mCdsId) << " "
<< mCdsHosts[mCdsId].c_str() << ".\nPlease edit the "
<< getConfigFileName() << " file. Attempting to run GUI on local X Server.");
setenv("DISPLAY",":0",true);
mQtApplication = new QApplication(mArgc, mArgv);
}
}

Any example of how to integrate Qt in some ROS package?

I would like to use an QT as an user interface for my mobile platform. I have a sensor package consist of IMU , Laser, Kinect and wheel encoders. Would like to have an input button that run a rose node than do something with the data and gives an output results. I was told that should set up like any other Qt + CMake project.
I have used the simple example
#include "QDebug"
#include "ros/ros.h"
int main(int argc, char** argv)
{
ros::init(argc, argv, "Qt_test");
qDebug()<<"Hello world";
return 0;
}
Than successfuly made the CmakeList file. I could compile it with make. But when I tried to run it with `./test_qt` I got this error
bash: ./test_qt: No such file or directory
An help
Thanks
You must use some package like this http://wiki.ros.org/qt_tutorials?distro=hydro.
And using cmake for build your project. In the case who you want use qtcreator you must call the ide by a command-line. But before, your bash must know the path of ROS installation.
1 - type that in your bash: source devel.setup.bash
2 - create your qtRos node/package in your catkin workspace.
3 - call qtcreator in command line

How to get executable name in Qt

I run a Qt application, what I want to know is this running binary file name.
I must (partially) disagree with the other comments that it is not a Qt question: There is a Qt method QCoreApplication::applicationFilePath() which gives the directory+filename of the executable.
On Linux this will try to use /proc, and on Windows perhaps GetModuleFileName(). According to the docs it will fall back to argv[0].
You could then use QFileInfo to split it into an executable name and a directory.
QFileInfo(QCoreApplication::applicationFilePath()).fileName()
The Qapplication parses the commandline arguemnts, the first entry is the name of the executable - this is roughly the same as argv[0] in standard C but has a few extra complexities on windows if you have a Unicode build or if the application is started as a service
See http://doc.qt.io/qt-5/qcoreapplication.html#arguments
Again not really a Qt question. To find the name of the binary file executed it would be something like.
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
cout << argv[0] << endl;
return 0;
}

Why is Qt reporting > 14000 errors in this one page source file?

Here is the code:
#include <QtCore/QCoreApplication>
#include <QProcess>
#include <QProcessEnvironment>
int main(int argc, char *argv[])
{
QProcessEnvironment env;
// Environment variables required by CGI apps
env.insert("QUERY_STRING", url.encodedQuery());
env.insert("REQUEST_URI", url.toString());
env.insert("REQUEST_METHOD", "GET");
env.insert("REMOTE_ADDR", pSocket->peerAddress().toString());
//==========
QProcess process;
process.setProcessEnvironment(env);
process.start("php-cgi",QProcess::ReadWrite);
process.write("<?php print_r($_GET); ?>");
process.closeWriteChannel();
process.waitForFinished();
qDebug(process.readAll().data());
return 0;
}
Qt Creator reports more than 14000 errors. Here is a small sample of them:
In file included from ../QProcess/main.cpp:2:
../QProcess/QProcess:1: error: stray ‘\177’ in program
../QProcess/QProcess:1: error: stray ‘\2’ in program
../QProcess/QProcess:1: error: stray ‘\1’ in program
../QProcess/QProcess:1: error: stray ‘\1’ in program
In file included from ../QProcess/main.cpp:2:
../QProcess/QProcess:1:8: warning: null character(s) ignored
../QProcess/QProcess:1: error: stray ‘\2’ in program
Here is a simple example instance of this error. The contents of a file called new.cpp:
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "Brand new." << std::endl;
return 0;
}
Now compile it:
ppu32-g++ new.cpp -o new
No problem. Let's compile it again:
ppu32-g++ new.cpp -o new
OMG! Screen after screen of errors! Most of these errors look like this:
./new:1: error: stray '\177' in program
The problem is that the compiler is trying to use the new file in the current directory, as the C++ standard library <new>; used by <iostream>. In fact any file in the current directory, named after a C++ standard library header, which is used in the code being compiled, will likely cause an error. That our problem file is an executable obfuscates the error messages.
It doesn't occur on all the gcc machines I've tried. ppu32-g++ 4.1.1 on PS3 Cell Fedora Linux certainly chokes.
If that problem arises not on every host then probably difference in the compiler. Difference is likely in the header files directory scan order.
Such error should not arise if standard headers directory scanned before others.
As a workaround its enough to remove project target file manually befor building target. But this is not a programmers way (which are very lazy creatures).
Programmers way - is to learn QMake to delete target file just before project sources compilations (but under this way link phase will be done permanently). For me (QMake 2.01a under Linux) this is achived by addition of following lines into project file:
deltarget.commands = $$QMAKE_DEL_FILE $$TARGET
QMAKE_EXTRA_TARGETS += deltarget
PRE_TARGETDEPS += deltarget
This declares target deltarget which becomes built before current project.
This sample uses undeclared in QMake's manual variable QMAKE_DEL_FILE which used to remove files (its content of course platfrom-dependent).

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