How to insert a command line to GUI applications [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I need to make a QT GUI application that will be able to run the command line batchs and commands. For example, ping, tcpdump, etc. ...
I would imagine it like this:
The standard graphical window with the QTableView, some checkboxes, etc. ... with a component instance QPlainTextEdit. This component (QPlainTextEdit) will act as a command line, that will allow to enter commands and capture their output.
Is such a thing possible? How should this be done?

You can use QProcess for your purpose..
QProcess cmd;
cmd.start("cmd");
More details here..
http://www.qtcentre.org/threads/12757-QProcess-cmd

The main idea is to use QProcess for running commands. See the code below for demonstration.
Sync approach
QProcess process;
// If "command" is not in your path,
// use the corresponding relative or absolute path
process.start("command", QStringList()
<< QString("-arg1")
<< QString("arg2")
<< QString("-arg3")
<< QString("arg4"));
// Wait for it to start
if(!process.waitForStarted())
return 0;
bool retval = false;
QByteArray buffer;
while ((retval = process.waitForFinished()));
buffer.append(process.readAll());
if (!retval) {
yourPlainTextEdit.appendPlainText(process.errorString());
} else {
yourPlainTextEdit.appendPlainText(buffer);
}
Async approach
MyClass::MyClass(QQProcess *process, QObject *parent)
: QObject(parent)
, m_process(process)
{
connect(m_process, SIGNAL(readyRead()), SLOT(handleReadyRead()));
connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(handleError(QProcess::ProcessError)));
connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
m_timer.start(5000);
}
MyClass::~MyClass()
{
}
void MyClass::handleReadyRead()
{
m_readData.append(m_process->readAll());
if (!m_timer.isActive())
m_timer.start(5000);
}
void MyClass::handleTimeout()
{
if (m_readData.isEmpty()) {
yourPlainTextEdit.appendPlainText("No data was currently available for reading from gnuplot");
} else {
yourPlainTextEdit.appendPlainText("Process successfully run");
}
}
void GnuPlotReader::handleError(QProcess::ProcessError processError)
{
if (processError == QProcess::ReadError) {
appendPlainTextEdit.appendPlainText("An I/O error occurred while reading the data, error: %1").arg(m_process->errorString()));
yourPlainTextEdit.appendPlainText(m_readData);
}
}
Disclaimer: This is fully untested code, so it may have compiler and run time issues, but this should give a good grasp of it without further ado.

Related

QT - slot preemption / interrupt

