1 of 45

Объектно-ориентированное программирование и проектирование

  • © Хуторова Ольга Германовна

  • Лекция 10

2 of 45

Темы лекции

  • Cредства кроссплатформенного программирования
  • ООП в Qt
  • Механизм сигналов и слотов
  • Иерархия классов Qt
  • GUI в Qt
  • PyQt

3 of 45

Кроссплатформенное программирование

  • кроссплатформенные языки на уровне компиляции (то есть для этих языков есть компиляторы под различные платформы): C, C++ и Free Pascal
  • кроссплатформенные языки на уровне выполнения (то есть их исполняемые файлы можно запускать на различных платформах без предварительной перекомпиляции): Java и C#.
  • кроссплатформенные интерпретируемые языки (их интерпретаторы существуют для многих платформ): PHP, ActionScript, Perl, Python, Tcl и Ruby.

4 of 45

Qt

  • Без изменения исходного кода путём компиляции создаются программы для множества платформ (Microsoft Windows, Linux и др. UNIX-подобные с графической подсистемой X11, Android, iOS, Mac OS).
  • Полностью объектно-ориентированный, расширяемый, поддерживающий компонентное программирование.
  • Включает основные классы (создание графического интерфейса, работа с сетью, базами данных и XML)

5 of 45

История

  • появился в 1995 году благодаря своим разработчикам Хаарварду Норду и Айрику Чеймб-Ингу.
  • В 1999 года вышла вторая версия — Qt 2.0.
  • в 2000 году состоялся выпуск версии для встраиваемых систем, который назывался Qt Embedded.
  • Версия Qt 3.0 — 2001 год — работала в ОС семейства Windows™ и многих Unix-подобных ОС, таких как MacOS, xBSD, в различных вариантах Linux для персональных компьютеров и встраиваемых систем.
  • 2005 - выпуск Qt 4.0, 500 классов. Вместе с выпуском Qt 4.5 вышла специализированная интегрированная среда разработки QtCreator.
  • В 2012 состоялся официальный выпуск Qt5.

6 of 45

Qt Creator & C++

7 of 45

moc

  • Отличительная особенность Qt — использование метаобъектного компилятора — предварительной системы обработки исходного кода (реализация компонентного программирования).
    • moc, - программа, которая обрабатывает расширения C++ от Qt.
    • moc читает заголовочный файл C++. Если он находит одно или более объявлений классов, которые содержат макрос Q_OBJECT, то он порождает файл исходного кода C++, содержащий мета-объектный код для этих классов.

8 of 45

Сигналы и слоты

  • Программа состоит из объектов, которые взаимодействуют между собой.
  • Каждый из объектов обладает состоянием (совокупность данных в данный момент)
  • В ответ на взаимодействие с объектом его состояние может измениться. Объект сообщает об этом с помощью сигнала.
  • Другие объекты могут присоединиться к сигналу слотом — специальной функцией, которая вызывается каждый раз, когда был выпущен присоединённый к нему сигнал.

9 of 45

Сигналы и слоты

  • Сигнал вырабатывается когда происходит определенное событие. Слот это функция, которая вызывается в ответ на определенный сигнал.

  • Событие ➞Генерация сигнала➞Передача параметров в слот.

  • Все классы, наследуемые от QObject или его дочерних классов (например, QWidget) могут содержать сигналы и слоты.
  • Слоты могут быть использованы для получения сигналов, но они так же нормальные функции-члены. Так же как объект не знает ничего о получателях своих сигналов, слот ничего не знает о сигналах, которые к нему подключены. Это гарантирует создание независимых компонентов.
  • Мы можем подключать к одному слоту столько сигналов, сколько захотим, также один сигнал может быть подключен к стольким слотам, сколько необходимо. Так же возможно подключать сигнал к другому сигналу.
  • Сигналы и слоты вместе составляют механизм создания компонентов.

10 of 45

Философия объектной модели.

  • Классы, имеющие сигналы и слоты, должны быть унаследованы класса QObject.
  • Родственность Qt-объектов осуществляется через наследование класса QObject. А связи между ними через сигнально-слотовую систему.

11 of 45

Иерархия классов Qt

12 of 45

