Методы приближения функций

как работать с заготовкой на Qt

пункты меню

ввод с клавиатуры

рисование с использованием QPainter

https://maxxk.github.io/programming-semester-6/

Qt

Скачать Qt 4: http://download.qt.io/archive/qt/4.8/4.8.6/

При установке проверить, что отмечен Qt Creator, он может открыть файл проекта basic_graph.pro

Проще компилировать в терминале. Вместо Makefile используется файл проекта:

HEADERS       = window.h
SOURCES       = main.cpp \
              window.cpp

Сборка (в каталоге с программой):

qmake        # qmake-qt4 в дисплейных классах
             # Для отладки: qmake CONFIG+=debug
make

C++ (на уровне «C с классами») I

window.h

class Window : public QWidget {

private: // внутренние поля
  int func_id, n; // переменная-член
  double *x, *f, *params; // параметры программы
  int prepare(); // функция подготовки для приближения
public: // общедоступные поля
  Window (QWidget *parent); // конструктор
  QSize minimumSizeHint () const; // функция-член
  // const = не меняет состояния переменных-членов класса
}

C++ (на уровне «C с классами») II

window.cpp

static // статическая функция = не член класса
double f_0 (double x) {
// return f[0]; // ERROR - нет доступа к переменной-члену f
return x;
}
// Конструктор инициализирует переменные
Window::Window (QWidget *parent)
: QWidget (parent)
{
  a = DEFAULT_A;
  x = (double*)malloc(n * sizeof(double));
}

C++ (на уровне «C с классами») III

window.cpp

// Функция-член
void Window::change_func ()
{
  // есть доступ к членам класса
  func_id = (func_id + 1) % 2;

  // Warning: если определить локальную переменную
  // с именем, совпадающим с именем члена класса
  // использоваться будет локальная переменная
  double func_id = -1.; // не делайте так

  func_id == -1.;

  // доступ к члену класса в этом случае:
  this->func_id
}

Меню и горячие клавиши

window.h

public slots:  // специфично для Qt
void change_func (); // тип void, без аргументов

main.cpp

action = tool_bar->addAction ("Change function",
  graph_area, SLOT (change_func ()));
action->setShortcut (QString ("Ctrl+C"));

window.cpp

// обработчик
void Window::change_func () {
  func_id = (func_id + 1) % 2;
  update ();
}

Ввод с клавиатуры I

(консольный)

С использованием стандартных функций C:

#include <cstdio>  // вместо <stdio.h>
#include <cstdlib> // вместо <stdlib.h>
// ...
double x;
if (scanf("%lf", &x) != 1) {
/* ... */
}

С использованием стандартных потоков C++:

#include <iostream>
// ...
double x;
std::cin >> x;

Ввод с клавиатуры II

(графический) http://doc.qt.io/qt-4.8/qinputdialog.html#details

С использованием диалога (в других программах лучше не использовать — раздражает пользователя, по-хорошему нужно просто держать рядом с основным окном общий диалог со всеми параметрами и кнопкой «обновить»)

#include <QInputDialog>

bool ok;
// есть ещё ::getInt, ::getText, ::getItem
double d = QInputDialog::getDouble(this,
"QInputDialog::getDouble()", // заголовок диалога
"Amount:",                   // подпись
37.56, -10000, 10000, 2, // default, min, max, decimal
&ok);                    // нажал ли пользователь «ОК»

if (ok)
    doubleLabel->setText(QString("$%1").arg(d));

Рисование в QPainter I

http://doc.qt.io/qt-4.8/qpainter.html

Для перерисовки окна после обновления параметров вызывайте update().

Всё рисование выполняется в Window::paintEvent.

painter.setPen("black"); // установить цвет

Полный список цветов: http://doc.qt.io/qt-4.8/qcolor.html#setNamedColor

// линия от (x1, y1) до (x2, y2)
// в текущей системе координат
painter.drawLine(QPointF(x1, y1), QPointF(x2, y2));

Для рисования можно использовать количество точек width() или width()/2, меньше точек — хуже картинка.

Рисование в QPainter II

// сохранить систему координат
painter.save();

// восстановить сохранённую систему
painter.restore();

// написать текст
painter.drawText (/* x */ 0, /* y */ 20, "Some text");

Замена координат

Исходная система координат

Замена координат

масштабирование

Замена координат

painter.scale (width () / (b - a), -height () / (max_y - min_y));

Замена координат

painter.translate (-0.5 * (a + b), -0.5 * (min_y + max_y));
(a, b) и (min_y, max_y) задают ограничивающий прямоугольник отображаемой части графика