QTextEdit promoted to Construct a Console Window - c++

I try to construct a promoted QTextEdit Console widget for my Gui in which i redirect all std::cout. For the redirection i mostly followed this tutorial:
My code looks like this:
myConsoleStream.cpp:
#include "myconsolestream.h"
myConsoleStream::myConsoleStream(std::ostream &stream, QTextEdit* text_edit,QWidget *parent)
:std::basic_streambuf<char>()
,m_stream(stream)
,myConsole(parent)
{
this->log_window = text_edit;
this->m_old_buf = stream.rdbuf();
stream.rdbuf(this);
}
myConsoleStream::~myConsoleStream()
{
this->m_stream.rdbuf(this->m_old_buf);
}
void myConsoleStream::registerMyConsoleMessageHandler()
{
qInstallMessageHandler(myConsoleMessageHandler);
}
void myConsoleStream::myConsoleMessageHandler(QtMsgType, const QMessageLogContext &, const QString &msg)
{
std::cout << msg.toStdString().c_str();
}
std::streamsize myConsoleStream::xsputn(const char *p, std::streamsize n)
{
QString str(p);
if(str.contains("\n"))
{
QStringList strSplitted = str.split("\n");
this->log_window->moveCursor (QTextCursor::End);
this->log_window->insertPlainText (strSplitted.at(0)); //Index 0 immer noch auf der alten Zeile
for(int i = 1; i < strSplitted.size(); i++)
{
this->log_window->append(strSplitted.at(i));
}
}
else
{
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (str);
}
return n;
}
myConsoleStream.h:
#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QObject>
#include <QWidget>
#include "QTextEdit"
#include <QApplication>
#include "myconsole.h"
class myConsoleStream : public std::basic_streambuf<char>, myConsole
{
public:
myConsoleStream(std::ostream &stream, QTextEdit* text_edit, QWidget *parent);
virtual ~myConsoleStream();
static void registerMyConsoleMessageHandler();
private:
static void myConsoleMessageHandler(QtMsgType, const QMessageLogContext &, const QString &msg);
protected:
// Diese Funktion wird aufgerufen wenn std::endl im Stream erscheint
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
log_window->append("");
}
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n);
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
QTextEdit* log_window;
};
#endif // Q_DEBUGSTREAM_H
I tried to make this class a subclass of an additional class to which I promoted the QTextEdit to.Which looks like this:
#include "myconsole.h"
myConsole::myConsole(QWidget *parent)
:QTextEdit(parent)
{
}
myConsole::~myConsole()
{
}
Last but not least my Mainwindow Class looks like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QBoxLayout>
#include <QTimer>
#include "myconsolestream.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
new myConsoleStream(std::cout, this->ui->Console,this);//Redirect Console output to QTextEdit
myConsoleStream::registerMyConsoleMessageHandler(); //Redirect qDebug() output to QTextEdit
std::cout << "Hallo" << std::endl;
}
MainWindow::~MainWindow()
{
delete ui;
}
If I execute this there appears a second QTextEdit in the left upperhand corner of my Mainwindow, which I dont want to have there. And I cant figure out why this is appearing or where this is created?
Btw I am using qt5.5 and QtCreator for that matter.

It looks like you create your own QTextEdit with the myConsole class and you also redirect your output to this->ui->Console which I guess is created with the UI designer and also an instance of QTextEdit. myConsole in then displayed in the top left of your window because you don't provide it with any layout information and just a parent widget.
To clarifiy, your myConsoleStream is derived from myConsole which in term is derived from QTextEdit, so your myConsoleStream is also an object of type QTextEdit itself.
If you follow the example provided in your link you don't have to create another QTextEdit, if you want to do that you also have to place it in your UI etc..

Related

How to display a QChartView inside a QStackedWidget?

