Top.Mail.Ru

Приложения Qt. Создание меню верхнего уровня. Часть 1.

На этой неделе будем заниматься усовершенствованием нашего приложения Qt, созданного ранее (подробнее тут).

Очевидно, что любое приложение должно предоставлять пользователю возможность изменить какие-либо параметры и настройки, сохранить результат работы приложения, посмотреть справочную информацию и т. п. Поэтому сегодня мы займемся созданием меню в Qt. В прошлых статьях мы создали проект, в котором при помощи библиотеки Qwt рисовался график функции y=|x|. Давайте в качестве примера прикрутим меню как раз к этому приложению.

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

Итак, начнем с того, что создадим в верхней части главного окна приложения пункт меню "File". В файле MainWindow.h объявляем новый член класса MainWindow:

QMenu *fileMenu;

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

void createMenu();
void createActions();

Первая функция создаст пункты верхнего меню (пока это только пункт File), а вторая создаст QAction, то есть в данном примере подпункт Save, при нажатии на который произойдет сохранение графика.

void MainWindow::createMenu()
{
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(saveAction);
}


void MainWindow::createActions()
{
	saveAction = new QAction(tr("&Save"), this);
	connect(saveAction, SIGNAL(activated()), this, SLOT(showSaveMenu()));
}

Мы привязали сигнал activated() объекта saveAction к слоту showSaveMenu() объекта MainWindow. Другими словами, при выборе пункта меню Save произойдет вызов функции showSaveMenu(). В конструктор класса MainWindow добавим вызовы:

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	ui->setupUi(this);
	createActions();
	createMenu();
	// Далее идет код нашего приложения из предыдущих статей :)

Теперь пришло время реализовать слот showSaveMenu(). В файле MainWindow.h объявляем:

public slots:
	void showSaveMenu();

И в файле MainWindow.c пишем:

void MainWindow::showSaveMenu()
{
	QString filename = QFileDialog::getSaveFileName(this, tr("Save Document"), QDir::currentPath(), tr("Images (*.JPG)"));
	QPixmap plotToPix;
	plotToPix = QPixmap::grabWidget(this->plot);
	plotToPix.save(filename, "JPG");
}

Алгоритм тут следующий... Создаем объект класса QString для хранения имени сохраняемого файла. Это имя будет получено в результате вызова диалогового окна сохранения файла:

QFileDialog::getSaveFileName(this, tr("Save Document"), QDir::currentPath(), tr("Images (*.JPG)"));

Параметры – название диалогового окна, путь и формат. Мы будем сохранять файл в jpg. Дальше мы объявляем объект plotToPix. Он нам нужен для того, чтобы непосредственно произвести сохранение. Сначала сохраняем график (объект plot) в объекте класса QPixmap, а затем уже сохраняем картинку вызовом функции save(). Вот собственно и все! Можно запустить и посмотреть, что получилось в итоге:

Меню в приложении Qt.

С сохранением разобрались, теперь давайте добавим еще один пункт меню – Help и подпункт About. При выборе этого пункта будет открываться новое окно с информацией о приложении. Для примера добавим в это окно какой-нибудь текст и тестовое изображение.

Делать все будем немного иначе по сравнению с меню сохранения файла. Добавим два новых файла в наш проект – menuclass.h и menuclass.cpp. Там мы реализуем класс окна, которое будет появляться при выборе пункта About в меню Help. А назовем мы этот класс InfoWindow. Вот полный код:

  • Файл menuclass.h:
class InfoWindow : public QWidget
{
	Q_OBJECT

public:
	explicit InfoWindow(QWidget *parent = 0);

signals:
	void activated(int i);

public slots:

private:
	QPixmap *aboutWindowPix;
	QLabel *aboutWindowLabel;
	QLabel *aboutWindowPixLabel;
};
  • Файл menuclass.cpp:
#include "menuclass.h"