Основные модули Qt

  • Qt Core — основной модуль, который содержит все базовые средства Qt. На его основе построены все другие модули. Каждая программа созданная с использованием Qt, использует этот модуль;
  • Qt Network — модуль для работы с сетевыми средствами;
  • Qt Gui — модуль поддержки графического вывода на экран. В Qt4 он также содержит содержит набор виджетов для создания графического интерфейса пользователя. В Qt5 виджеты вынесены в отдельный модуль;
  • Qt Widgets — модуль, который содержит набор виджетов для создания графического интерфейса пользователя (Qt5);
  • Qt WebKit — средства работы с Веб;
  • Qt WebKit Widgets — виджеты для работы с Веб (Qt5);
  • Qt Multimedia — средства работы с мультимедийными устройствами и файлами;
  • Qt Multimedia Widgets — виджеты для работы с мультимедийными устройствами и файлами (Qt5);
  • Qt Sql — средства работы с базами данных;
  • Qt Qml — поддержка декларативной языка QML для разработки динамических визуальных интерфейсов (Qt5);
  • Qt Quick — поддержка создания динамических визуальных интерфейсов (Qt5);
  • Qt Quick Controls — использование технологии QtQuick для создания традиционного для рабочих столов графического интерфейса (Qt5);
  • Qt Quick Layouts — компоновка для элементов QtQuick (Qt5).
  • QtOpenGL – набор классов для работы с OpenGL;
  • QtScript – классы для работы с Qt Scripts (специальным скриптовым языком Qt, похожем наJavaScript);
  • QtXml – модуль для работы с XML;

13 of 45

Иерархия классов Qt

  • Любая Qt-программа так или иначе должна использовать хотя бы один из модулей QtCore, QtGui и QtWidgets, они присутствуют во всех программах с графическим интерфейсом и поэтому определены в программе создания make-файлов.

14 of 45

Структура проекта

  • Настройки в .pro-файле:
    • тип проекта (приложение, динамическая или статическая библиотека, проект, который состоит из подпроектов);
    • Используемые модули Qt;
    • настройки компиляции;
    • пути к файлам, библиотекам и другим частям проекта необходимым для компиляции;
    • файлы, входящие в проект;
  • В исходниках заголовочные файлы (.h) и файлы с кодом (.cpp), формы (.ui), ресурсы и др. компоненты.
    • Для каждого модуля Qt предоставляет отдельный заголовочный файл
      • #include <QtWidgets>
      • #include <QApplication>
    • Пространство имен Qt
      • using namespace Qt;

15 of 45

Структура проекта

16 of 45

Компиляция проекта

  • предварительная обработка проекта с помощью программы qmake.
    • генерирует необходимые промежуточные файлы (дополнительные файлы с исходным кодом и make-файлы для компиляции). Это необходимо для того, чтобы превратить все особые расширения Qt, которые были использованы в программе, в код на языке C++ и использовать дополнительные настройки для проекта, описанные в pro-файле.
  • непосредственно процесс компиляции.
  • сборка

17 of 45

Настройка компилятора pro-файл

18 of 45

Простейшее консольное приложение. Выбор типа проекта:Файл/Новый файл или проект

19 of 45

Простейшее консольное приложение. Файл профиля проекта

20 of 45

QApplication

  • Это основной класс приложения использующего графические элементы и организатор цикла сбора сообщений. Объект этого класса должен быть создан в единственном экземпляре перед основным кодом программы.

    • Инициализирует приложение в соответствии с пользовательскими настройками.
    • Выполняет обработку сообщений и передачу их соответствующим виджетам.
    • Анализирует аргументы командной строки и соответствующим образом устанавливает свой внутреннее состояние.
    • Определяет внешний вид приложения через установку стиля и изменение разрешенных цветов.
    • Предоставляет ссылки на глобальный буфер обмена(clipboard()) и другие полезные объекты.
    • Следит за открытыми окнами приложения и может выдать информацию о них.
    • Управляет видом иконки курсора.
    • другие полезные функции.

21 of 45

Пример консольного приложения c QCoreApplication

#include <QCoreApplication>

#include <iostream>

using namespace std;

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

{

/*создаётся объект класса QAplication, котрый осуществляет контроль и управление приложением*/

QCoreApplication a(argc, argv);

int x [4];

for (int i=0; i<4; i++) x[i]=i*10-5;

for (int i=0; i<4; i++) cout <<"x["<<i<<"]="<< x[i]<<endl;

return a.exec(); // приложение запускается (обработка событий)

}

22 of 45

Модуль QtCore

  • базовый для приложений и не содержит классов, относящихся к интерфейсу пользователя (консоль).
  • Содержит
    • контейнерные классы: QList, QVector, QMap, QVariant, QString и т. д.
    • классы для ввода и вывода: QIODevice, QTextStream, QFile
    • классы процесса QProcess и для программирования многопоточности: Qthread
    • классы для работы с таймером: QBasicTimer и QTimer
    • классы для работы с датой и временем: QDate и QTime
    • класс QObject, являющийся краеугольным камнем объектной модели Qt
    • базовый класс событий QEvent
    • класс для сохранения настроек приложения QSettings
    • класс приложения QCoreApplication, из объекта которого можно запустить цикл событий;
    • классы поддержки анимации: QAbstractAnimation, QVariantAnimation и т.

23 of 45

Простейшее графическое приложение. Создать

24 of 45

Простейшее графическое приложение

#include <QtWidgets>