I want my form to have a QStackedWidget with 2 (at least) pages and each of them has a QChartView.
In the form editor, through the 'promote' menu, I made a QChartView from QGraphicView. (screenshoot (so far there is only 1 QChartView on it - so that i can see which page is open)).
From the main window, when one of the buttons is pressed, I want to open the above windows in a loop:
void Widget::ShowStudioCharts() noexcept
{
for(auto & e : this->userInfoVector){
Form *pForm = new Form();
pForm->provideStudioData(&e.studiosStats, e.nickname);
pForm->processStudioStats();
pForm->show();
}
}
I tried to do it like this:
Form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QPieSeries>
#include <QChart>
#include <QChartView>
#include <QGridLayout>
#include <vector>
#include <map>
#include <QStackedWidget>
#include <QtGlobal>
#include <QRectF>
#include <QRect>
#include <QPushButton>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
void provideStudioData(std::map<std::string, std::size_t> *studiosStats, const std::string &nickname) noexcept;
void processStudioStats() noexcept;
private slots:
void on_pushButton_2_clicked();
private:
std::vector<std::map<std::string, size_t>*> stats;
std::vector<std::string> nicknames;
Ui::Form *ui;
};
#endif // FORM_H
Form.cpp
#include "form.h"
#include "ui_form.h"
#include <QPieSeries>
#include <QPieSlice>
#include <QChart>
using namespace QtCharts;
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::provideStudioData(std::map<std::string, size_t> *studiosStats, const std::string &nickname) noexcept
{
this->stats.push_back(studiosStats);
this->nicknames.push_back(nickname);
}
void Form::processStudioStats() noexcept
{
srand(time(0));
QPieSeries *series = new QPieSeries();
// for (const auto & e : this->stats ){
// //QBarSet *set0 = new QBarSet("1");
// for ( const auto & a : *e){
// //*set0 << a.second;
// qDebug( (a.first + " " + std::to_string(a.second)).c_str());
// }
// }
for ( const auto & a : *this->stats[0]){
QPieSlice * slice = new QPieSlice();
slice->setColor(QColor(rand()%255, rand()%255, rand()%255));
slice->setValue(a.second);
slice->setLabel(a.first.c_str());
series->append(slice);
}
QChart *chart = new QChart();
chart->setAnimationOptions(QChart::AnimationOption::AllAnimations);
chart->addSeries(series);
//chart->setPlotArea(QRectF(200,0,1400,1100));
//chart->legend()->detachFromChart();
chart->legend()->setBackgroundVisible(true);
chart->legend()->setBrush(QBrush(QColor(128, 128, 128, 128)));
chart->legend()->setPen(QPen(QColor(192, 192, 192, 192)));
//chart->legend()->setGeometry(QRectF(20,20,200,1000));
chart->setTitle(QString::fromStdString(this->nicknames[0]));
this->setWindowTitle(QString::fromStdString(this->nicknames[0]));
chart->legend()->setAlignment(Qt::AlignLeft);
ui->graphicsView = new QChartView(chart);
ui->graphicsView->show();
//ui->stackedWidget->show();
}
void Form::on_pushButton_2_clicked()
{
if(0 == this->ui->stackedWidget->currentIndex())
this->ui->stackedWidget->setCurrentIndex(1);
else if(1 == this->ui->stackedWidget->currentIndex())
this->ui->stackedWidget->setCurrentIndex(0);
}
The code is compiled, windows are opened. But the problem is that my chart is displayed in another window above the opened one.
This is obviously the result of
ui->graphicsView->show();
But if i remove this line, then the graph is not visible at all.
Help please, thanks in advance.
Doing ui->graphicsView = new QChartView(chart); does not replace the QChartView, you are just assigning the pointer. The solution is to reuse the existing QChartView so it changes to: ui->graphicsView->setChart(chart);.

Redirect qDebug to an emitted signal