InfoWindow::InfoWindow(QWidget *parent) :
	QWidget(parent)
{
	this->setWindowTitle("About");
	aboutWindowLabel = new QLabel("Info");
	aboutWindowPix = new QPixmap();
	aboutWindowPix->load(":images/testpicture.JPG");
	aboutWindowPixLabel = new QLabel();
	aboutWindowPixLabel->setPixmap(*aboutWindowPix);
	QVBoxLayout *aboutWindowLayout = new QVBoxLayout();
	aboutWindowLayout->addWidget(aboutWindowPixLabel);
	aboutWindowLayout->addWidget(aboutWindowLabel);
	this->setLayout(aboutWindowLayout);
	this->resize(100,200);
}

Давайте разбираться по порядку... Наше окно будет содержать текст и картинку, соответственно добавляем в класс три поля:

QPixmap *aboutWindowPix;
QLabel *aboutWindowLabel;
QLabel *aboutWindowPixLabel;

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

signals:
void activated(int i);

Идем в конструктор класса. Для начала даем имя нашему окну:

this->setWindowTitle("About");

Создаем два объекта класса QLabel – в один поместим наш текст, а в другой - нашу картинку. Саму картинку мы поместим в папку images, которую в свою очередь создадим в папке с проектом. Загружаем картинку в объект aboutWindowPix:

aboutWindowPix->load(":images/testpicture.JPG");

Но тут не все так просто. Приложение то соберется, вот только картинки там не окажется. А чтобы все стало на свои места нужно добавить к проекту файл ресурсов:

Создание файла ресурсов в Qt.

Открываем файл ресурсов в блокноте и прописываем туда путь к нашей картинке, например:

Файл ресурсов.

Вот теперь изображение появится, где надо, продолжаем… Устанавливаем объект aboutWindowPix в качестве Pixmap для aboutWindowPixLabel:

aboutWindowPixLabel->setPixmap(*aboutWindowPix);

Располагаем два объекта класса QLabel друг над другом:

QVBoxLayout *aboutWindowLayout = new QVBoxLayout();
aboutWindowLayout->addWidget(aboutWindowPixLabel);
aboutWindowLayout->addWidget(aboutWindowLabel);
this->setLayout(aboutWindowLayout);

Задаем размер окна и собственно все, окно информации готово! Осталось создать соответствующий пункт меню, как в случае с сохранением графика в начале статьи. Дополняем код функций createActions() и createMenu():

void MainWindow::createMenu()
{
	fileMenu = menuBar()->addMenu(tr("&File"));
	helpMenu = menuBar()->addMenu(tr("&Help"));
	fileMenu->addAction(saveAction);
	helpMenu->addAction(aboutAction);
}

void MainWindow::createActions()
{
	saveAction = new QAction(tr("&Save"), this);
	connect(saveAction, SIGNAL(activated() ), this, SLOT(showSaveMenu()));
	aboutAction = new QAction(tr("&About"), this);
	connect(aboutAction, SIGNAL( activated() ), this, SLOT(showInfo()));
}

Тут все аналогично созданию меню File - Save, так что двигаемся дальше. Мы привязали к выбору пункта About слот showInfo(), вот его нам и осталось реализовать:

void MainWindow::showInfo()
{
	InfoWindow *info = new InfoWindow();
	info->setVisible(true);
}

Вот и все, просто создаем объект нашего класса InfoWindow и делаем его видимым, собираем проект и пробуем запустить:

Меню верхнего уровня в Qt.
Подписаться
Уведомить о
guest

4 комментариев
Старые
Новые
Межтекстовые Отзывы
Посмотреть все комментарии
Avega
Avega
7 лет назад

C:\Users\velichanskij\Documents\Menu\mainwindow.cpp:21: ошибка: C2065: saveAction: необъявленный идентификатор

Avega
Avega
Ответ на комментарий  Aveal
7 лет назад

Спасибо, я уже разобрался)

4
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x