/* * QDebugStream.hpp * * Created on: Jun 19, 2014 * Author: heber */ #ifndef QDEBUGSTREAM_HPP_ #define QDEBUGSTREAM_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include /** This class connects an output stream, such as std::cout, and a QTextEdit. * * It works by overriding certain streambuf functions such as xsputn() and * overflow(). * * This code is copied from the questions posted here * http://stackoverflow.com/questions/10308425/redirect-stdcout-to-a-qtextedit * which worked right away. */ class QDebugStream : public std::basic_streambuf { public: QDebugStream(std::ostream &stream, QTextEdit* text_edit) : m_stream(stream) { log_window = text_edit; m_old_buf = stream.rdbuf(); stream.rdbuf(this); } ~QDebugStream() { // output anything that is left if (!m_string.empty()) { change_mutex.lock(); log_window->append(m_string.c_str()); qDebug() << m_string.c_str(); change_mutex.unlock(); } m_stream.rdbuf(m_old_buf); } protected: virtual int_type overflow(int_type v) { if (v == '\n') { change_mutex.lock(); log_window->append(m_string.c_str()); qDebug() << m_string.c_str(); m_string.erase(m_string.begin(), m_string.end()); change_mutex.unlock(); } else m_string += v; return v; } virtual std::streamsize xsputn(const char *p, std::streamsize n) { change_mutex.lock(); m_string.append(p, p + n); change_mutex.unlock(); size_t pos = 0; while (pos != std::string::npos) { pos = m_string.find('\n'); if (pos != std::string::npos) { std::string tmp(m_string.begin(), m_string.begin() + pos); change_mutex.lock(); log_window->append(tmp.c_str()); qDebug() << tmp.c_str(); m_string.erase(m_string.begin(), m_string.begin() + pos + 1); change_mutex.unlock(); } } return n; } private: std::ostream &m_stream; std::streambuf *m_old_buf; std::string m_string; QTextEdit* log_window; QMutex change_mutex; }; #endif /* QDEBUGSTREAM_HPP_ */