如何显示api函数的输出?

时间:2014-02-20 21:53:09

标签: c++ multithreading qt

对不起基本问题。我正试图在QPlainTextWidget中显示json。我有api函数,它有控制台输出并包含所有需要的数据。看起来像这样:

 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;
}

现在我的第一个线程是我的gui,第二个线程包含在信号上运行此函数的类。一切正常,但我不完全理解,我怎么能“停止”iperf_run_server“读取/缓冲”输出,而没有api的任何变化。

1 个答案:

答案 0 :(得分:0)

最简单的方法是收集字符串中的每条消息,并从第二个线程中运行的对象发出信号。您可以将该信号连接到GUI线程中对象的插槽。每次完成事件循环处理其他事件时,都会调用零超时计时器 - 这是一种有用的机制,可以“持续”地运行事物。

例如:

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"