0

Sorry for basic question. I'm trying to show json in QPlainTextWidget. I have api function which have console output and contains all needed data. Looks like that:

 int iperf_run_server(struct iperf_test *test)
 {
int result, s, streams_accepted;
fd_set read_set, write_set;
struct iperf_stream *sp;
struct timeval now;
struct timeval* timeout;
......
if (test->json_output)
    if (iperf_json_start(test) < 0)
        return -1;

if (test->json_output) {
    cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version));
    cJSON_AddItemToObject(test->json_start, "system_info",        cJSON_CreateString(get_system_info()));
} else if (test->verbose) {
    iprintf(test, "%s\n", version);
    iprintf(test, "%s", "");
    fflush(stdout);
    printf("%s\n", get_system_info());
}
.....
cleanup_server(test);

if (test->json_output) {
    if (iperf_json_finish(test) < 0)
        return -1;
} 

....
return 0;
}

For now I have first thread with my gui, and second thread, contains class which run this function on a signal. All things works normally, but i'm not fully understand, how I can "stop" iperf_run_server for "reading/buffering" output, without any changes in api.

MikSer
  • 19
  • 1
  • 5

1 Answers1

0

The simplest thing to do would be to collect each message in a string, and emit a signal from the object running in the second thread. You can connect that signal to a slot in an object in the GUI thread.A zero-timeout timer is invoked each time the event loop is done processing other events - it is a useful mechanism to leverage to run things "continuously".

For example:

screenshot

#include <QApplication>
#include <QPlainTextEdit>
#include <QThread>
#include <QBasicTimer>
#include <QTextStream>

//! A thread that's always safe to destruct.
class Thread : public QThread {
private:
   // This is a final class.
   using QThread::run;
public:
   Thread(QObject * parent = 0) : QThread(parent) {}
   ~Thread() {
      quit();
      wait();
   }
};

class IperfTester : public QObject {
   Q_OBJECT
   struct Test { int n; Test(int n_) : n(n_) {} };
   QList<Test> m_tests;
   QBasicTimer m_timer;
public:
   IperfTester(QObject * parent = 0) : QObject(parent) {
      for (int i = 0; i < 50; ++i) m_tests << Test(i+1);
   }
   //! Run the tests. This function is thread-safe.
   Q_SLOT void runTests() {
      QMetaObject::invokeMethod(this, "runTestsImpl");
   }
   Q_SIGNAL void message(const QString &);
private:
   Q_INVOKABLE void runTestsImpl() {
      m_timer.start(0, this);
   }
   void timerEvent(QTimerEvent * ev) {
      if (ev->timerId() != m_timer.timerId()) return;
      if (m_tests.isEmpty()) {
         m_timer.stop();
         return;
      }
      runTest(m_tests.first());
      m_tests.removeFirst();
   }
   void runTest(Test & test) {
      // do the work
      QString msg;
      QTextStream s(&msg);
      s << "Version:" << "3.11" << "\n";
      s << "Number:" << test.n << "\n";
      emit message(msg);
   }
};

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QPlainTextEdit log;
   // This order is important: the thread must be defined after the object
   // to be moved into the thread.
   IperfTester tester;
   Thread thread;
   tester.moveToThread(&thread);
   thread.start();
   log.connect(&tester, SIGNAL(message(QString)), SLOT(appendPlainText(QString)));
   log.show();
   tester.runTests();
   return a.exec();
   // Here, the thread is stopped and destructed first, following by a now threadless
   // tester. It would be an error if the tester object was destructed while its
   // thread existed (even if it was stopped!).
}

#include "main.moc"
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thanks for help, I've tried with your algorithm. But still no unparsed json in textwidget. – MikSer Feb 24 '14 at 19:35
  • @MikSer First you need to verify that the unchanged code works for you. Then introduce the changes in steps, and verify that things work after each small change. Are you sure that your unparsed json exists and is not an empty string? – Kuba hasn't forgotten Monica Feb 24 '14 at 20:00
  • I found where I have a mistake, a string is empty, when I'm trying to put it in the widget. Thank you. – MikSer Feb 25 '14 at 20:46