Приложения QT. Меню верхнего уровня, часть2.

Продолжаем работать с интерфейсом нашего проекта (начало тут) и сегодня замутим меню для работы непосредственно с графиком. В качестве примера создадим пункт меню Graph и подпункт Scale для изменения пределов по осям x и y.

Сначала создадим диалоговое окно, содержащее два объекта класса QspinBox. В этом окне пользователь выберет максимальные значения для отображения на осях. Для всего этого мы реализуем новый класс ScaleActionMenu. Итак, идем в файл menuclass.h и добавляем туда объявление нашего класса:

class ScaleActionMenu : public QWidget
{
    Q_OBJECT
 
public:
    explicit ScaleActionMenu(QWidget *parent = 0);
    QSpinBox *xAxisMaxSpinBox;
    QSpinBox *yAxisMaxSpinBox;
 
private:
    QLabel *xAxisLabel;
    QLabel *xAxisMaxLabel;
    QLabel *yAxisLabel;
    QLabel *yAxisMaxLabel;
 
signals:
    void valueChanged(int i);
};

Объекты Qlabel нам нужны для надписей типа «Axis X» в менюшке. Для общения же с пользователем, как и решили выше, будем использовать spinbox’ы:

QSpinBox *xAxisMaxSpinBox;
QSpinBox *yAxisMaxSpinBox;

Кроме этого объявляем сигнал valueChanged(int i), который нужен, собственно, для того, чтобы обработать выбор пользователя. Скоро мы привяжем к этому сигналу парочку слотов, но сначала закончим с диалоговым окном – создадим конструктор класса в файле menuclass.cpp:

ScaleActionMenu::ScaleActionMenu(QWidget *parent) :
    QWidget(parent)
{
    this->setWindowTitle("Scale");
    xAxisLabel = new QLabel("X Axis Scale");
    xAxisMaxLabel = new QLabel("Maximum Value");
    yAxisLabel = new QLabel("Y Axis Scale");
    yAxisMaxLabel = new QLabel("Maxomum Value");
    xAxisMaxSpinBox = new QSpinBox;
    yAxisMaxSpinBox = new QSpinBox;
    xAxisMaxSpinBox->setRange(0,10);
    yAxisMaxSpinBox->setRange(0,10);
    QVBoxLayout *scaleActionMenuLayout = new QVBoxLayout;
    scaleActionMenuLayout->addWidget(xAxisLabel);
    scaleActionMenuLayout->addWidget(xAxisMaxLabel);
    scaleActionMenuLayout->addWidget(xAxisMaxSpinBox);
    scaleActionMenuLayout->addWidget(yAxisLabel);
    scaleActionMenuLayout->addWidget(yAxisMaxLabel);
    scaleActionMenuLayout->addWidget(yAxisMaxSpinBox);
    this->setLayout(scaleActionMenuLayout);
    this->resize(150, 200);
}

Давайте опять прямо по строчкам разбираться, что тут происходит.

Задаем имя окна, а также текст, который поможет пользователю понять, что же вообще от него требуется:

this->setWindowTitle("Scale");
xAxisLabel = new QLabel("X Axis Scale");
xAxisMaxLabel = new QLabel("Maximum Value");
yAxisLabel = new QLabel("Y Axis Scale");
yAxisMaxLabel = new QLabel("Maxomum Value");

Все эти объекты Qlabel – просто текст и ничего более 😉 Когда будет создано окно можно будет увидеть, что и где отображается.

Теперь создаем «спинбоксы» и задаем пределы, в которых могут меняться значения:

xAxisMaxSpinBox = new QSpinBox;
yAxisMaxSpinBox = new QSpinBox;
xAxisMaxSpinBox->setRange(0,10);
yAxisMaxSpinBox->setRange(0,10);

То есть значение xAxisMaxSpinBox может меняться от 0 до 10, а соответственно на оси x будут отображаться разные значения. Забегая вперед, скажу, что по оси y мы будем менять только максимальное отображаемое значение, а по оси x – и минимальное и максимальное. Например, при значении xAxisMaxSpinBox, равном 5, на оси x будут значения от -5 до 5, а при значении yAxisMaxSpinBox (отвечает за ось y), равном 5, на оси y будут значения от 0 до 5. Это связано с тем что у нас функция симметричная относительно оси y.

Так..что там дальше..

А дальше мы просто располагаем все элементы друг над другом в нужной нам последовательности:

QVBoxLayout *scaleActionMenuLayout = new QVBoxLayout;
scaleActionMenuLayout->addWidget(xAxisLabel);
scaleActionMenuLayout->addWidget(xAxisMaxLabel);
scaleActionMenuLayout->addWidget(xAxisMaxSpinBox);
scaleActionMenuLayout->addWidget(yAxisLabel);
scaleActionMenuLayout->addWidget(yAxisMaxLabel);
scaleActionMenuLayout->addWidget(yAxisMaxSpinBox);
this->setLayout(scaleActionMenuLayout);
this->resize(150, 200);

И меняем размер окна.

Теперь нам нужно создать пункт верхнего меню Graph и в выпадающем меню – пункт Scale. Для этого делаем все также, как в первой части этого повествования (в начале статьи есть ссылочка). А именно:

Объявляем слоты:

void showScaleMenu();
void scaleActionX(int i);
void scaleActionY(int i);

Первый слот – для показа диалогового окна при выборе меню Scale, два других слота – для изменения пределов по осям x и y соответственно.

Помимо этого в файле MainWindow.h добавляем еще пару членов к классу:

QMenu *graphMenu;
QAction *saveAction;

И переходим к файлу MainWindow.cpp.

В методе createActions() добавляем:

scaleAction = new QAction(tr("&Scale"), this);
connect(scaleAction, SIGNAL( activated() ), this, SLOT(showScaleMenu () ) );

Тут мы привязали к пункту меню слот showScaleMenu(). Сразу же, пока не забыли, в методе createMenu() дописываем:

graphMenu = menuBar()->addMenu(tr("&Graph"));
graphMenu->addAction(scaleAction);

Подготовка завершена, реализуем слот showScaleMenu():

void MainWindow::showScaleMenu()
{
    ScaleActionMenu *scaleMenu = new ScaleActionMenu();
    scaleMenu->setVisible(true);
    connect(scaleMenu->xAxisMaxSpinBox, SIGNAL( valueChanged(int) ), this, SLOT( scaleActionX(int) ) );
    connect(scaleMenu->yAxisMaxSpinBox, SIGNAL( valueChanged(int) ), this, SLOT( scaleActionY(int) ) );
}

Здесь мы создаем объект нашего класса ScaleActionMenu и показываем его пользователю. А к «спинбоксам» (точнее к сигналу, который они эмитируют при изменении значения) прикручиваем слоты scaleActionX(int) и scaleActionY(int).

Осталось совсем немного, пишем:

void MainWindow::scaleActionX(int i)
{
    this->plot->setAxisScale(QwtPlot::xBottom, -i, i);
    plot->replot();
}
 
void MainWindow::scaleActionY(int i)
{
    this->plot->setAxisScale(QwtPlot::yLeft, 0, i);
    plot->replot();
}

Методы, которые выполнят полезную работу и изменят масштаб осей. Тут все вроде бы очевидно, так что пробуем запустить:
Меню верхнего уровня в QT
Получили то, что хотели 😉

В общем ничего сложного тут не было, но, разобравшись с такой простой менюшкой, можно в принципе написать довольно удобный интерфейс для своего приложения.

Понравилась статья? Поделись с друзьями!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *