I'm trying to write an editor for the ruby programming language using Qt 4. This editor should be able to run a ruby script written by the user and display the output and error messages from the script in a QListView, using a different color for the latter. To do this, I use a QProcess. I connect the readyReadStandardError and readyReadStandardOutput signals from the process with two slots which set the read channel respectively to StandardError and StandardOutput, read the content of the channel and display them.
Having written this code, I tried running a ruby script which, for 10 times, writes a string to standard error and one to standard output. The result should have been this:
warning 0
message 0
warning 1
message 1
...
warning 9
message 9
where the warnings are the text written to standard error and the messages are the text written to standard output. Instead, what I got is this:
warning 0
warning 1
...
warning 9
message 0
message 1
...
message 9
Besides, the slots connected to the readyStandardError and readyStandardOutput are called only once, while I expected each of them to be called ten times (one for each message). Does anyone know what I'm doing wrong or how to achieve the result I want?
Here's a simplified version of the application. It consists of a simple QPushButton which launches the ruby script and writes the output to the terminal.
This is the header file for the MyApp class, which contains the QProcess:
#ifndef MYAPP_H
#define MYAPP_H
#include <QApplication>
#include <QProcess>
Q_OBJECT
public:
MyApp(int argc, char ** argv);
~MyApp();
public slots:
void displayOutputMsg();
void displayErrorMsg();
void runRuby();
private:
};
#endif
#ifndef MYAPP_H
#define MYAPP_H
#include <QApplication>
#include <QProcess>
class MyApp: public QApplication{
Q_OBJECT
public:
MyApp(int argc, char ** argv);
~MyApp();
public slots:
void displayOutputMsg();
void displayErrorMsg();
void runRuby();
private:
QProcess * m_proc;
};
#endif
To copy to clipboard, switch view to plain text mode
and here's the implementation:
#include "app.h"
#include <iostream>
#include <string>
#include <QStringList>
connect(m_proc, SIGNAL(readyReadStandardOutput()),this, SLOT(displayOutputMsg()));
connect(m_proc, SIGNAL(readyReadStandardError()),this, SLOT(displayErrorMsg()));
}
MyApp::~MyApp(){}
void MyApp::displayOutputMsg(){
m_proc
->setReadChannel
(QProcess::StandardOutput);
std::cout << "Output: "<< (msg.data())<<"\n";
}
void MyApp::displayErrorMsg(){
m_proc
->setReadChannel
(QProcess::StandardError);
std::cout << "Error: "<< (msg.data())<<"\n";
}
void MyApp::runRuby(){
args << "-w" << "/home/stefano/documenti/scripts/prova.rb";
m_proc->start("ruby", args);
}
#include "app.h"
#include <iostream>
#include <string>
#include <QStringList>
MyApp::MyApp(int argc, char ** argv): QApplication(argc, argv), m_proc(new QProcess(this)){
connect(m_proc, SIGNAL(readyReadStandardOutput()),this, SLOT(displayOutputMsg()));
connect(m_proc, SIGNAL(readyReadStandardError()),this, SLOT(displayErrorMsg()));
}
MyApp::~MyApp(){}
void MyApp::displayOutputMsg(){
m_proc->setReadChannel(QProcess::StandardOutput);
QByteArray msg = m_proc->read(1000);
std::cout << "Output: "<< (msg.data())<<"\n";
}
void MyApp::displayErrorMsg(){
m_proc->setReadChannel(QProcess::StandardError);
QByteArray msg = m_proc->read(1000);
std::cout << "Error: "<< (msg.data())<<"\n";
}
void MyApp::runRuby(){
QStringList args;
args << "-w" << "/home/stefano/documenti/scripts/prova.rb";
m_proc->start("ruby", args);
}
To copy to clipboard, switch view to plain text mode
This is the main.cpp file:
#include "app.h"
#include <QPushButton>
#include <QWidget>
#include <QLayout>
int main(int argc, char ** argv){
MyApp * app = new MyApp(argc, argv);
l->addWidget(ruby);
// QPushButton * python = new QPushButton("Run &python", w);
// l->addWidget(python);
app->connect( ruby, SIGNAL(clicked()), SLOT(runRuby()));
// app->connect( python, SIGNAL(clicked()), SLOT(runPython()));
w->show();
app->exec();
}
#include "app.h"
#include <QPushButton>
#include <QWidget>
#include <QLayout>
int main(int argc, char ** argv){
MyApp * app = new MyApp(argc, argv);
QWidget * w = new QWidget;
QLayout * l = new QHBoxLayout(w);
QPushButton * ruby = new QPushButton("Run &ruby", w);
l->addWidget(ruby);
// QPushButton * python = new QPushButton("Run &python", w);
// l->addWidget(python);
app->connect( ruby, SIGNAL(clicked()), SLOT(runRuby()));
// app->connect( python, SIGNAL(clicked()), SLOT(runPython()));
w->show();
app->exec();
}
To copy to clipboard, switch view to plain text mode
Thanks in advance
Bookmarks