int main(int argc, char** argv)

{

QApplication app(argc, argv);

QLabel lbl ("Hello, World !");

lbl.show ( ) ;

return app.exec ( );

}

25 of 45

Создание графического интерфейса

  • Виджеты (Widgets) — это визуальные элементы, из которых состоит графический интерфейс пользователя.
  • Примеры виджетов:
    • Кнопка (класс QPushButton);
    • Метка (класс QLabel);
    • Поле ввода (класс QLineEdit);
    • Числовое поле-счётчик (класс QSpinBox);
    • Строка прокрутки (класс QScrollBar).
  • Все виджеты в Qt наследники класса QWidget. 
  • Виджеты можно скомпоновать и создать с их помощью диалоговое графическое приложение

26 of 45

Виджеты

27 of 45

Формы Qt

28 of 45

Сигналы и слоты

29 of 45

Сигналы и слоты

30 of 45

файл main.cpp и окно отладки

31 of 45

PyQt

Установка:

pip install PyQt5

Преобразование форм Qt в Python:

pyuic5 name_of_input.ui -o name_of_output.py

Импорт формы в Python

from PyQt5 import QtWidgets, uic

from form1 import * #это наш файл из Qt

32 of 45

Пример импорта формы PyQt

33 of 45

Класс QString

  • Необходимо #include <QString>;
  • Элементы строки QString относятся к символьному типу QChar.
  • Для задания строки можно использовать оператор =.
  • Строки можно сравнивать с помощью ==, <=, >=, !=, >,<. Результат зависит от регистра символов.
  • Доступ к элементу осуществляется с помощью [] или .at(index). Счет начинается с нуля.
  • Для конкатенации строк можно использовать +, +=.

34 of 45

Класс QString

Функция

Описание

Пример

append

Добавление к строке справа строки.

s="one";s.append(" two"); // "one two"

clear

Очищает содержимое строки.

s.clear();

size

Количество символов в строке

s="itmath";int n=s.size(); //5

contains

true, если строка содержит данную строку. Чувствительность к регистру определяется вторым параметром.

s="Abc Def"; s.contains("dEf", Qt::CaseInsensitive); //true

length

 Количество символов в строке

 s="test"; s.length(); //4

truncate

 Удаление окончания строки с указанного символа

 s="abcdel"; s.truncate(3); //"abc"

indexOf

 Номер позиции первого вхождения строки в данную строку. Можно указать, с какой позиции искать. Возвращает -1, если строки не найдена.

s="test line best";s.indefOf("est"); // 1s.indexOf("est",5); //10

35 of 45

Класс QString

Функция

Описание

Пример

split

 Разбиение строки на фрагменты. Обратная операция: QStringList::join(QChar sep)

 s="a,,,,,b,c";QStringList w=s.split(",", QString::SkipEmptyParts); // ["a","b","c"]

insert

 Вставка строки в заданную позицию

 s="QtStyle"; s.insert(2,"C++"); //QtC++Style

isEmpty

 Проверка на пустую строку

prepend

 Добавление строки или символа в начало данной строки

 s="def";s.prepend("abc"); //abcdef

remove

 Удаление фрагмента с указанной позиции заданной длины, удаление всех вхождений данного символа или строки (с учетом настроек чувствительности к регистру)

 s="example"; s.remove(1,4); //"ele"s="abcA"; s.remove(QChar('a'), Qt::CaseInsensitive); //"bc"

replace

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

 s="It math";s.replace(3,4,"c++"); //"it c++"

36 of 45

Класс QString

Функция

Описание

Пример

setNum

 Перевод переданного числа в строковое представление.

 s.setNum(2015); //"2015"

toDouble

 Конвертация строки в действительное число типа double.

 s="12.34"; double d=str.toDouble(); //12.34

