2

I am trying to connect QTextEdit to QTextBrowser, so the text browser widget outputs what is entered in text edit widget. As a signal I used textChanged(), and as a slot I used setText(QString). And these two don't have same parameters.

If I used QLineEdit instead of QTextEdit, in that case there is textChanged(QString) function which is compatible with the slot,but I need to make it work with QTextEdit. Here is the code:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtWidgets>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    QWidget * mainWidget=new QWidget(this);
    ui->setupUi(this);
    QTextEdit * mainTextEdit=new QTextEdit();
    QTextBrowser * textDisplay=new QTextBrowser();

    connect(mainTextEdit,SIGNAL( textChanged() ),
            textDisplay,SLOT( setText(QString) ) );

    QHBoxLayout * Alayout=new QHBoxLayout();
    Alayout->addWidget(mainTextEdit);
    Alayout->addWidget(textDisplay);
    mainWidget->setLayout(Alayout);
    setCentralWidget(mainWidget);
}

MainWindow::~MainWindow()
{
    delete ui;
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
xpg94
  • 495
  • 1
  • 10
  • 26
  • Style note: Change your `MainWindow` declaration to hold a `QScopedPointer ui` instead of `Ui::MainWindow * ui`. Then you don't have to write a destructor. You still need a destructor, just that it's empty and you won't ever forget to delete the ui. – Kuba hasn't forgotten Monica Mar 31 '14 at 21:04

2 Answers2

1

I would do it in the following way:

Declare the pointers to the text edit and text browser widgets as member variables in the class,

Create a slot onTextChanged() in MainWindow class that will be called as soon as the text edit is changed and setup the connection as:

connect(mainTextEdit, SIGNAL(textChanged()), this, SLOT(onTextChanged()));

Implement the onTextChanged() slot in the following way:

MainWindow::onTextChanged()
{
    QString text = mainTextEdit->toPlainText();
    textDisplay->setPlainText(text); 
}
vahancho
  • 20,808
  • 3
  • 47
  • 55
  • 1
    I'd show both how to do it in Qt 4 and Qt 5/C++11. Eventually, the Qt 4 style should become deprecated since it leads to lots of verbosity. – Kuba hasn't forgotten Monica Mar 31 '14 at 21:02
  • I did everything as you said,but QT gives me an error,which states that "class QTextEdit has no member named text". Error is displayed in this line of code (The one you mentioned in your comment): QString text = mainTextEdit->text(); – xpg94 Mar 31 '14 at 21:03
1

Thankfully, the QTextEdit and QTextBrowser are views onto a QTextDocument model. So, you can simply set the editor's document on the browser. QTextBrowser::setDocument is semantically equivalent to QAbstractItemView::setModel:

textDisplay->setDocument(mainTextEdit->document());

In Qt, there are really two basic model classes: QAbstractItemModel and QTextDocument. A QTextDocument is a model in its own model-view framework. We simply set another view onto the document that the editor operates on. The editor allows modifications to the model, the browser doesn't. It's no different from using the same model on two QListViews, etc.

A QTextEditor is a view with a default model (document). You can replace that default model with one from another view, or even with one that you yourself provide. You could have multiple editors all displaying the same QTextDocument document and allowing editing of it, in parallel. You can also have multiple browsers doing the same.

Complete example:

#include <QApplication>
#include <QTextEdit>
#include <QTextBrowser>
#include <QHBoxLayout>

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QWidget window;
   QHBoxLayout layout(&window);
   QTextEdit edit;
   QTextBrowser browser;
   layout.addWidget(&edit);
   layout.addWidget(&browser);
   browser.setDocument(edit.document());
   window.show();
   return a.exec();
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • how can I use that in my constructor (in mainwindow.cpp),not in the main.cpp ? Is it possible? – xpg94 Mar 31 '14 at 21:07
  • @xpg94 Use it like you ordinarily would, I don't know what the problem is? I'm merely showing a *complete* example, that doesn't mean your code needs to look like that. In fact, I've shown the line you need to connect the two in your own code. The first line of code I shown is the one you need, in your constructor, instead of all the signal-slot connections. – Kuba hasn't forgotten Monica Mar 31 '14 at 21:09
  • Sorry for making troubles for you. I used that line instead of connect... and it workes. Now I only need to figure out how and why does it work. What does setDocument function actually do? Thanks. – xpg94 Mar 31 '14 at 21:13