Spec-Zone.ru › Qt 5.9

Начало работы с Qt Widgets

В этом разделе мы изучим основы Qt, реализовав простое приложение «Блокнот» с использованием C++ и модуля Qt Widgets. Приложение представляет собой небольшой текстовый редактор, который позволяет создавать текстовый файл, сохранять его, печатать, повторно открывать и редактировать. Также вы можете задать шрифт.

"Notepad application"

Вы можете найти исходные файлы приложения «Блокнот» в репозитории qtdoc в каталоге snippets/widgets-tutorial/notepad. Вы можете скачать исходники Qt 5 с сайта Qt Project или установить их как часть Qt 5.

Создание проекта «Блокнот»

Настройка нового проекта в Qt Creator облегчается с помощью мастера, который пошагово проведет вас через процесс создания проекта. Мастер запросит у вас необходимые настройки для этого типа проекта и создаст проект.

"Qt Creator New File or Project dialog"

Чтобы создать проект «Блокнот», выберите Файл > Создать новый файл или проект > Приложения > Приложение Qt Widgets > Выбрать и следуйте инструкциям мастера. В диалоговом окне Информация о классе введите Notepad в качестве имени класса и выберите QMainWindow в качестве базового класса.

"Class Information Dialog"

Мастер Приложение Qt Widgets создает проект, содержащий главный исходный файл и набор файлов, определяющих пользовательский интерфейс (виджет «Блокнот»):

  • notepad.pro – файл проекта.
  • main.cpp – главный исходный файл приложения.
  • notepad.cpp – исходный файл класса notepad для виджета «Блокнот».
  • notepad.h – заголовочный файл класса notepad для виджета «Блокнот».
  • notepad.ui – форма пользовательского интерфейса для виджета «Блокнот».

Файлы с расширениями .cpp, .h и .ui содержат необходимый шаблонный код, который позволит вам скомпилировать и запустить проект. Файл .pro завершен. В следующих разделах мы более подробно рассмотрим содержимое этих файлов.

Дополнительная информация

О Здесь
Использование Qt Creator Qt Creator
Создание других типов приложений с помощью Qt Creator Учебники по Qt Creator

Главный исходный файл

Мастер генерирует следующий код в файле main.cpp:

#include "notepad.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication EditorApp(argc, argv);
    Notepad Editor;
    Editor.show();

    return EditorApp.exec();
}

Мы пройдемся по коду построчно. Следующие строки включают заголовочные файлы для виджета «Блокнот» и QApplication. Все классы Qt имеют заголовочный файл, названный так же, как и класс.

#include "notepad.h"
#include <QApplication>

Следующая строка определяет функцию main, которая является точкой входа для всех приложений, основанных на C и C++:

