Top.Mail.Ru

Приложения 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("Maximum 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 и показываем его пользователю. А к QSpinBox (точнее к сигналам, который они эмитируют при изменении значения) прикручиваем слоты 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.

Получили то, что хотели, все работает верно )

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

Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x