Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Streaming Text Continuously to QTextEdit Without Creating File

[SOLVED] Streaming Text Continuously to QTextEdit Without Creating File

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 8.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Ade Malsasa Akbar
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andreyc
      wrote on last edited by
      #2

      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.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Ade Malsasa Akbar
        wrote on last edited by
        #3

        So fast! Thank you for your response. I will try your solution.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Ade Malsasa Akbar
          wrote on last edited by
          #4

          [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.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andreyc
            wrote on last edited by
            #5

            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.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              Ade Malsasa Akbar
              wrote on last edited by
              #6

              [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_OBJECT

              public:
              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.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved