Жақында форумда Qt формулаларын қалай бейнелеуге болатыны туралы өте қызықты сұрақ пайда болды. Өкінішке орай, менде сайт пен форуммен ұзақ уақыт айналысуға мүмкіндігім болмады, бірақ біраз уақыттан кейін де мәселе туралы өзімнің болжамымды ұсыну пайдалы болады деп шештім.
Сұрақ жол ретінде жазылған формуланы визуализациялау болып табылады.
Мысалы, сіз кейбір енгізу өрісіне sqrt(5) енгізесіз, ал кейбір виджетте 5 квадрат түбірінің графикалық дисплейі көрсетіледі, яғни нәтиже емес, формуланың өзі. Ұқсас функция Latex және LibreOffice-те жүзеге асырылады.
Бұл келесідей болады.
Өздігінен, мұндай функционалдылықты жазу міндеті, менің ойымша, өте қиын және көп уақытты қажет етеді, әсіресе кірістірілген формулалары бар функцияны жүзеге асыруға келгенде және т.б. Сондықтан мен формулалардың ең қарапайым нұсқаларын көрсетуді жүзеге асыру үшін менің ойыма келген тұжырымдамаға тоқталатын боламын, яғни. кірістірілген ішкі формулаларсыз.
Жалпы ережелер
Бұл функцияны іске асыру үшін сізге қажет:
- Тұрақты өрнектерді пайдаланып, формула жазбасын бөлектеңіз
- Виджеттегі формуланы көрсету
Бұл тапсырма үшін тұрақты өрнектерді пайдалану өте орынды болады деп ойлаймын, өйткені жолды дұрыс талдау және формулалардың даналарын бөлектеу керек. Формуланың графикалық дисплейін жасау үшін формула жолында іздеуге арналған тұрақты өрнекті, сондай-ақ формуланы көрсетілген нүктеде сызатын әдісті қамтитын FormulaWidget арнайы класын жазамыз. виджеттің өзі қамтамасыз ететін QPainter нысанын қолданатын виджет. Бұл әдіс келесі формуланы салу үшін жаңа позицияны қайтаруы керек, осылайша олар бірнеше формулалар қатарынан берілсе, олар бір-біріне сәйкес келмейді.
Формулаларды салу үшін QWidget-тен мұраланған класс жасап, оның осы виджеттің мазмұнын салуға жауап беретін paintEvent() әдісін қайта анықтайық.
Қолданбаның негізгі терезесі
QWidget-тен мұраланған класс қолданбаның негізгі терезесі ретінде пайдаланылады. Сіз оны жобаны жасаған кезде таңдайсыз. Сондай-ақ оның графикалық пішін файлы болады, оған бізді қызықтыратын виджеттерді орналастыру қажет:
- QLineEdit - формуланы мұнда жазамыз
- FormulaWidget - формула көрсетілетін жерде
Графикалық редакторда әдеттегі виджет нысанын қосып, оны бұрын жасалған FormulaWidget сыныбына түрлендіру үшін контекстік мәзірді пайдалану қажет. Мәтінмәндік мәзірде бұл үшін "Convert to ..." немесе ағылшын тіліндегі нұсқасында "Promote to ..." бар.
Мен main.cpp файлының мазмұнына қол тигізбеймін, себебі бәрі әдепкі бойынша жасалған.
виджет.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; }; #endif // WIDGET_H
widget.cpp
Терілген мәтінді формула виджеттеріне беру үшін біз FormulaWidget ішінде жасайтын QLineEdit құралының setFormula ұясына сигнал textChanged қосылымын қолданамыз. сынып.
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); connect(ui->lineEdit, &QLineEdit::textChanged, ui->formulaWidget, &FormulaWidget::setFormula); } Widget::~Widget() { delete ui; }
Формулаларды көрсетуге арналған сабақтар
Енді формулаларды визуализациялауға арналған сыныптың өзін және формуланың өзін қарастырыңыз. Бұл сыныптардың екеуі бір тақырып файлында ( FormulaWidget.h ) және іске асыру файлында ( FormulaWidget.cpp ) орналасады.
Формула элементі
FormulaWidget.h
// Класс визуализации формулы class FormulaItem { public: explicit FormulaItem(QString value) : m_value(value){} static const QString REGULAR_EXPRESSION; // Строка регулярного выражения для поиска формулы // Метод отрисовки формулы QPoint draw(const QPoint& pos, QPainter& p) const; private: QString m_value; // Значение формулы };
FormulaWidget.cpp
const QString FormulaItem::REGULAR_EXPRESSION = "sqrt\\((?<value>\\d+)\\)"; QPoint FormulaItem::draw(const QPoint& pos, QPainter& p) const { int valueWidth = p.fontMetrics().width(m_value); int valueHeight = p.fontMetrics().height(); p.drawLine(pos.x(), 4 + valueHeight / 2, pos.x() + 5, 4 + valueHeight); p.drawLine(pos.x() + 5, 4 + valueHeight, pos.x() + 10, pos.y() + 1); p.drawLine(pos.x() + 10, pos.y() + 1, pos.x() + 14 + valueWidth, pos.y() + 1); p.drawText(QRect(pos.x() + 12, pos.y() + 4, pos.x() + 12 + valueWidth, pos.y() + 4 + valueHeight), m_value); return QPoint(pos.x() + valueWidth + 20, pos.y()); }
REGULAR_EXPRESSION статикалық тұрақты айнымалы мәні формуланың пайда болуын іздеу үшін тұрақты өрнекті қамтитын жол болып табылады.
Qt тұрақты өрнектермен жұмыс істеу үшін екі сыныпты ұсынады:
- QRegExp - Мен оны html белгілеу синтаксисін бөлектеуді жазу туралы мақалада қолдандым.
- QRegularExpression - Мен бұл туралы әлі мақала жазған жоқпын және бұл оны қолданатын бірінші мақала болмақ.
Бірінші класс бұрын енгізілді, екіншісі тек Qt 5.0-де енгізілді. Біріншісі, менің түсінуімше, Qt-тің тұрақты өрнектерді жеке жүзеге асыруы. Ал екінші класс тек Perl тіліне арналған синтаксистік қолдауы бар тұрақты өрнектерді іске асыру болып табылады. Әзірге құжаттама QRegularExpression пайдалануды ұсынады және тұрақты өрнектердің синтаксисін үйрену үшін Perl құжаттамасын зерттеңіз.
Қорқынышты сызу әдісіне келетін болсақ, оның орындалуы формуланы әдемі сызуға, квадрат түбір ішіндегі мәннің орнын орнатуға жауап береді. Сиқырлы сандар бар барлық сызықтар мен сандарды пиксель бойынша көрсету үшін псевдоматематика жеткілікті. Нақты жобаларда мұны болдырмауға тырысыңыз және PADDING_BOTTOM, OFFSET және т.б. сияқты аталған тұрақтыларды пайдаланыңыз.
draw әдісіндегі маңызды сәттердің бірі QPainter нысаны сілтеме арқылы аргумент ретінде берілуі керек, бірақ сілтеме const болуы мүмкін емес, себебі бұл нысан өзгертілетін болады. Демек, мұнда бәрі жақсы. Өз тәжірибемнен айтамын, бұл реттелетін виджеттерді көрсетумен жұмыс істеу үшін олардың QPainter басқа әдістерге тұрақты емес сілтеме арқылы берілген кезде қалыпты жағдай.
Жоғарыдағы тұрақты өрнекте кейінірек сызу үшін түбірдегі мәнді шығаруға болатын аталған түсірілген мән бар.
"sqrt\((?
формула виджеті
FormulaWidget.h
// Класс для отрисовки всех формул class FormulaWidget : public QWidget { Q_OBJECT using BaseClass = QWidget; public: explicit FormulaWidget(QWidget* parent = nullptr); public slots: // Слот для установки формулы void setFormula(const QString& formula); protected: virtual void paintEvent(QPaintEvent* event) override; private: QList<FormulaItem> m_items; };
Сыныпта екі маңызды әдіс бар. Біріншісі формулаларды шығаратын жолды орнатуға арналған, ал екіншісі қайта анықталған әдіс paintEvent(). Қайта анықталған әдіс виджетті салуға жауап береді, біз ондағы барлық формулаларды да саламыз. . Бұл әдіс оқиғаны өңдеу әдістерінің стекінде Qt деп аталады. Бұл әдіс ешқашан тікелей шақырылмайды, белгілі бір оқиғалар орын алған кезде шақырылады, бірақ оны шақыру үшін update(). әдісін шақыру жеткілікті.
FormulaWidget.cpp
FormulaWidget::FormulaWidget(QWidget* parent) : BaseClass(parent) { // Установим цвет фона виджета, по умолчанию он такой же, как в системном оформлении ОС QPalette pal = palette(); pal.setColor(QPalette::Background, Qt::white); setAutoFillBackground(true); setPalette(pal); } void FormulaWidget::setFormula(const QString& formula) { // Очищаем все формулы m_items.clear(); // Создаём объект регулярного выражения для поиска формулы QRegularExpression sqrt_value(FormulaItem::REGULAR_EXPRESSION); // Ищем все вхождения формулы QRegularExpressionMatchIterator i = sqrt_value.globalMatch(formula); // создаём все объекты формул while (i.hasNext()) { QRegularExpressionMatch match = i.next(); if (match.hasMatch()) { m_items.append(FormulaItem(match.captured("value"))); } } // Запускаем перерисовку update(); } void FormulaWidget::paintEvent(QPaintEvent* event) { // Для перерисовки используется объект QPainter, // который обязательно должен получить объект за отрисовку которого он отвечает QPainter p(this); p.setRenderHint(QPainter::Antialiasing); p.setPen(Qt::black); QPoint formulaPos(2, 2); // Производим отрисовку всех формул, которые удалось найти for (const FormulaItem& item : m_items) { formulaPos = item.draw(formulaPos, p); } }
Осы кодтың нәтижесінде мақаланың басындағы скриншотта көрсетілген қолданба алынады.
Мен сондай-ақ жоба кодын қосамын. Жүктеп алу