I've successfully redirected qDebug() output to a QTextEdit widget. For several reasons, I'd like every qDebug() message to be included in an emitted signal. One reason is that the object which shall receive the output isn't available. Another reason is that I want to redirect the output to different objects depending on which activity is active at the moment (using connect/disconnect of the signal to different slots).
I've made a working example code that redirects qDebug to a QTextEdit widget. Can someone please help me to get this code to emit a signal which includes the qDebug message?
I'm not sure if its possible to have Q_DebugStream emit a signal (I've tried and failed to make a Qt Class out of it).
It must be possible to pass a pointer to a function/slot instead of a pointer to a QTextEdit when calling Q_DebugStream, but I'm not sure how this is done.
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void logSignal(QString);
public slots:
void logSlot(QString);
private:
QTextEdit *logView;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "q_debugstream.h"
#include <QGridLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
logView = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(logView,0,0,1,1);
mainWidget->setLayout(mainLayout);
connect(this, SIGNAL(logSignal(QString)),
this, SLOT(logSlot(QString)));
emit logSignal("Message from a signal\n");
new Q_DebugStream(std::cout, logView); //Redirect Console output to QTextEdit
Q_DebugStream::registerQDebugMessageHandler(); //Redirect qDebug() output to QTextEdit
qDebug() << "DEBUG MODE ACTIVE";
}
MainWindow::~MainWindow(){}
void MainWindow::logSlot(QString log) {
logView->append(log);
}
q_debugstream.h
//As per forum:
//http://www.qtforum.org/article/39768/redirecting-std-cout-std-cerf-qdebug-to-qtextedit.html
//A couple of lines added to ensure newlines go between each call.
//Thanks, James!
#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QTextEdit>
class Q_DebugStream : public std::basic_streambuf<char>
{
public:
Q_DebugStream(std::ostream &stream, QTextEdit* text_edit) : m_stream(stream)
{
log_window = text_edit;
m_old_buf = stream.rdbuf();
stream.rdbuf(this);
}
~Q_DebugStream()
{
m_stream.rdbuf(m_old_buf);
}
static void registerQDebugMessageHandler(){
qInstallMessageHandler(myQDebugMessageHandler);
}
private:
static void myQDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &msg)
{
std::cout << msg.toStdString().c_str();
}
protected:
//This is called when a std::endl has been inserted into the stream
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
log_window->append("");
}
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n)
{
QString str(p);
if(str.contains("\n")){
QStringList strSplitted = str.split("\n");
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (strSplitted.at(0)); //Index 0 is still on the same old line
for(int i = 1; i < strSplitted.size(); i++){
log_window->append(strSplitted.at(i));
log_window->append("\n");
}
}else{
log_window->moveCursor (QTextCursor::End);
log_window->insertPlainText (str);
log_window->insertPlainText ("\n");
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
QTextEdit* log_window;
};
#endif // Q_DEBUGSTREAM_H
When application is started, I get both messages in my QTextEdit:
"Message from a signal"
"DEBUG MODE ACTIVE"
(This answer extracted from an edit to the question - now rolled back).
Here's how I solved this:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void logSignal(QString);
public slots:
void logSlot(QString);
private:
void dbgMsg(QString);
QTextEdit *logView;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "q_debugstream.h"
#include <QGridLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QWidget *mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
logView = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(logView,0,0,1,1);
mainWidget->setLayout(mainLayout);
connect(this, SIGNAL(logSignal(QString)),
this, SLOT(logSlot(QString)));
emit logSignal("Now call Q_DebugStream");
//Redirect qDebug() output to dbgMsg(QString)
new Q_DebugStream(std::cout, this, &MainWindow::dbgMsg);
Q_DebugStream::registerQDebugMessageHandler();
qDebug() << "Debug message";
qWarning() << "Warning!";
qCritical() << "Critical issue!";
qInfo() << "Information";
qDebug() << "This\nis\na\nlong\none.";
}
MainWindow::~MainWindow(){}
void MainWindow::logSlot(QString log) {
logView->append(log);
}
void MainWindow::dbgMsg(QString log) {
emit logSignal(log);
}
q_debugstream.h
#ifndef Q_DEBUGSTREAM_H
#define Q_DEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QString>
#include "mainwindow.h"
class Q_DebugStream : public std::basic_streambuf<char> {
public:
Q_DebugStream(std::ostream &stream, MainWindow* obj, void (MainWindow::*dbgMsgPtr)(QString log)): m_stream(stream) {
m_old_buf = stream.rdbuf();
stream.rdbuf(this);
msgObj = obj;
msgHandler = dbgMsgPtr;
}
~Q_DebugStream() {
m_stream.rdbuf(m_old_buf);
}
static void registerQDebugMessageHandler() {
qInstallMessageHandler(myQDebugMessageHandler);
}
private:
static void myQDebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
QString message = msg;
switch (type) {
case QtDebugMsg:
message.prepend("qDbg(): ");
break;
case QtWarningMsg:
message.prepend("qWarn(): ");
break;
case QtCriticalMsg:
message.prepend("qCrit(): ");
break;
case QtInfoMsg:
message.prepend("qInfo(): ");
break;
case QtFatalMsg:
message.prepend("qFatal(): ");
abort();
break;
}
message.append(" (" + QString::fromUtf8(context.file) + ")");
message.append(" line: " + QString::number(context.line));
std::cout << message.toStdString().c_str();
}
protected:
//This is called when a std::endl has been inserted into the stream
virtual int_type overflow(int_type v) {
if (v == '\n') {
(msgObj->*msgHandler)("\n");
}
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n) {
QString str(p);
if(str.contains("\n")) {
QStringList strSplitted = str.split("\n");
(msgObj->*msgHandler)(strSplitted.at(0)); //Index 0 is still on the same old line
for(int i = 1; i < strSplitted.size(); i++) {
(msgObj->*msgHandler)("\\ " + strSplitted.at(i));
}
} else {
(msgObj->*msgHandler)(str);
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
MainWindow* msgObj;
void (MainWindow::*msgHandler)(QString);
};
#endif // Q_DEBUGSTREAM_H
When application is started, I get these messages in my QTextEdit:
Now call Q_DebugStream
qDbg(): Debug message (..\qDebugFetch\mainwindow.cpp) line: 25
qWarn(): Warning! (..\qDebugFetch\mainwindow.cpp) line: 26
qCrit(): Critical issue! (..\qDebugFetch\mainwindow.cpp) line: 27
qInfo(): Information (..\qDebugFetch\mainwindow.cpp) line: 28
qDbg(): This
\ is
\ a
\ long
\ one. (..\qDebugFetch\mainwindow.cpp) line: 29

Dynamic QLabel misplacing in UI

I'm trying to create a program that accepts images through drag and drop and shows those images on my UI, then I want to rename them and save them.
I got the drag and drop to work, but I have some issues with my Image placement and I can't seem to find where I'm making my mistake.
In the image you see my UI during runtime, in the top left you can see a part of the image I dragged into the green zone(this is my drag and drop zone that accepts images). The position I actually want it to be in should be the red square. The green zone is a Dynamic created object called Imagehandler that I created to handle the drag and drop of the images. The Red square is my own class that inherits from QLabel, I called it myiconclass. This class should hold the actual image data.
I think my mistake has to do with the layouts, but I can't see it.
Could I get some help with this please?
Imagehandler.h
#ifndef IMAGEHANDLER_H
#define IMAGEHANDLER_H
#include <QObject>
#include <QWidget>
#include <QLabel>
#include <QDrag>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QList>
#include <QDebug>
//this class is designed to help me take in the images with drag and drop
class ImageHandler : public QWidget
{
Q_OBJECT
public:
explicit ImageHandler(QWidget *parent = nullptr);
QList<QImage> getImageListMemory() const;
void setImageListMemory(const QList<QImage> &value);
QList<QUrl> getUrlsMemory() const;
void setUrlsMemory(const QList<QUrl> &value);
private:
//QWidget Icon;
QLabel Icon;
QList <QImage> imageListMemory;
QList <QUrl> urlsMemory;
protected:
void dragEnterEvent(QDragEnterEvent * event);
void dragLeaveEvent(QDragLeaveEvent * event);
void dragMoveEvent(QDragMoveEvent * event);
void dropEvent(QDropEvent * event);
signals:
void transferImageSignal(QList <QImage>);
public slots:
};
#endif // IMAGEHANDLER_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QImageReader>
#include <QList>
#include <QWidget>
#include <QLabel>
#include <myiconclass.h>
#include <imagehandler.h>
#include <QGridLayout>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QList<QImage> getImageListMemory() const;
void setImageListMemory(const QList<QImage> &value);
private:
Ui::MainWindow *ui;
QLabel Icon;
QList <QImage> imageListMemory;
QList <QUrl> urlsMemory;
QList<QWidget *> labelList;
ImageHandler * ImageHandlerMemory;
QGridLayout * grid2;
QList <MyIconClass *> memory;
signals:
public slots:
void setIconSlot(QList <QImage>);
};
#endif // MAINWINDOW_H
myiconclass.h
#ifndef MYICONCLASS_H
#define MYICONCLASS_H
#include <QWidget>
#include <QLabel>
//this class is based on a Qlabel and is only made so it can help me with the actual images, gives me more members if I need it
class MyIconClass : public QLabel
{
Q_OBJECT
public:
explicit MyIconClass(QWidget *parent = nullptr);
int getMyNumber() const;
void setMyNumber(int value);
private:
int myNumber;
signals:
public slots:
};
#endif // MYICONCLASS_H
imagehandler.cpp
#include "imagehandler.h"
ImageHandler::ImageHandler(QWidget *parent) : QWidget(parent)
{
setAcceptDrops(true);
}
QList<QImage> ImageHandler::getImageListMemory() const
{
return imageListMemory;
}
void ImageHandler::setImageListMemory(const QList<QImage> &value)
{
imageListMemory = value;
}
QList<QUrl> ImageHandler::getUrlsMemory() const
{
return urlsMemory;
}
void ImageHandler::setUrlsMemory(const QList<QUrl> &value)
{
urlsMemory = value;
}
void ImageHandler::dragEnterEvent(QDragEnterEvent * event)
{
event->accept();
}
void ImageHandler::dragLeaveEvent(QDragLeaveEvent * event)
{
event->accept();
}
void ImageHandler::dragMoveEvent(QDragMoveEvent * event)
{
event->accept();
}
void ImageHandler::dropEvent(QDropEvent * event)
{
QList <QImage> imageList2;
QList <QUrl> urls;
QList <QUrl>::iterator i;
urls = event->mimeData()->urls();
//imageList.append(event->mimeData()->imageData());
foreach (const QUrl &url, event->mimeData()->urls())
{
QString fileName = url.toLocalFile();
qDebug() << "Dropped file:" << fileName;
qDebug()<<url.toString();
QImage img;
if(img.load(fileName))
{
imageList2.append(img);
}
}
emit transferImageSignal(imageList2);
this->setUrlsMemory(urls);
this->setImageListMemory(imageList2);
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ImageHandler * handler = new ImageHandler(this);
handler->show();
QGridLayout *grid = new QGridLayout;
grid->addWidget(handler, 0, 0);
ui->groupBoxIcon->setLayout(grid);
ImageHandlerMemory = handler;
//connect(handler,SIGNAL(handler->transferImageSignal(QList <QUrl>)),this,SLOT(setIconSlot(QList <QUrl>)));
connect(handler,SIGNAL(transferImageSignal(QList<QImage>)),this,SLOT(setIconSlot(QList<QImage>)));
}
MainWindow::~MainWindow()
{
delete ui;
}
QList<QImage> MainWindow::getImageListMemory() const
{
return imageListMemory;
}
void MainWindow::setImageListMemory(const QList<QImage> &value)
{
imageListMemory = value;
}
void MainWindow::setIconSlot(QList<QImage> images)
{
printf("succes!");
this->setImageListMemory(images); //save the images to memory
QGridLayout *grid = new QGridLayout; //create the grid layout I want my images to be in
// create counters to remember the row and column in the grid
int counterRow =0;
int counterColumn =0;
int counter3 =0;
int counterImages = 0;
//iterate over each image in the list
QList <QImage>::iterator x;
for(x = imageListMemory.begin(); x != imageListMemory.end(); x++)
{
MyIconClass * myLabel = new MyIconClass(this); //create an object of my own class (which is a Qlabel with an int member)
QPixmap pixmap(QPixmap::fromImage(*x)); //create a pixmap from the image in the iteration
myLabel->setPixmap(pixmap); //set the pixmap on my label object
myLabel->show();
memory.append(myLabel); //add it to the memory so I can recal it
counterImages++;
}
while(counter3 < images.count())
{
grid2->addWidget(memory.value(counter3), counterRow, counterColumn);
counterColumn++;
counter3++;
if(counterColumn >= 5)
{
counterRow++;
counterColumn =0;
}
}
if(ImageHandlerMemory->layout() == 0)
{
ImageHandlerMemory->setLayout(grid2);
}
}
myiconclass.cpp
#include "myiconclass.h"
MyIconClass::MyIconClass(QWidget *parent) : QLabel(parent)
{
}
int MyIconClass::getMyNumber() const
{
return myNumber;
}
void MyIconClass::setMyNumber(int value)
{
myNumber = value;
}
As Benjamin T said I had to change this:
MyIconClass * myLabel = new MyIconClass(this);
into this:
MyIconClass * myLabel = new MyIconClass(ImageHandlerMemory);
Thanks Benjamin!
PS, I also had to add this line in my mainwindow constructor:
grid2 = new QGridLayout;

