Приложения QT. Создание меню верхнего уровня.

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

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

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

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

QMenu *fileMenu;

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

void createMenu();
void createActions();

Первая функция создаст пункты верхнего меню (пока это только пункт File), а вторая создаст экшн, то есть в данном примере подпункт 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");

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

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

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

Вот теперь изображение появится, где надо.

Продолжаем… Устанавливаем объект aboutWindowPix в 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

Вот так просто мы реализовали два пункта верхнего меню, и наше приложение стало хоть и ненамного, но удобнее =))

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

Приложения QT. Создание меню верхнего уровня.: 4 комментария
  1. C:\Users\velichanskij\Documents\Menu\mainwindow.cpp:21: ошибка: C2065: saveAction: необъявленный идентификатор

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

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