cout nach QPlaintext Thread safe

Code-Schnippsel, oder Tipps und Tricks, die einem beim Programmieren mit Qt helfen können.
Antworten
madrich
Beiträge: 7
Registriert: 26. April 2006 00:37

cout nach QPlaintext Thread safe

Beitrag von madrich » 1. Dezember 2008 00:51

Nach einem Code Beispiel von Jochen Ulrich habe ich seine QDebugStream Klasse ein wenig angepasst, damit diese unter QT 4.x läuft. Bei mir scheint diese Implementation jetzt auch Thread sicher zu sein.

Nach dem Einfügen der folgenden Code Zeile, werden alle cout-Ausgaben
in ein QPlainTextEdit Widget (hier ui.logTextEdit) ausgegeben.

Viel Spass damit
Gruss Madrich

Code: Alles auswählen

QDebugStream* _qout = new QDebugStream(std::cout, ui.logTextEdit);
cout << "irgendwas" << endl;

Code: Alles auswählen

#ifndef QDEBUGSTREAM_H
#define QDEBUGSTREAM_H

#include <QObject>
#include <QPlainTextEdit>
#include <QMutex>

///////////////////////////////////////////////////////////////////////////
//
class QDebugStream : public QObject, std::basic_streambuf<char>{

	Q_OBJECT

signals:
	void sendString(QString text);

public:
	QDebugStream(std::ostream &stream, QPlainTextEdit* text_edit) : m_stream(stream){
		log_window = text_edit;
		m_old_buf = stream.rdbuf();
		stream.rdbuf(this);
		
		connect(this, SIGNAL(sendString(QString)), text_edit, SLOT(appendPlainText (QString)));
	}
	~QDebugStream(){
	// output anything that is left
	if (!m_string.empty())
		emit sendString(m_string.c_str());
		//log_window->appendPlainText(m_string.c_str());
		m_stream.rdbuf(m_old_buf);
	}

protected:
	virtual int_type overflow(int_type v){
		mutex.lock();		
		if (v == '\n'){
			emit sendString(m_string.c_str());
			//log_window->appendPlainText(m_string.c_str());
			m_string.erase(m_string.begin(), m_string.end());
		}
		else
			m_string += v;
		
		mutex.unlock();
		return v;
	}

	virtual std::streamsize xsputn(const char *p, std::streamsize n){
		mutex.lock();
		
		m_string.append(p, p + n);
		int 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);
			emit sendString(tmp.c_str());
			//log_window->appendPlainText(tmp.c_str());
			m_string.erase(m_string.begin(), m_string.begin() + pos + 1);
			}
		}
		
		mutex.unlock();
		return n;
	}

private:
	std::ostream &m_stream;
	std::streambuf *m_old_buf;
	std::string m_string;
	QPlainTextEdit* log_window;
	QMutex mutex;
};


#endif // QDEBUGSTREAM_H

Antworten