Как заставить QTextBrowser отображать содержимое QTextEdit?

Я пытаюсь подключить QTextEdit к QTextBrowser, поэтому виджет текстового браузера выводит то, что введено в виджет редактирования текста. В качестве сигнала я использовал textChanged(), а в качестве слота — setText(QString). И эти два не имеют одинаковых параметров.

Если бы я использовал QLineEdit вместо QTextEdit, в этом случае есть функция textChanged(QString), которая совместима со слотом, но мне нужно, чтобы она работала с QTextEdit. Вот код:

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

person xpg94    schedule 31.03.2014    source источник
comment
Примечание по стилю: измените объявление MainWindow так, чтобы оно содержало QScopedPointer<Ui::MainWindow> ui вместо Ui::MainWindow * ui. Тогда вам не нужно писать деструктор. Вам все еще нужен деструктор, просто он пустой, и вы никогда не забудете удалить пользовательский интерфейс.   -  person Kuba hasn't forgotten Monica    schedule 01.04.2014


Ответы (2)


К счастью, QTextEdit и QTextBrowser являются видами модели QTextDocument. Итак, вы можете просто установить документ редактора в браузере. QTextBrowser::setDocument семантически эквивалентен QAbstractItemView::setModel:

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

В Qt на самом деле есть два основных класса моделей: QAbstractItemModel и QTextDocument. QTextDocument — это модель в своей собственной структуре представления модели. Мы просто устанавливаем другой вид документа, с которым работает редактор. Редактор позволяет вносить изменения в модель, а браузер — нет. Это ничем не отличается от использования одной и той же модели в двух QListView и т. д.

QTextEditor — это представление с моделью по умолчанию (документом). Вы можете заменить эту модель по умолчанию моделью из другого представления или даже моделью, которую вы сами предоставили. У вас может быть несколько редакторов, отображающих один и тот же QTextDocument документ и позволяющих редактировать его параллельно. У вас также может быть несколько браузеров, делающих то же самое.

Полный пример:

#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();
}
person Kuba hasn't forgotten Monica    schedule 31.03.2014
comment
как я могу использовать это в своем конструкторе (в mainwindow.cpp), а не в main.cpp? Является ли это возможным? - person xpg94; 01.04.2014
comment
@ xpg94 Используйте его, как обычно, я не знаю, в чем проблема? Я просто показываю полный пример, это не значит, что ваш код должен выглядеть именно так. На самом деле, я показал строку, которая вам нужна, чтобы соединить их в вашем собственном коде. Первая строка кода, которую я показал, — это та, которая вам нужна в вашем конструкторе, вместо всех соединений сигнал-слот. - person Kuba hasn't forgotten Monica; 01.04.2014
comment
Прости, что доставил тебе неприятности. Я использовал эту строку вместо соединения... и это работает. Теперь мне нужно только выяснить, как и почему это работает. Что на самом деле делает функция setDocument? Спасибо. - person xpg94; 01.04.2014

Я бы сделал это следующим образом:

Объявите указатели на виджеты редактирования текста и текстового браузера как переменные-члены в классе,

Создайте слот onTextChanged() в классе MainWindow, который будет вызываться, как только будет изменено редактирование текста, и настройте соединение как:

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

Реализуйте слот onTextChanged() следующим образом:

MainWindow::onTextChanged()
{
    QString text = mainTextEdit->toPlainText();
    textDisplay->setPlainText(text); 
}
person vahancho    schedule 31.03.2014
comment
Я бы показал, как это сделать в Qt 4 и Qt 5/C++11. В конце концов, стиль Qt 4 должен стать устаревшим, поскольку он приводит к большому количеству многословия. - person Kuba hasn't forgotten Monica; 01.04.2014
comment
Я сделал все, как вы сказали, но QT выдает ошибку, в которой говорится, что класс QTextEdit не имеет члена с именем text. Ошибка отображается в этой строке кода (той, которую вы упомянули в своем комментарии): QString text = mainTextEdit->text(); - person xpg94; 01.04.2014