Evgenii Legotckoi
Evgenii LegotckoiСәуір 21, 2018, 4:18 Т.Қ.

Qt/C++ - 076-сабақ. Qt-дағы математикалық формулаларды визуализациялау

Жақында форумда 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 тұрақты өрнектермен жұмыс істеу үшін екі сыныпты ұсынады:

  1. QRegExp - Мен оны html белгілеу синтаксисін бөлектеуді жазу туралы мақалада қолдандым.
  2. QRegularExpression - Мен бұл туралы әлі мақала жазған жоқпын және бұл оны қолданатын бірінші мақала болмақ.

Бірінші класс бұрын енгізілді, екіншісі тек Qt 5.0-де енгізілді. Біріншісі, менің түсінуімше, Qt-тің тұрақты өрнектерді жеке жүзеге асыруы. Ал екінші класс тек Perl тіліне арналған синтаксистік қолдауы бар тұрақты өрнектерді іске асыру болып табылады. Әзірге құжаттама QRegularExpression пайдалануды ұсынады және тұрақты өрнектердің синтаксисін үйрену үшін Perl құжаттамасын зерттеңіз.

Қорқынышты сызу әдісіне келетін болсақ, оның орындалуы формуланы әдемі сызуға, квадрат түбір ішіндегі мәннің орнын орнатуға жауап береді. Сиқырлы сандар бар барлық сызықтар мен сандарды пиксель бойынша көрсету үшін псевдоматематика жеткілікті. Нақты жобаларда мұны болдырмауға тырысыңыз және PADDING_BOTTOM, OFFSET және т.б. сияқты аталған тұрақтыларды пайдаланыңыз.

draw әдісіндегі маңызды сәттердің бірі QPainter нысаны сілтеме арқылы аргумент ретінде берілуі керек, бірақ сілтеме const болуы мүмкін емес, себебі бұл нысан өзгертілетін болады. Демек, мұнда бәрі жақсы. Өз тәжірибемнен айтамын, бұл реттелетін виджеттерді көрсетумен жұмыс істеу үшін олардың QPainter басқа әдістерге тұрақты емес сілтеме арқылы берілген кезде қалыпты жағдай.

Жоғарыдағы тұрақты өрнекте кейінірек сызу үшін түбірдегі мәнді шығаруға болатын аталған түсірілген мән бар.

"sqrt\((? \d+)\)" - бұл тұрақты өрнекте бұл атау мән болып табылады.

формула виджеті

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

Осы кодтың нәтижесінде мақаланың басындағы скриншотта көрсетілген қолданба алынады.

Мен сондай-ақ жоба кодын қосамын. Жүктеп алу

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
m
  • molni99
  • Қаз. 26, 2024, 1:29 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:20ұпай,
  • Бағалау ұпайлары-10
Соңғы пікірлер
i
innorwallҚар. 13, 2024, 11:03 Т.Қ.
Qt тілінде ойын қалай жазылады - 3-сабақ. Басқа объектілермен әрекеттесу what is priligy tablets What happens during the LASIK surgery process
i
innorwallҚар. 13, 2024, 8:09 Т.Қ.
C++ файлдарының ішінде CMakeLists.txt ішінде жарияланған айнымалы мәндерді пайдалану where can i buy priligy online safely Tom Platz How about things like we read about in the magazines like roid rage and does that really
i
innorwallҚар. 11, 2024, 10:12 Т.Қ.
Django - Оқулық 055. Автоматты толтыру өрісі функциясын қалай жазу керек Freckles because of several brand names retin a, atralin buy generic priligy
i
innorwallҚар. 11, 2024, 6:23 Т.Қ.
QML - Сабақ 035. C++ қолданбай QML тілінде сандарды пайдалану priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
i
innorwallҚар. 11, 2024, 3:50 Т.Қ.
Qt/C++ - 052-сабақ. Qt аудио ойнатқышын AIMP стилінде теңшеу It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
Енді форумда талқылаңыз
i
innorwallҚар. 13, 2024, 6:52 Т.Қ.
добавить qlineseries в функции PMID 35774217 Free PMC article priligy cvs
i
innorwallҚар. 11, 2024, 10:55 Т.Ж.
Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз