[SOLVED] Streaming Text Continuously to QTextEdit Without Creating File
-
wrote on 24 Mar 2014, 04:45 last edited by
I want to make a GUI with a QTextEdit to show
@sudo apt-get update@
command standard output (Ubuntu) continuously. In short, I want to make my program looks like Synaptic Package Manager when doing installation:
!http://malsasa.files.wordpress.com/2014/03/apt-get-okular112.png!
I want my program to start apt-get command (have done) then read all the standar output + standard error, and show them all in QTextEdit continuously. I want to do it without creating a temporary file or any text file. Any solution to do it? I have used these classes:
- QTextStream
- QFile
Here is my approach until now (code + screenshot):
@void MainWindow::redirect_output()
{
QProcess Proses;
Proses.readAllStandardError();
Proses.readAllStandardOutput();
Proses.setStandardOutputFile("update.txt", QIODevice::Append);
Proses.setStandardErrorFile("update.txt", QIODevice::Append);
Proses.start("sh", QStringList() << "-c" << "gksudo apt-get update");
QFile data("update.txt");
QTextStream streamer(&data);
if(data.open(QFile::ReadOnly))
{
QString penampung;
penampung = streamer.readAll();
this->keluaranKonsol->setText(penampung);
}
Proses.waitForFinished(-1);
Proses.close();
}@!http://malsasa.files.wordpress.com/2014/03/apt-get-okular113.png!
Weakness:
My code above only creates a file named update.txt, then do apt-get command, then save all standard output and standard error to update.txt, then read the update.txt to QTextEdit. My code doesn't delete update.txt or at least empty that file.
Questions:
If using my code: how to delete the update.txt (or empty the content) when program exit?
If using another solution: how to transfer continuously text from standard output/standard error to my QTextEdit?
Thank you so much.
-
wrote on 24 Mar 2014, 05:02 last edited by
Disclamer: I have not tried it. Just my guess.
You may use "QProcess":http://qt-project.org/doc/qt-5/QProcess.html#communicating-via-channels
channels to read data as soon as it is available.
Connect your MainWindow to @QProcess::readyReadStandardOutput()@and to @QProcess::readyReadStandardError()@
When the signals are emitted read all available data using
@QProcess::readAllStandardOutput()@
or
@QProcess::readAllStandardError()@
and display whatever you've got to
@QTextStream@
or other output widget.
-
wrote on 24 Mar 2014, 05:25 last edited by
So fast! Thank you for your response. I will try your solution.
-
wrote on 25 Mar 2014, 06:23 last edited by
[quote author="andreyc" date="1395637332"]
[/quote]
I have edited my code until this:@void MainWindow::redirect_output()
{
QProcess Proses;
Proses.readAllStandardError();
Proses.readAllStandardOutput();
Proses.readyReadStandardError(); //here
Proses.readyReadStandardOutput(); //and here
Proses.setStandardOutputFile("update.txt", QIODevice::Append);
Proses.setStandardErrorFile("update.txt", QIODevice::Append);
Proses.start("sh", QStringList() << "-c" << "gksudo apt-get update");
QFile data("update.txt");
QTextStream streamer(&data);
if(data.open(QFile::ReadOnly))
{
QString penampung;
penampung = streamer.readAll();
this->keluaranKonsol->setText(penampung);
}
Proses.waitForFinished(-1);
Proses.close();
}@but my Qt Creator says:
@error: 'void QProcess::readyReadStandardError()' is protected@
and same with Standard Output. Actually I have low experience with Qt and C++. Maybe my code was wrong. How to write the correct code? Thank you.
-
wrote on 25 Mar 2014, 15:11 last edited by
readyReadStandardError() and readyReadStandardOutput() are the signals you should not call them. The QProcess object will emit these signals and your MainWindow object should connect its slots to these signals.
Inside the slots you will call Proses.readAllStandardError() and Proses.readAllStandardOutput() to get data.I would suggest you to read about "Signal and Slots in Qt":http://qt-project.org/doc/qt-5/signalsandslots.html first and try the simple examples.
-
wrote on 28 Mar 2014, 10:17 last edited by
[quote author="andreyc" date="1395760308"]...[/quote]
Thank you, Mr Andrey. My problem was solved by searching on Google for this problem and I found a biggest clue at http://minhazulhaque.blogspot.com/2012/07/read-shell-command-output-using.html and I have modificated the code to suit my need. Once again: SOLVED.
Here is my complete code now.
mainwindow.h
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QtGui>
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QPushButton *tombolOke;
QWidget *widgetUtama;
QVBoxLayout *layoutUtama;
QTextEdit *keluaranKonsol;public slots:
void redirect_output();
void hapus_isi_teks();
void tunjukkan_bahwa_kamu_mati();private slots:
void ambillah_datanya();private:
Ui::MainWindow *ui;
QProcess *prosesku;
};#endif // MAINWINDOW_H@
mainwindow.cpp
@#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
this->setGeometry(333, 333, 355, 355);
QPushButton *tombolOke = new QPushButton;
QVBoxLayout *layoutUtama = new QVBoxLayout;
QWidget *widgetUtama = new QWidget;
keluaranKonsol = new QTextEdit;
prosesku = new QProcess;tombolOke->setText("NOTHING TO SAY");
// keluaranKonsol->setTextBackgroundColor("RED");
layoutUtama->addWidget(tombolOke); layoutUtama->addWidget(keluaranKonsol); prosesku->setProcessChannelMode(QProcess::MergedChannels); //menghitamkan background dari QTextEdit dengan CSS keluaranKonsol->setStyleSheet("QTextEdit { background-color : black; color : white; }"); //membuat scrollbar selalu otomatis mengikuti kursor terbawah //dipasang pada Wednesday, March 26, 2014 05:39 PM dari dokumentasi Qt keluaranKonsol->ensureCursorVisible(); widgetUtama->setLayout(layoutUtama); this->setCentralWidget(widgetUtama); connect(tombolOke, SIGNAL(clicked()), this, SLOT(redirect_output())); //teknik S&S baru ini didapatkan pada Tuesday, March 25, 2014 dari http://minhazulhaque.blogspot.com/2012/07/read-shell-command-output-using.html //juga bisa didapatkan dari http://www.qtcentre.org/threads/47538-QProcess-read-from-stdout-lively connect(prosesku, SIGNAL(readyRead()), this, SLOT(ambillah_datanya())); //teknik pembacaan kematian proses ini ditemukan pada Wednesday, March 26, 2014 05:18 PM dari perkiraan dan dokumentasi Qt connect(prosesku, SIGNAL(finished(int)), this, SLOT(tunjukkan_bahwa_kamu_mati()));
// connect(prosesku, SIGNAL(readyReadStandardError()), this, SLOT(ambillah_datanya()));
}
//satu
MainWindow::~MainWindow()
{
delete ui;
}//dua
void MainWindow::hapus_isi_teks()
{}
//tiga
void MainWindow::redirect_output()
{
prosesku->start("sh", QStringList() << "-c" << "apt-get update");
// prosesku->start("sh", QStringList() << "-c" << "tailf /var/log/syslog");
}//empat
void MainWindow::ambillah_datanya()
{
//teknik appending ini ditemukan pada Tuesday, March 25, 2014 05:07 PM dari http://www.jcjc-dev.com/2013/03/qt-48-appending-text-to-qtextedit.html
this->keluaranKonsol->moveCursor(QTextCursor::End);
this->keluaranKonsol->insertPlainText(prosesku->readAll());
this->keluaranKonsol->moveCursor(QTextCursor::End);
// this->keluaranKonsol->setPlainText(prosesku->readAllStandardError());
}void MainWindow::tunjukkan_bahwa_kamu_mati()
{
this->keluaranKonsol->insertPlainText("\n\n===PROSES SELESAI===\n\n");
}@This is the screenshot of the result:
!http://i.imgur.com/0VMb0zC.png!
Do you know? Perfectly what I want.
Sorry for late response here. Actually I have solved this problem completely at Tuesday, March 25, 2014 ago but just now I come back. And finally my conclusion is: the realtime reading for standard output (and error too) in Linux by using QProcess is by using SIGNAL AND SLOT between the QProcess object and function to do readAll(). The reading function not related directly to the button click function, different with what I thought before I made this thread. Now I understand, at least more than before. Thank you for all your supports.
5/6