I'm trying to write an app for testing ST board via serial port and I'm currently facing the following issue. (The code below is just a simplification of a problem.)
Widget::Widget(QWidget *parent)
: QWidget(parent)
, m_button(new QPushButton(this))
, m_timer(new QTimer(this))
{
m_timer->setSingleShot(true);
connect(m_button, &QPushButton::released, this, &Widget::RunTest);
connect(m_timer, &QTimer::timeout, this, &Widget::OnTimeout);
}
void Widget::RunTest()
{
qDebug() << "Start test";
m_timer->start(1000);
while (m_timeout != true);
qDebug() << "Start end";
}
void Widget::OnTimeout()
{
qDebug() << "Timeout";
m_timeout = true;
}
I want to have a seprate class for gathering and running tests. The tests are triggered by clicking on a button. Some tests will have to send data via serial port and wait for the reply. I would like to be able to implement a timeout feature (if board doesn't reply then finish test with failure). However I the app is waiting for the m_timeout flag indefinitely. So my question is: Is there any signal/slot mechanism similar to interrupt preemption? If no how sush problems are solved in Qt? Shall I create seprate QTimer object and run it in separate thread?

Sleep inside QTConcurrent run method

I'm using QtConcurrent::run to execute some functions in background and not hang the GUI thread. In one function, I read logs from local SQlite database and send them to server by TCP socket.
Now I want to delay the execution after each log so the server has time to save it (TCP response is read in different thread). I'm stuck with Qt4.8 due to implementation limitations (many embeded devices - no chance to upgrade QT on them) and I can't use QThread::sleep(2) because it is protected in 4.8.
Is it possible to somehow pause the execution of thread inside QtConcurrent::run method or should I redesign it to implement my own class inheriting QThread?
void MainWindow::ReportFinishedHUs(bool asyncWork)
{
if(asyncWork == false)
{
QMutexLocker locker(&localDBmutex);
QList<QSqlRecord> HUsToReport = localDB->getHUsForBook();
qDebug() << "HUs to report" << HUsToReport.count();
if(!HUsToReport.isEmpty())
{
Cls_log::WriteDebugLog("HUs to report: " + QString::number(HUsToReport.count()));
foreach (QSqlRecord record, HUsToReport)
{
int _hu = record.indexOf("hu");
int _logTime = record.indexOf("logTime");
QString logTimeString = record.value(_logTime).toString();
QString hu = record.value(_hu).toString();
qDebug() << hu << logTimeString;
// creating message here ...
qDebug() << message;
emit sig_SendTCPMessage(message);
// this is where I need to wait for 2 seconds
QThread::sleep(2);
}
}
}
else
{
QtConcurrent::run(this, &MainWindow::ReportFinishedHUs, false);
}
}
EDIT:
Solved by usleep(2000000) which I somehow discarded for being platform specific... but hey, half of my aplication is platform specific and I only use it in embeded device with constant OS.
Keeping the question open if anyone can suggest more elegand solution using Qt methods. I like to get inspired.

Run two functions at the same time [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have two functions. How would i run two functions at the same time? I Know should use threading.
I need a example for Multi Threading . I am using Visual Studio 2010
You can use _beginthread
void CalculatePrimes(void*)
{
// Do something
}
void TransmitFile(void*)
{
// Do domething
}
int main()
{
uintptr_ x = _beginthread(CalculatePrices,0,NULL);
uintptr_ y = _beginthread(TransmitFile,0,NULL);
return 0;
}
If you've got access to C++11 you can use std::thread :
void CalculatePrimes()
{
// Do something
}
void TransmitFile()
{
// Do domething
}
int main()
{
std::thread x(CalculatePrices);
std::thread y(TransmitFile);
// Both function are now running an different thread
// We need to wait for them to finish
x.join();
y.join();
return 0;
}
And, if you want to get down to the metal you can use the CreateThread api :
DWORD WINAPI CalculatePrimes(void *)
{
// Do something
return 0;
}
DWORD WINAPI TransmitFile(void *)
{
// Do something
return 0;
}
int main()
{
HANDLE x=::CreateThread(NULL,0,CalculatePrimes,NULL,0,NULL);
HANDLE y=::CreateThread(NULL,0,CalculatePrimes,NULL,0,NULL);
// Wait for them to finish
::WaitForSingleObject(x,INFINITE);
::WaitForSingleObject(y,INFINITE);
return 0;
}
The MSDN reference for < thread > only goes back to VS2012,not VS2010. You could update to VS2012 (you also need to be running Win 7 or Win 8) Here is a link to a zip of a windows console program written in C that copies a file using two threads, creating a thread to do the writes. It uses windows mutexes and semaphores to implement an inter-thread single linked list messaging interface.
mtcopy.zip
If you are using MFC, you could use AfxBeginThread to create a CWinThread:
UINT SomeFunction(LPVOID pParam)
{
CSomeObject * pObject = (CSomeObject*)pParam;
// do stuff
return 0; // thread completed successfully
}
int main()
{
CSomeObject pObject = new CSomeObject;
AfxBeginThread(SomeFunction, pObject);
...
return 0;
}
For more information, see MSDN for AfxBeginThread.

Qt: How to catch an error with system call?

I am building a GUI application where I do a system call and call for gnuplot to run a script. Now i want to build in an error message that says when something is wrong (e.g. gnuplot is not installed or in the wrong path).
So I've been thinking about just putting out a QMessageBox, but I don't know how I can check whether the system call succeeded or not.
if(//System call didn't work)
{
QMessageBox msgBox;
msgBox.setWindowTitle("Error");
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText("GNUPLOT was not installed");
msgBox.exec();
}
My system call looks like this:
system(gnuplot script.txt);
Any suggestions?
You should use QProcess rather than low-level system call because it is a nice abstraction in a Qt codebase. Otherwise, you will end up dealing with platform specific bits. QProcess already solves that for you. If you happen to be fine with a blocking approach, aka. sync, you could write something like that code below.
QProcess process;
process1.start("gnuplot arg1 arg2 etc");
// Wait for it to start
if(!process.waitForStarted())
return 0;
bool retval = false;
QByteArray buffer;
while ((retval = process.waitForFinished()));
buffer.append(process.readAll());
if (!retval) {
qDebug() << "Process 2 error:" << process.errorString();
msgBox.setText(buffer);
return 1;
}
If you would not like to block while the gnuplot script of yours is running, you could connect a slot, or simply lambda with C++11 and on, to the readyRead() signal. For sure, you would also need to connect to the error() signal. The code without lambda to work with pre C++11 environments would look something like this:
GnuPlotReader::GnuPlotReader(QQProcess *process, QObject *parent)
: QObject(parent)
, m_process(process)
, m_standardOutput(stdout)
{
connect(m_process, SIGNAL(readyRead()), SLOT(handleReadyRead()));
connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(handleError(QProcess::ProcessError)));
connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
m_timer.start(5000);
}
GnuPlotReader::~GnuPlotReader()
{
}
void GnuPlotReader::handleReadyRead()
{
m_readData = m_process->readAll();
if (!m_timer.isActive())
m_timer.start(5000);
}
void GnuPlotReader::handleTimeout()
{
if (m_readData.isEmpty()) {
m_standardOutput << QObject::tr("No data was currently available for reading from gnuplot") << endl;
} else {
m_standardOutput << QObject::tr("GnuPlot successfully run")<< endl;
}
}
void GnuPlotReader::handleError(QProcess::ProcessError processError)
{
if (processError == QProcess::ReadError) {
m_standardOutput << QObject::tr("An I/O error occurred while reading the data, error: %2").arg(m_process->errorString()) << endl;
messageBox.setText(m_readData);
}
}

How to start a executable within a C++ program and get its process id (in linux)? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
i tried system(), but somehow when the secondary program runs, my main program(primary program which executes the secondary) hangs
and second issue is how do i obtain the process id of the secondary program in my main program?
In the parent process you want to fork.
Fork creates an entirely new process and returns either the child process's pid to the calling process, and 0 to the new child process.
In the child process you can then use something like execl to execute your desired secondary program.
In the parent process you can use waitpid to wait for the child to complete.
Here is a simple illustrative example:
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
int main()
{
std::string cmd = "/bin/ls"; // secondary program you want to run
pid_t pid = fork(); // create child process
int status;
switch (pid)
{
case -1: // error
perror("fork");
exit(1);
case 0: // child process
execl(cmd.c_str(), 0, 0); // run the command
perror("execl"); // execl doesn't return unless there is a problem
exit(1);
default: // parent process, pid now contains the child pid
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
{
// handle error
std::cerr << "process " << cmd << " (pid=" << pid << ") failed" << std::endl;
}
break;
}
return 0;
}
Use fork to create a new process, then exec to run a program in the new process. There are many such examples.