Scrolling list of labels on Qt

I'm trying to create a scrollbar for my labels. For the moment, if the users create too many labels, the sizes of the button and of the text zone are reduced, that's why I wanted to create a scrollbar then if there is too many labels, they will not change the aspect of the window.
This is my actual code :
#include <iostream>
#include <QApplication>
#include <QPushButton>
#include <QLineEdit>
#include <QWidget>
#include <QFormLayout>
#include "LibQt.hpp"
LibQt::LibQt() : QWidget()
{
this->size_x = 500;
this->size_y = 500;
QWidget::setWindowTitle("The Plazza");
setFixedSize(this->size_x, this->size_y);
manageOrder();
}
LibQt::~LibQt()
{
}
void LibQt::keyPressEvent(QKeyEvent* event)
{
if (event->key() == Qt::Key_Escape)
QCoreApplication::quit();
else
QWidget::keyPressEvent(event);
}
void LibQt::manageOrder()
{
this->converLayout = new QFormLayout;
this->testline = new QLineEdit;
this->m_button = new QPushButton("Send");
this->m_button->setCursor(Qt::PointingHandCursor);
this->m_button->setFont(QFont("Comic Sans MS", 14));
this->converLayout->addRow("Order : ", this->testline);
this->converLayout->addWidget(this->m_button);
QObject::connect(m_button, SIGNAL(clicked()), this, SLOT(ClearAndGetTxt()));
CreateLabel("test");
CreateLabel("test2");
}
void LibQt::CreateLabel(std::string text)
{
QString qstr = QString::fromStdString(text);
this->label = new QLabel(qstr);
this->converLayout->addWidget(this->label);
this->setLayout(converLayout);
}
std::string LibQt::ClearAndGetTxt()
{
QString txt = this->testline->text();
if (!txt.isEmpty())
{
this->usertxt = txt.toStdString();
std::cout << this->usertxt << std::endl;
this->testline->clear();
CreateLabel(this->usertxt);
return (this->usertxt);
}
return (this->usertxt);
}
std::string LibQt::getUsertxt()
{
return (this->usertxt);
}
And this is the .hpp :
#ifndef _LIBQT_HPP_
#define _LIBQT_HPP_
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QKeyEvent>
class LibQt : public QWidget
{
Q_OBJECT
public:
LibQt();
~LibQt();
void manageOrder();
std::string getUsertxt();
void keyPressEvent(QKeyEvent *event);
void keyPressEventEnter(QKeyEvent *event);
void CreateLabel(std::string text);
public slots:
std::string ClearAndGetTxt();
protected:
int size_x;
int size_y;
QPushButton *m_button;
QLineEdit *testline;
std::string usertxt;
QLabel *label;
QFormLayout *converLayout;
};
#endif /* _LIBQT_HPP_ */
there are different solutions depending on what precisely do you want
QTextEdit is Qt widget class for scrollable text. By turning off text interaction flags, frame style and unsetting background color you will basically get scrollable QLabel
QScrollArea as a more generic solution