toInt

 Конвертация строки в целое число в данной системе счисления (по умолчанию 10).

 s="123"; bool flag; int n=s.toInt(&flag); if (flag) { //success };

toLower

 Перевод всех символов в нижний регистр

toUpper

 Перевод всех символов в верхний регистр

37 of 45

Класс QString. Пример: работа с числами

//преобразование целого числа в строку

int x = 1+6;

QString lXStr = QString::number ( x ); // x = 7; lXStr = 7

//преобразование строки в целое число

int y = lXStr.toInt ( );

//преобразование дробного числа в строку

double teta = 12099.10012021210102109991;

QString lTetaStr = QString::number ( teta ); // lTetaStr == 12099.1

lTetaStr.setNum ( teta ); // lTetaStr == 12099.1

//вывод с 4-мя знаками после запятой

lTetaStr = QString::number ( teta, " f ", 4 ); // lTetaStr == 12099.1001

//форматирование с использованием символа "e"

lTetaStr = QString::number ( teta, " e " ); // lTetaStr == 1.209910e+04

38 of 45

Пример работы с QString

#include <QCoreApplication>

#include <QString>

#include <QTime>

#include <QDebug>

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

{

QCoreApplication a(argc, argv);

QString str1 = "Hello World! ";

QString str2 = "Now is ", str3=" o'clock now";

QTime time=QTime::currentTime();

qDebug()<<str1+str2<< time.toString()+str3;

return a.exec();

}

39 of 45

Потоки QTextStream

#include <QTextStream>

#include <QString>

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

{

QTextStream out(stdout);

QTextStream in(stdin);

out << "Enter your name: " << flush;

QString value = in.readLine();

out << "Hello " << value << endl;

out << "Enter two numbers: " << flush;

int num1;

int num2;

in >> num1;

in >> num2;

out << "You entered " << num1 << " and " << num2 << endl;

}

40 of 45

Контейнерные классы Qt

QList

Список общего назначения

QLinkedList

Cвязный список в Qt. Отсутствует операция доступа по индексу элемента

QVector

Реализует вектор элементов в Qt.

QStack

Реализует стек.

QQueue

Реализует очередь.

QSet

Множество элементов.

QMap

Контейнерный класс для словаря. Элементы добавляют парами: ключ-значение

QMultiMap

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

QHash

Контейнерный класс для хеша. Элементы добавляют парами: ключ — значение. Позволяет выполнять очень быстрый поиск элемента по ключу.

QMultiHash

Контейнерный класс хеша, создан для удобной работы с тем, чтобы каждому ключу соответствовало несколько значений.

41 of 45

Двумерный массив в QVector

#include <QCoreApplication>

#include <QVector>

#include <QDebug>

//+++++++++++++++++++++++++++++++++++++++++++

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

{

QCoreApplication a(argc, argv);

QVector <QVector <int> > myVector;

int massive[4][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16} };

  for(int i = 0; i < 4; i++)

{

QVector<int> tempVector;

  for(int j = 0; j < 4; j++)

{

tempVector.push_back(massive[i][j]);

qDebug() << "Value " << j << ": " << tempVector.value(j);

}

myVector.push_back(tempVector);

qDebug() << "myVector " << i << ": " << myVector.value(i);

}

  return a.exec();

}

42 of 45

Работа с файлами

  • Все устройства ввода/вывода в Qt наследуют от абстрактного класса QIODevice. Среди его потомков: буфер для данных (QBuffer), процесс — программа которая выполняется в системе (QProcess) и классдля работы с файлом (QFile).
  • Для работы с файлом необходимо создать объект класса QFile и задать для него путь к файлу (абсолютный или относительный), с которым вы будете работать. Путь и имя передают как параметр конструктора или с помощью метода setFileName().
  • Далее файл необходимо открыть и задать режим доступа к нему. Метод open()принимает флаги доступа и возвращает true, если файл удалось открыть. Доступные флаги доступа:
    • QIODevice::ReadOnly — открыть для чтения;
    • QIODevice::WriteOnly — открыть для записи;
    • QIODevice::ReadWrite — открыть для чтения и записи;
    • QIODevice::Append — все данные будут добавляться в конец файла (после уже существующих данных);
    • QIODevice::Truncate — если возможно, стереть содержимое файла перед открытием;
    • QIODevice::Text — режим работы с текстовым файлом (важно для текстовых файлов для корректной обработки символов завершения строки в Windows и Linux).

43 of 45

#include <QDebug>

#include <QFile>

int main ( int arg c, char * argv [ ] )

{

const QString lFileName ( " file.txt " );

if ( ! QFile::exists ( lFileName ) ) //Проверяем существование файла

{qCritical ( " File % s does not exists." ,

qPrintable ( lFileName ) );

return 1;}

QFile lFile;

lFile.setFileName ( lFileName ); //Устанавливаем имя файла

//Открываем файл — текстовый, только для чтения

if ( ! lFile.open ( QIODevice::ReadOnly | QIODevice::Text ) )

{qCritical ( " Error % d : % s.", lFile.error ( ) ,qPrintable ( lFile.errorString ( ) ) ); //открыть файл не удалось

return 2; }

while ( ! lFile.atEnd ( ) ) //Пока можно прочесть строку

{qDebug ( ) << lFile.readLine ( );} // ... выводить её в консоль

lFile.close ( ); //Заканчиваем работу с файлом

return 0;

}

44 of 45

Задание

  • Пример — консоль, диалог, классы
  • Создать консольное приложение
  • Создать простейшее диалоговое приложение «Hello Qt!»
  • Освоить редактор форм, классы кнопок, меток и др.

45 of 45

Литература к лекции

  • Шлее М. Qt 5.3. Профессиональное программирование на C++
  • Бланшетт Ж., Саммерфилд М. Qt4: программирование GUI на C++
  • Документация