16.2. Использование QTextBrowser для отображения текста справки.
Большие серьезные приложения могут содержать объем справочной информации, намного превышающий возможности всплывающих подсказок и даже подсказок типа «What’s This?». Самое простое решение в этом случае — создать обозреватель справочной системы. Приложение может открывать окно обозревателя справки при выборе пункта Help, в меню Help, или при нажатии на кнопку Help в панели инструментов.
В этом разделе мы рассмотрим простейший обозреватель справочной системы, внешний вид которого представлен на рисунке 16.3, и опишем, как его использовать в приложении. Для отображения текста справки используется QTextBrowser, который может обрабатывать некоторые теги HTML и идеально подходит под заданные условия.

Рисунок 16.3. Виджет HelpBrowser.
Как обычно, начнем с заголовочного файла:
#include class QPushButton; class QTextBrowser; class HelpBrowser : public QWidget < Q_OBJECT public: HelpBrowser(const QString &path, const QString &page, QWidget *parent = 0, const char *name = 0); static void showPage(const QString &page); private slots: void updateCaption(); private: QTextBrowser *textBrowser; QPushButton *homeButton; QPushButton *backButton; QPushButton *closeButton; >;
HelpBrowser имеет статическую функцию, которая может вызываться из любого места в приложении. Она создает окно обозревателя и показывает запрошенную страницу.
Теперь исходный код файла реализации:
#include #include #include #include #include "helpbrowser.h" HelpBrowser::HelpBrowser(const QString &path, const QString &page, QWidget *parent, const char *name) : QWidget(parent, name, WGroupLeader | WDestructiveClose) < textBrowser = new QTextBrowser(this); homeButton = new QPushButton(tr("&Home"), this); backButton = new QPushButton(tr("&Back"), this); closeButton = new QPushButton(tr("Close"), this); closeButton->setAccel(tr("Esc")); QVBoxLayout *mainLayout = new QVBoxLayout(this); QHBoxLayout *buttonLayout = new QHBoxLayout(mainLayout); buttonLayout->addWidget(homeButton); buttonLayout->addWidget(backButton); buttonLayout->addStretch(1); buttonLayout->addWidget(closeButton); mainLayout->addWidget(textBrowser); connect(homeButton, SIGNAL(clicked()), textBrowser, SLOT(home())); connect(backButton, SIGNAL(clicked()), textBrowser, SLOT(backward())); connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); connect(textBrowser, SIGNAL(sourceChanged(const QString &)), this, SLOT(updateCaption())); textBrowser->mimeSourceFactory()->addFilePath(path); textBrowser->setSource(page); >
Размещение компонентов в окне более чем простое: ряд кнопок находится над QTextBrowser. Аргумент path — это путь к каталогу, где находятся файлы с текстом справки. Аргумент page — имя файла справки, с необязательным названием темы (в терминах HTML — anchor, или имя ссылки).
Мы передаем конструктору флаг WGroupLeader, потому что окно HelpBrowser может открываться из модальных диалогов. Обычно модальные диалоги не позволяют пользователю взаимодействовать с другими окнами приложения. Однако, в данном случае, после того как пользователь запросил помощь, он должен иметь возможность работать как с окном модального диалога, так и с окном обозревателя справочной системы. Флаг WGroupLeader обеспечивает такую возможность.
void HelpBrowser::updateCaption() < setCaption(tr("Help: %1").arg(textBrowser->documentTitle())); >
Всякий раз, при переходе на другую страницу, вызывается слот updateCaption(). Функция documentTitle() возвращает текст, заданный в теге .
void HelpBrowser::showPage(const QString &page) < QString path = qApp->applicationDirPath() + "/doc"; HelpBrowser *browser = new HelpBrowser(path, page); browser->resize(500, 400); browser->show(); >
В функции showPage() создается окно обозревателя и затем выводится на экран. Окно будет уничтожено автоматически, когда пользователь закроет его, поскольку в конструкторе был установлен флаг WDestructiveClose.
В данном примере мы исходим из предположения, что файлы справки находятся в подкаталоге doc.
Теперь можно вызвать обозреватель из приложения. Для этого, в главном окне приложения, мы создадим объект QAction -- Help и соединим его со слотом help():
void MainWindow::help()
Мы полагаем, что основной файл справки называется index.html. Чтобы вызвать обозреватель из диалога, нужно связать соответствующую кнопку Help со слотом help():
void EntryDialog::help()
Здесь мы обращаемся уже к другому файлу справки -- dialogs.html и выполняем переход к ссылке entrydialog.
Еще одно место, откуда можно вызвать обозреватель справочной системы -- текст справки типа "What's This?". Для этого достаточно вставить в текст справки "What's This?" тег HTML .

Рисунок 16.4. Текст справки "What's This?" со ссылкой на файл справки.
Чтобы такая гипертекстовая ссылка работала, мы должны использовать класс, производный от QWhatsThis, который будет "знать", как вызвать обозреватель справочной системы. Для этого надо в классе-потомке перекрыть метод clicked(), в котором вызвать HelpBrowser:: showPage(). Ниже приводится определение класса:
class MyWhatsThis : public QWhatsThis < public: MyWhatsThis(QWidget *widget, const QString &text); QString text(const QPoint &point); bool clicked(const QString &page); private: QString myText; >;
Где text() и clicked() -- это методы предка, перекрываемые потомком.
MyWhatsThis::MyWhatsThis(QWidget *widget, const QString &text) : QWhatsThis(widget)
Конструктор получает указатель на виджет и текст справки для этого виджета. Мы передаем указатель на виджет базовому конструктору и сохраняем текст справки в приватной переменной.
QString MyWhatsThis::text(const QPoint &)
Функция text() возвращает текст справки виджета, для заданных координат указателя мыши. Некоторые виджеты могут возвращать разный текст справки, в зависимости от того, где был произведен щелчок мышью, но в данном примере мы всегда будем возвращать один и тот же текст.
bool MyWhatsThis::clicked(const QString &page) < if (page.isEmpty()) < return true; >else < HelpBrowser::showPage(page); return false; >>
Функция clicked() вызывается в момент щелчка мышью по виджету, когда окно находится в режиме "What's This?". Если пользователь щелкает по гиперссылке, то функция получит название страницы в аргументе page. В противном случае в page будет пустая строка.
Возвращаемое значение используется базовым классом QWhatsThis для того, чтобы определить, что делать дальше -- скрыть (true) подсказку "What's This?" или оставить ее видимой (false). В данной ситуации мы хотим, чтобы текст "What's This?" оставался видимым на экране, поэтому возвращаем false. Когда пользователь щелкает по любому другому месту в тексте "What's This?", мы возвращаем true.
Ниже показан пример использования класса MyWhatsThis:
new MyWhatsThis(sourceLineEdit, tr("
" " The meaning of the " "Source field depends on " "the Type field:" "-
" "
- Books have a Publisher" "
- Articles have a Journal name with volume and " "issue number" "
- Thesis have an Institution name and a department " "name" "
На этот раз, вместо вызова QWhatsThis::add(), мы создаем экземпляр класса MyWhatsThis для виджета, с текстом подсказки. Теперь пользователь может щелкнуть по гипертекстовой ссылке и вызвать обозреватель справочной системы.
Выглядит немного странно, так как мы создаем объект, но не связываем его с какой бы то ни было переменной. Но это только на первый взгляд, потому что Qt сама следит за создаваемыми объектами класса QWhatsThis и удаляет их, когда необходимость в них отпадает.
| Пред. | В начало | След. |
| Разработка справочной системы приложения. | На уровень выше | Использование Qt Assistant для отображения текста справки. |
Как поместить текст в qTextBrowser?
Пишу 1-ю программу (это очень важно). Набросал тело программы в QT Designer . Подскажите, пожалуйста . Смысл таков:
import random a = random.randint (1,299) b = 300 - a print ("Сколько будет", a, "+",b,"?") res = int(input("Введите число: ")) while res != 300: print ("\nНе верно, попробуй ещё раз. ") res = int(input("Введите число: ")) res = 300 print ("\n\n****Ахахааха. Ну Вы поняли****\n")
Не могу найти подходящий способ, чтобы поместить переменную a в поле: textBrowser (qTextBrowser), а переменную b в поле textBrowser2 (qTextBrowser). Подскажите, пожалуйста. скрин ниже design.py
# Form implementation generated from reading ui file 'design.ui' # # Created by: PyQt5 UI code generator 5.11.3 # # WARNING! All changes made in this file will be lost! from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.setEnabled(True) MainWindow.resize(224, 241) MainWindow.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(20, 10, 91, 21)) self.label.setObjectName("label") self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setGeometry(QtCore.QRect(20, 180, 91, 31)) self.pushButton.setObjectName("pushButton") self.splitter = QtWidgets.QSplitter(self.centralwidget) self.splitter.setGeometry(QtCore.QRect(20, 100, 91, 61)) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setObjectName("splitter") self.label_2 = QtWidgets.QLabel(self.splitter) self.label_2.setObjectName("label_2") self.plainTextEdit = QtWidgets.QPlainTextEdit(self.splitter) self.plainTextEdit.setObjectName("plainTextEdit") self.splitter_2 = QtWidgets.QSplitter(self.centralwidget) self.splitter_2.setGeometry(QtCore.QRect(20, 40, 181, 31)) self.splitter_2.setOrientation(QtCore.Qt.Horizontal) self.splitter_2.setObjectName("splitter_2") self.textBrowser = QtWidgets.QTextBrowser(self.splitter_2) self.textBrowser.setObjectName("textBrowser") self.label_3 = QtWidgets.QLabel(self.splitter_2) self.label_3.setObjectName("label_3") self.textBrowser_2 = QtWidgets.QTextBrowser(self.splitter_2) self.textBrowser_2.setObjectName("textBrowser_2") self.label_4 = QtWidgets.QLabel(self.splitter_2) self.label_4.setObjectName("label_4") MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Суперпрограмма")) self.label.setText(_translate("MainWindow", "Сколько будет")) self.pushButton.setText(_translate("MainWindow", "Окей?")) self.label_2.setText(_translate("MainWindow", "Ответ:")) self.label_3.setText(_translate("MainWindow", "+")) self.label_4.setText(_translate("MainWindow", "?"))
main.py
import sys # Импортируем наш интерфейс из файла from design import * from PyQt5 import QtCore, QtGui, QtWidgets class MyWin(QtWidgets.QMainWindow): def __init__(self, parent=None): QtWidgets.QWidget.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Здесь прописываем событие нажатия на кнопку self.ui.pushButton.clicked.connect(self.MyFunction) # Пока пустая функция которая выполняется # при нажатии на кнопку def MyFunction(self): pass #заглушка if __name__=="__main__": app = QtWidgets.QApplication(sys.argv) myapp = MyWin() myapp.show() sys.exit(app.exec_())
Как добавить текст в qtextbrowser в qt
![]()

Просмотр профиля
22.2.2011, 18:26
Группа: Новичок
Сообщений: 9
Регистрация: 22.2.2011
Пользователь №: 2433
Репутация: 0
Добрый день!
Есть QTextEdit и PushButton. Задача - вставить в окошко определённый текст по клику этой кнопки. Пробовал через void и cursor.InsertText, но не выходит. Есть ли способ это осуществить только кодом или только через "Дизайн"? Совмещать слишком геморно.

опции профиля:
![]()

Просмотр профиля
22.2.2011, 19:13
Группа: Участник
Сообщений: 1654
Регистрация: 24.5.2010
Из: Харьков
Пользователь №: 1752
Репутация: 212
Можно через connect:
connect(pushButton,SIGNAL(clicked()),this,SLOT(my_setText(QString)));
my_setText(QString)) - ваша функция. которая будет вставлять текст.

опции профиля:
Работа с текстом в QTextEdit

Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Подписка на обсуждение 3
Подписка на раздел 237
Вам это нравится? Поделитесь в социальных сетях!
Вы такое хотите сделать?
Когда тыкайте исчезает автоматически


- Evgenii Legotckoi → WXQ
- #
- 7 августа 2018 г. 13:06
Нет. Здесь нужно сделать поведение, как в консоли, то есть имеется путь, который не получается удалить, а дальше уже можно вводить текст.
Здесь нужна переменная QString , куда будет записываться нередактируемый текст, а потом выводить этот текст при обработке нажатий клавиш, а также следить за позицией курсора, чтобы не дать передвинуться на место нередактируемого текста. То есть прибавлять перед строкой этот нередактируемый текст, а за счёт этого текста сдвигать вводимый текст на позицию, равную длине этого текста, если понятно выразился.
В общем более замороченно, чем простой placeholder.
Нужно наследоваться от QTextEdit для этого.

- Arrow → Evgenii Legotckoi
- #
- 7 августа 2018 г. 13:11
Что-то мне подсказывало, что без моего любимого 🙂 наследования не обойтись.

- Evgenii Legotckoi
- #
- 7 августа 2018 г. 13:18
- (ред.)
- Ответ был помечен как решение.
Встроенного такого функционала там нет, а без наследования бардак будет.
Там как минимум потребуется две переменных в секции private
private: int m_fixedStartPosition; QString m_caption;
Первая - это длина этого текста, чтобы проще было понимать, где заканчивается нередактируемая часть, а где начинается редактируемая,
Вторая - это тот нередактируемый текст
Также придётся обрабатывать все кнопки BackSpace и Enter, то есть переопределять метод keyEvent. По сути это эмулятор терминала получается