Unknown ouput with qdebugstream and qtextedit

The first output in the textedit is a number 3, I don't know why that number is coming form Qt::LogText. This question is based from a previous question I had asked, I'm using the same qdebugstream header file from the link below.
Redirect std::cout to a QTextEdit
The new project below is a QT Gui Application that will redirect the cout to a textedit. Also, since settextformat() is no longer a member of QTextEdit, I converted Qt::LogText into a string.
This was based on another post but I did not understand the solution.
QTextEdit::setTextFormat(Qt::LogText) does not exist anymore, what else can I use to log?.
Can someone provide more information on this?
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->textEdit->setReadOnly(true);
ui->textEdit->setText(QString("%1").arg(Qt::LogText));
QDebugStream qout(std::cout, ui->textEdit);
cout << "Send this to the Text Edit!" << endl;
}
MainWindow::~MainWindow()
{
delete ui;
}
Mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "qdebugstream.h"
#include "stdio.h"
#include "iostream"
using namespace std;
namespace Ui {
class MainWindow;
}
class QtextEdit;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
You should use QPlainTextEdit in Qt 4.x which seems to be equivalent using Q3TextEdit(QTextEdit in Qt 3.x) with text format of Qt::LogText.
For QPlainTextEdit version of QDebugStream might be like followings.(you may be noticed that append() mem func is renamed into addPlainText() and that's it viola). Hope this helps.
#ifndef QDEBUGSTREAM_H
#define QDEBUGSTREAM_H
#include <iostream>
#include <streambuf>
#include <string>
#include <QPlainTextEdit>
class QDebugStream : public std::basic_streambuf<char>
{
public:
QDebugStream(std::ostream &stream, QPlainTextEdit* 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())
log_window->appendPlainText(m_string.c_str());
m_stream.rdbuf(m_old_buf);
}
protected:
virtual int_type overflow(int_type v)
{
if (v == '\n')
{
log_window->appendPlainText(m_string.c_str());
m_string.erase(m_string.begin(), m_string.end());
}
else
m_string += v;
return v;
}
virtual std::streamsize xsputn(const char *p, std::streamsize n)
{
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);
log_window->appendPlainText(tmp.c_str());
m_string.erase(m_string.begin(), m_string.begin() + pos + 1);
}
}
return n;
}
private:
std::ostream &m_stream;
std::streambuf *m_old_buf;
std::string m_string;
QPlainTextEdit* log_window;
};
#endif