int main(int argc, char *argv[])
{

Следующая строка создает объект QApplication. Этот объект управляет ресурсами всего приложения и необходим для запуска любой программы Qt, использующей Qt Widgets. Он создаёт объект приложения с argc аргументами командной строки, запущенными в argv. (Для приложений графического интерфейса, не использующих Qt Widgets, можно использовать QGuiApplication.)

    QApplication EditorApp(argc, argv);

Следующая строка создает объект Notepad. Это объект, для которого мастер создал класс и файл пользовательского интерфейса. Пользовательский интерфейс содержит визуальные элементы, которые называются widgets в Qt. Примерами виджетов являются поля редактирования текста, полосы прокрутки, метки и радиокнопки. Виджет также может быть контейнером для других виджетов; например, диалоговое окно или главное окно приложения.

    Notepad Editor;

Следующая строка отображает виджет «Блокнот» на экране в собственном окне. Виджеты также могут выполнять функции контейнеров. Примером является QMainWindow, который часто содержит несколько типов виджетов. Виджеты по умолчанию не отображаются; функция show() делает виджет видимым.

    Editor.show();

Следующая строка заставляет QApplication войти в цикл обработки событий. При запуске приложения Qt генерируются события и отправляются виджетам приложения. Примерами событий являются нажатия мыши и нажатия клавиш.

    return EditorApp.exec();

Дополнительная информация

О Здесь
Виджеты и геометрия окна Окна и диалоговые виджеты
События и обработка событий Система обработки событий

Проектирование пользовательского интерфейса

Мастер генерирует определение пользовательского интерфейса в формате XML: notepad.ui. При открытии файла notepad.ui в Qt Creator он автоматически открывается в интегрированном Qt Designer.

При компиляции приложения Qt Creator запускает компилятор пользовательского интерфейса Qt (uic), который считывает файл .ui и создаёт соответствующий заголовочный файл C++, ui_notepad.h.

Использование Qt Designer

Мастер создаёт приложение, использующее QMainWindow. У него есть собственная компоновка, в которую можно добавить строку меню, виджеты-доки, панели инструментов и строку состояния. Центральная область может быть занята любым типом виджета. Мастер помещает туда виджет «Блокнот».

Для добавления виджетов в Qt Designer:

  1. В режиме редактирования Qt Creator дважды щелкните файл notepad.ui в представлении «Проекты», чтобы открыть файл в интегрированном Qt Designer.
  2. Перетащите виджет «Поле редактирования текста» (QTextEdit) на форму.
  3. Нажмите Ctrl+A (или Cmd+A), чтобы выбрать виджеты, и нажмите Разместить вертикально (или нажмите Ctrl+L), чтобы применить вертикальную компоновку (QVBoxLayout).
  4. Нажмите Ctrl+S (или Cmd+S), чтобы сохранить изменения.

Пользовательский интерфейс теперь выглядит следующим образом в Qt Designer:

Вы можете просмотреть сгенерированный XML-файл в редакторе кода:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Notepad</class>
 <widget class="QMainWindow" name="Notepad">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>524</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Notepad</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTextEdit" name="textEdit"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
    ...

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

<?xml version="1.0" encoding="UTF-8"?>

Остальная часть файла определяет элемент ui, который определяет виджет «Блокнот»:

<ui version="4.0">

Файл пользовательского интерфейса используется совместно с заголовочным и исходным файлом класса Notepad. В следующих разделах мы рассмотрим остальную часть файла пользовательского интерфейса.

Заголовочный файл Notepad

Мастер сгенерировал заголовочный файл для класса Notepad, содержащий необходимые #include, конструктор, деструктор и объект Ui. Файл выглядит следующим образом:

#include <QMainWindow>

namespace Ui {
class Notepad;
}

class Notepad : public QMainWindow
{
    Q_OBJECT

public:
    explicit Notepad(QWidget *parent = 0);
    ~Notepad();

private:
    Ui::Notepad *ui;
};

Следующая строка включает QMainWindow, который предоставляет главное окно приложения:

#include <QMainWindow>

Следующие строки объявляют класс Notepad в пространстве имён Ui, которое является стандартным пространством имён для классов пользовательского интерфейса, сгенерированных из файлов .ui инструментом uic:

namespace Ui {
class Notepad;
}

Объявление класса содержит макрос Q_OBJECT. Он должен стоять первым в определении класса и объявляет наш класс как QObject. Естественно, он также должен наследоваться от QObject. QObject добавляет несколько возможностей к обычному классу C++. В частности, имя класса и имена слотов можно запросить во время выполнения. Также возможно запросить типы параметров слота и вызвать его.

class Notepad : public QMainWindow
{
    Q_OBJECT

Следующие строки объявляют конструктор, имеющий аргумент по умолчанию, называемый parent. Значение 0 указывает, что у виджета нет родителя (это виджет верхнего уровня).

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

Следующая строка объявляет виртуальный деструктор для освобождения ресурсов, полученных объектом за время его жизненного цикла. Согласно соглашению об именовании C++, деструкторы имеют то же имя, что и класс, к которому они относятся, с префиксом тильда (~). В QObject деструкторы виртуальные, чтобы гарантировать, что деструкторы производных классов вызываются должным образом, когда объект удаляется через указатель на базовый класс.

    ~Notepad();

Следующие строки объявляют член-переменную, которая является указателем на класс пользовательского интерфейса Notepad. Член-переменная связана с определенным классом и доступна для всех его методов.

private:
    Ui::Notepad *ui;

Исходный файл Notepad

Исходный файл, сгенерированный мастером для класса Notepad, выглядит следующим образом:

#include "notepad.h"
#include "ui_notepad.h"

Notepad::Notepad(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Notepad)
{

    ui->setupUi(this);
}

Notepad::~Notepad()
{
    delete ui;
}

Следующие строки включают заголовочный файл класса Notepad, сгенерированный мастером, и заголовочный файл пользовательского интерфейса, сгенерированный инструментом uic:

#include "notepad.h"
#include "ui_notepad.h"

Следующая строка определяет конструктор Notepad:

Notepad::Notepad(QWidget *parent) :

Следующая строка вызывает конструктор QMainWindow, который является базовым классом для класса Notepad:

    QMainWindow(parent),

Следующая строка создает экземпляр класса пользовательского интерфейса и присваивает его члену ui:

    ui(new Ui::Notepad)

Следующая строка настраивает пользовательский интерфейс:

    ui->setupUi(this);

В деструкторе мы удаляем ui:

Notepad::~Notepad()
{
    delete ui;
}

Для того, чтобы поле редактирования текста занимало весь экран, мы добавляем setCentralWidget в главное окно.

Notepad::Notepad(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Notepad)
{
    ui->setupUi(this);
    this->setCentralWidget(ui->textEdit);
}

Файл проекта

Мастер генерирует для нас следующий файл проекта, notepad.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2017-07-10T14:20:07
#
#-------------------------------------------------

QT       += core gui printsupport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Notepad
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp\
        notepad.cpp

HEADERS  += notepad.h

FORMS    += notepad.ui

RESOURCES += \
    notepad.qrc

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

Вы также можете использовать qmake's -project вариант для генерации файла .pro. Однако в этом случае вам нужно помнить, чтобы добавить строку QT += widgets в сгенерированный файл, чтобы связаться с модулем Qt Widgets.

Дополнительная информация

О Здесь
Использование Qt Designer Справочник Qt Designer
Компоновки Управление компоновкой, Виджеты и компоновки, Примеры компоновок
Виджеты, которые поставляются с Qt Галерея виджетов Qt
Главные окна и классы главных окон Главное окно приложения, Примеры главного окна
QObjects и модель объектов Qt (необходимо понять Qt) Модель объектов
qmake и система сборки Qt Справочник qmake

Добавление взаимодействия с пользователем

Чтобы добавить функциональность редактору, мы начнем с добавления пунктов меню и кнопок на панели инструментов.

Нажмите на «Ввести здесь» и добавьте параметры «Новый», «Открыть», «Сохранить», «Сохранить как», «Печать» и «Выход». Это создаст 5 строк в редакторе действий ниже. Чтобы связать действия со слотами, щелкните правой кнопкой мыши действие и выберите «Перейти к слоту» > «triggered()», а затем заполните код для этого слота.

Если мы также хотим добавить действия в панель инструментов, мы можем назначить значок каждому QAction, а затем перетащить QAction на панель инструментов. Вы назначаете значок, введя имя значка в свойстве «Значок» соответствующего действия. Когда QAction перетащен на панель инструментов, щелчок по значку запустит связанный слот.

Заполните метод on_actionNew_triggered():

void Notepad::on_actionNew_triggered()
{
    currentFile = "";
    ui->textEdit->setText("");
}

current_file — это глобальная переменная, содержащая файл, который в настоящее время редактируется. Она определена в частной части notepad.h:

private:
    Ui::Notepad *ui;
    QString CurrentFile;

setText("") очищает буфер текста.

Открытие файла

В notepad.ui щелкните правой кнопкой мыши actionOpen и выберите Go to slot

Заполните метод on_actionOpen_triggered().

void Notepad::on_actionOpen_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, "Open the file");
    QFile file(fileName);
    currentFile = fileName;
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this,"..","File not opened.");
        return;
    }
    QTextStream in(&file);
    QString text = in.readAll();
    ui->textEdit->setText(text);
    file.close();
}

QFileDialog::getOpenFileName открывает диалоговое окно, позволяющее выбрать файл. Объект QFile myfile имеет выбранный file_name в качестве параметра. Мы также сохраняем выбранный файл в глобальную переменную current_file для последующего использования. Мы открываем файл с file.open как текстовый файл только для чтения. Если его невозможно открыть, выводится предупреждение, и программа останавливается.

Мы определяем QTextStream instream для параметра myfile. Содержимое файла myfile копируется в QString text. setText(text) заполняет буфер нашего редактора содержимым text.

section2 Сохранение файла

Мы создаём метод для сохранения файла аналогично методу для Открытия файла, щелкнув правой кнопкой мыши actionSave и выбрав Go to Slot.

void Notepad::on_actionSave_triggered()
{
    QFile file(currentFile);
    if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this,"..","No file opened. Use Save As");
        return;
    }
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.flush();
    file.close();
}

Объект QFile myfile связан с глобальной переменной current_file, переменной, содержащей файл, с которым мы работали. Если мы не можем открыть myfile, выводится сообщение об ошибке, и метод останавливается. Мы создаём QTextStream outstream. Содержимое буфера редактора преобразуется в обычный текст и записывается в outstream.

section2 Сохранение файла с Save as

void Notepad::on_actionSave_as_triggered()
{
    QString fileName = QFileDialog::getSaveFileName(this, "Save as");
    QFile file(fileName);
    currentFile = fileName;
    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this,"..","File not opened.");
        return;
    }
    QTextStream out(&file);
    QString text = ui->textEdit->toPlainText();
    out << text;
    file.flush();
    file.close();
}

Это та же процедура, что и для Saving a file, единственное отличие заключается в том, что здесь вам необходимо ввести новое имя файла для создания файла.

Печать файла

Если вы хотите использовать функции печати, вам нужно добавить printsupport в файл проекта:

QT += core gui printsupport

Мы объявляем объект QPrinter с именем printer. Мы запускаем диалоговое окно принтера и сохраняем выбранный принтер в объекте printer. Если мы щелкнули по Cancel и не выбрали принтер, методы возвращают значение. Фактическая команда печати выполняется с помощью ui->textEdit->print с нашим объектом QPrinter в качестве параметра.

Выбор шрифта

void Notepad::on_actionFont_triggered()
{
    bool fontSelected;
    QFont font = QFontDialog::getFont(&fontSelected, this);
    if (fontSelected) {
        ui->textEdit->setFont(font);
    }
}

Мы объявляем булево значение, указывающее, выбрали ли мы шрифт с помощью QFontDialog. В таком случае мы устанавливаем шрифт с помощью ui->textEdit->setFont(myfont).

Копирование, вырезание, вставка, отмена, повторение

Если вы выделили текст и хотите скопировать его в буфер обмена, вызывается соответствующий метод ui->textEdit. То же самое касается вырезания, вставки, отмены и повторения.

В этой таблице показано имя метода, который нужно использовать.

Задача Вызываемый метод
Копирование ui->textEdit->copy()
Вырезание ui->textEdit->cut()
Вставка ui->textEdit->paste()
Отмена ui->textEdit->undo()
Повторение ui->textEdit->redo()

В этом проекте содержатся следующие файлы:

  • {main.cpp}
  • {notepad.cpp}
  • {notepad.h}
  • {notepad.pro}
  • {notepad.ui}

Дополнительная информация

О Здесь
MDI-приложения QMdiArea, Пример MDI
Файлы и устройства ввода-вывода QFile, QIODevice
tr() и международная локализация Руководство Qt Linguist, Написание исходного кода для перевода, Международная локализация с Qt

Сборка и запуск Блокнота

Теперь, когда у вас есть все необходимые файлы, выберите Сборка > Собрать проект Блокнот, чтобы собрать и запустить приложение. Qt Creator использует qmake и make для создания исполняемого файла в каталоге, указанном в настройках сборки проекта, и запускает его.

Сборка и запуск из командной строки

Чтобы собрать приложение из командной строки, переключитесь на каталог, в котором находится файл .cpp приложения, и добавьте файл проекта (с расширением .pro), описанный ранее. Затем следующие команды оболочки собирают приложение:

qmake
make (or nmake on Windows)

Команды создают исполняемый файл в каталоге проекта. Инструмент qmake считывает файл проекта и генерирует Makefile с инструкциями по сборке приложения. Затем инструмент make (или инструмент nmake) считывает Makefile и генерирует двоичный исполняемый файл.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.9/gettingstartedqt.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API