Сегодня мы рассмотрим: Настоящие ценители музыки знают, что для качественного...
Это кросс-платформенный инструментарий разработки ПО на языке программирования C++. Есть также «привязки» ко многим другим языкам программирования: Python - PyQt, Ruby - QtRuby, Java - Qt Jambi, PHP - PHP-Qt и другие.
Позволяет запускать написанное с его помощью ПО в большинстве современных операционных систем путём простой компиляции программы для каждой ОС без изменения исходного кода. Включает в себя все основные классы, которые могут потребоваться при разработке прикладного программного обеспечения, начиная от элементов графического интерфейса и заканчивая классами для работы с сетью, базами данных и XML. Qt является полностью объектно-ориентированным, легко расширяемым и поддерживающим технику компонентного программирования.
В этой статье я покажу как написать простую программу «Hello, World!» с использованием библиотеки Qt4
Среда разработки
Сначала определимся со средой разработки. Лично я для написания программа использую кросс платформенную IDE Code::Blocks (подробнее про работу в этой IDE с Qt4 можно почитать ). Так же есть плагины для работы с Qt в Eclipse. Коммерческая версия Qt под MS Windows может быть интегрирована в MSVS. Программы так же можно писать в любом текстовом редакторе, а потом компилировать их из командной строки.Для наглядности, я покажу как компилировать программы, написанные на Qt, вручную.
Первая программа
Сначала в любом текстовом редакторе создадим файл и назовем его, например, main.cppНапишем в нем следующее:
- #include
- #include
- QApplication app(argc, argv);
- QDialog *dialog = new QDialog;
- QLabel *label = new QLabel(dialog);
- label->setText("Hello, World!" );
- dialog->show();
- return app.exec();
В строках 1 и 2 мы подключили заголовочные файлы Qt в которых находятся основные классы.
В строке 4 мы объявили функцию main - главную функцию, с которой начинается выполнение любой программы. Она возвращает целое число (результат работы программы; 0 - если все в порядке) и принимает на вход две переменные - число параметров командной строки и массив, в котором они сохранены.
В строке 5 мы создаем объект приложения. Этому объекту мы передаем переменные командной строки.
В строке 6 мы создаем диалог - графическое окно прямоугольной формы, с заголовком и кнопками в верхнем правом углу. Создаем метку (строка 7). При создании метки мы передаем ее конструктору указатель на диалог, который становится ее родителем. При удалении родителя автоматически удаляются все его потомки, что очень удобно. Затем устанавливаем надпись метки путем вызова функции setText() (строка 8). Как видно из примера, для отображаемого текста можно использовать html-теги.
В строке 9 мы отображаем наше диалоговое окно с меткой на экране.
И, наконец в строке 10 мы запускаем цикл обработки событий операционной системы приложением. Результат работы объекта мы возвращаем как результат работы программы.
Компиляция
Теперь скомпилируем написанную программу.Перейдем в каталог, куда мы сохранили наш файл main.cpp и выполним команду
$ qmake -project
При этом произойдет создание заготовки проекта Qt4, в который автоматически будут включены все файлы исходных кодов, лежащих в данной директории. В результате получится файл с именем как у текущей директории и расширением.pro. Он будет выглядеть следующим образом:
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
# Input
SOURCES += main.cpp
В результате мы получим Makefile, который используем для того что бы скомпилировать программу, выполнив следующую команду:
Подождем пока процесс компиляции не закончится и запустим нашу первую программу. Она будет выглядеть примерно так:
Вторая программа
Что бы получить полный контроль над создаваемыми окнами и другими виджетами, необходимо создавать производные от них классы. Создадим производный класс MyDialog. В качестве родительского будем использовать класс QDialog. Описание нашего класса поместим в заголовочный файл mydialog.h:В первых четырех строках мы подключаем необходимые заголовочные файлы используемых графических элементов - диалога, кнопки, надписи и вертикального менеджера компоновки. Использовать такие крупные заголовочные файлы как* This source code was highlighted with Source Code Highlighter .
- #include
- #include
- #include
- #include
- class MyDialog: public QDialog {
- Q_OBJECT
- public :
- MyDialog(QWidget *parent = 0);
В шестой строке мы определили наш класс производным от QDialog.
На следующей строчке мы указали макрос Q_OBJECT, который указывает предпроцессору Qt что данный класс будет использовать дополнительные возможности Qt, например, систему сигналов и слотов.
На строке 9 мы указываем конструктор нашего диалогового окна. У него только один входной параметр - указатель на родительский объект (0 если родителя нет).
Конструктор нашего класса мы определим в файле mydialog.cpp:
* This source code was highlighted with Source Code Highlighter .
- #include "mydialog.h"
- MyDialog::MyDialog(QWidget *parent) : QDialog(parent) {
- QVBoxLayout *layout = new QVBoxLayout(this );
- QLabel *label = new QLabel(this );
- label->setText("Hello, World!" );
- QPushButton *button = new QPushButton(this );
- button->setText("Close" );
- layout->addWidget(label);
- layout->addWidget(button);
- connect(button, SIGNAL(clicked()), this , SLOT(close()));
В строке 4 мы создаем менеджер компоновки, который будет автоматически отображать все добавленные в него виджеты вертикально. Создание надписи аналогично предыдущему примеру.
В строках 7 и 8 создаем кнопку и устанавливаем ее текст. На следующих двух строчках мы добавляем наши виджеты в менеджер компоновки что бы он их автоматически упорядочил.
В строке 11 мы подключаем сигнал нажатия clicked() кнопки button к слоту close() нашего диалогового окна. У каждого объекта Qt могут быть свои сигналы и слоты, которые можно подключать к сигналам и слотам других объектов и таким образом осуществлять коммуникацию между элементами программы.
Файл main.cpp примет следующий вид:
* This source code was highlighted with Source Code Highlighter .
- #include
- #include "mydialog.h"
- int main(int argc, char * argv) {
- QApplication app(argc, argv);
- MyDialog *dialog = new MyDialog;
- dialog->show();
- return app.exec();
Пересоздаем проект командой
$ qmake -project
Что бы новые файлы автоматически в него добавились и компилируем его. Вот так выглядит наша новая программа:
Третья программа
Если диалоговое окно содержит много графических элементов, то создавать такие окна довольно утомительно. Для упрощения этого процесса есть инструмент под названием Qt Designer. Запускаем егоИ выбираем создание диалогового окна без кнопок. Добавляем на него метку и кнопку, редактируем их текст. С помощью инструмента редактора сигналов и слотов (Signal/Slot Editor) подключаем сигнал нажатия clicked() кнопки button к слоту close() диалогового окна. Располагаем их вертикально с помощью менеджера компоновки. Сохраняем полученный файл под именем mydialog.ui. Позже он будет автоматически преобразован в заголовочный файл с именем ui_mydialog.h.
Изменяем заголовочный файл нашего диалогового окна mydialog.h следующим образом:
Рис. A.1.
После перезагрузки ОС Windows для обращения к компилятору достаточно будет указывать его имя - g++ .
Таким образом, в ОС Linux для работы с компилятором в командной строке необходимо запустить Терминал, а в ОС Windows – командную строку. После чего работа с компилятором g++ с ОС Windows и Linux идентична.
Рассмотрим опции компилятора командной строки, необходимые для компиляции и запуска простейших программ.
Для того, чтобы создать исполняемый файл из текста программы на C++ , необходимо выполнить команду
Здесь name.cpp - имя файла с текстом программы. В результате будет создан исполняемый файл со стандартным именем a.out. Для того, чтобы создать исполняемый файл с другим именем, необходимо выполнить команду
g++ -o nameout name.cpp
Здесь name.cpp - имя файла с текстом программы, nameout - имя исполняемого файла.
При использовании компилятора g++ после компиляции программы автоматически происходит компоновка программы (запуск компоновщика make). Чтобы исключить автоматическую компоновку программы, следует использовать опцию -c. В этом случае команда будет иметь вид g++ -c name.cpp
Рис. A.2.
Рис. A.3.
Технология работы с компилятором g++ может быть такой: набираем текст программы в стандартном текстовом редакторе, потом в консоли запускаем компилятор, после исправления синтаксических ошибок запускаем исполняемый файл. После каждого изменения текста программы надо сохранить изменения в файле на диске, запустить компилятор, и только после этого запускать программу (исполняемый файл). Очень важно не забывать сохранять текст программы, иначе при запуске компилятора будет компилироваться старая версия текста программы.
Рис. A.4.
Рис. A.5.
Компилятор g++ эффективен при разработке больших комплексов программ, он позволяет собирать приложения из нескольких файлов, создавать библиотеки программ. Рассмотрим процесс создания и использования библиотеки решения задач линейной алгебры (см. п. 6.4, задачи 6.10 - 6.12):
int SLAU(double **matrica_a, int n, double *massiv_b, double *x) - функция решения системы линейных алгебраических уравнений;
int INVERSE(double **a, int n, double **y) - функция вычисления обратной матрицы;
double determinant(double **matrica_a, int n) - функция вычисления определителя.
Для создания библиотеки создадим заголовочный файл slau.h и файл slau.cpp , в который поместим тексты всех трёх функций решения задач линейной алгебры.
Текст файла slau1.h:
int SLAU(double ** matrica_a, int n, double *massiv_b, double *x); int INVERSE(double **a, int n, double **y); double determinant (double ** matrica_a, int n);
Текст файла slau1.cpp :
#include В качестве тестовой задачи напишем главную функцию, которая предназначена для решения системы линейных алгебраических уравнений. #include Теперь необходимо из этих текстов создать работающее приложение. Рассмотрим это поэтапно. После разработки библиотеки линейной алгебры (пример) slau1
, можно использовать её в различных программах при вычислении определителя, обратной матрицы и решения систем линейных алгебраических уравнений. При разработке программ с большим количеством вычислений, компилятор g++
позволяет оптимизировать программы по быстродействию. Для получения оптимизированных программ можно использовать ключи -O0, -O1, -O2, -O3, -Os
: Для разработки программ на различных языках программирования можно использовать текстовый редактор Geany
. Редактор Geany
входит в репозитории большинства дистрибутивов Linux, его установка осуществляется стандартным для вашего дистрибутива образом (в debian-подобных ОС с помощью команды apt-get install geany
). Для установки его в Windows необходимо скачать со страницы http://www.geany.org/Download/Releases инсталляционный файл и установить программу стандартным способом. Разработка программ с использованием Geany более эффективна. Окно Geany представлено на . Последовательно рассмотрим основные этапы разработки программы с использованием Geany
. Параметры компилятора определяются автоматически после выбора шаблона (Файл -> Создать из шаблона). Однако команды компиляции и сборки по умолчанию можно изменить, используя команду Сборка -> Установить параметры сборки (см. ). Здесь %f
- имя компилируемого файла, %e
- имя файла без расширения. Рис. A.6.
Рис. B.1.
Задача B.2.
Построить графики функций и в одной графической области. #include Рис. B.2.
Задача B.3.
Построить в одном графическом окне графики функций: Результаты вывести на экран и в файл. Рис. B.3.
#include Рис. B.4.
Задача B.4.
Построить график функций . Нетрудно заметить, что функция не существует в точке ноль. Поэтому построим её график на двух интервалах [-2;-0.1] и , исключив точку разрыва из диапазона построения. Текст программы с подробными комментариями приведён далее. Решение задачи представлено на . #include Рис. B.5.
Задача B.5.
Построить график функции на интервале [-5;5]. Функция имеет разрыв в точках -1 и 3. Построим её график на трёх интервалах [-5; -1.1], [-0.9;2.9] и , исключив точки разрыва из диапазона построения. Текст программы с подробными комментариями приведён далее. Решение задачи представлено на . #include Рис. B.6.
Задача B.6
. Построить график функции . График задан в параметрической форме и представляет собой эллипс. Выберем интервал построения графика , ранжируем переменную на этом интервале, сформируем массивы и и построим точечный график. Текст программы и результаты её работы () представлены далее. #include Рис. B.7.
Задача B.7.
Построить график функции: В данном случае необходимо построить график функции двух аргументов. Для этого нужно сформировать матрицу при изменении значений аргументов и и отобразить полученные результаты. #include Рис. B.9.
График к задаче B.8 В завершении приведём решение реальной инженерной задачи с использованием MathGL
. Задача B.9.
В "Основах химии" Д. И. Менделеева приводятся данные о растворимости азотнокислого натрия в зависимости от температуры воды. Число условных частей , растворяющихся в 100 частях воды при соответствующих температурах, представлено в таблице. Текст программы решения задачи с комментариями приведён ниже. #include После запуска программы на экране пользователь увидит следующие значения X
0 4 10 15 21 29 36 51 68
Y
66.7 71 76.3 80.6 85.7 92.9 99.4 113.6 125.1
k=3
a=67.5078 b=0.87064
Xr Yr
25 89.2738
32 95.3683
45 106.687 Графическое решение задачи, полученное с помощью средств библиотеки MathGL
, представлено на . Рис. B.11.
Для изучения всех возможностей MathGL
, авторы советуют обратиться к документации по MathGL
. При освоении библиотеки MathGL
следует помнить, что логика и синтаксис библиотеки напоминает синтаксис Scilab
и Octave
. В этом примере мы опишем шаги использования Qt Creator для написания маленькой программы Qt, Text Finder. Вдохновлённые примером QtUiTools Text Finder , мы напишем похожую на него но упрощённую версию как показано ниже. После того как вы установили Qt Creator, он автоматически определит, находится ли Qt в вашей переменной PATH . Если Qt не находится в вашем PATH , вы можете установить его одним из следующих способов, в зависимости от вашей платформы: Замечание:
Если для сборки Qt вы использовали Visual Studio, все переменные окружения, установленные в Visual Studio, должны быть также установлены для Qt Creator. Мы начнём с проекта Gui приложение Qt4, сгенерированного Qt Creator. Документ Создание проекта в Qt Creator детально описывает этот проект. Не забудьте выбрать QWidget в качестве базового класса Text Finder. Если ваш проект ещё не загружен, вы можете загрузить его выбрав Открыть...
из меню Файл
. В вашем проекте будут следующие файлы: Файлы.h и.cpp содержат необходимые строки кода; файл.pro также завершён. Мы начнём с проектирования интерфейса пользователя и затем перейдём к заполнению недостающего кода. В заключение мы добавим поиск. Для начала проектирования интерфейса пользователя, щёлкните два раза на файле textfinder.ui в вашем обозревателе проекта
. Это запустит интегрированный Qt Designer. Спроектируйте форму выше с использованием QLabel , QLineEdit (назовите его lineEdit), QPushButton (назовите её findButton) и QTextEdit (назовите его textEdit). Мы рекомендуем вам использовать QGridLayout для расположения QLabel , QLineEdit и QPushButton . QTextEdit можно добавить в QVBoxLayout помимо QGridLayout . Если вы новичок в проектировании форм с Qt Designer
, вы можете взглянуть на руководство по Qt Designer . Файл textfinder.h уже имеет необходимые заголовочные файлы, конструктор, деструктор и объект Ui . Нам необходимо добавить закрытый слот on_findButton_clicked() для выполнения операции поиска. Нам также необходима закрытая функция loadTextFile() для чтения и отображения содержимого входного файла в QTextEdit . Это делается следующим кодом: Private slots:
void on_findButton_clicked();
private:
Ui::TextFinder *ui;
void loadTextFile();
Замечание:
Объект Ui::TextFinder уже предоставлен. Теперь, когда наш заголовочный файл завершён, перейдём к файлу исходных кодов textfinder.cpp . Мы начнём с заполнения функциональности для загрузки текстового файла. Это описано в куске кода ниже: Void TextFinder::loadTextFile()
{
QFile inputFile(":/input.txt");
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString line = in.readAll();
inputFile.close();
ui->textEdit->setPlainText(line);
QTextCursor cursor = ui->textEdit->textCursor();
cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor, 1);
}
Мы загружаем текстовый файл используя QFile , читаем его с помощью QTextStream , а затем отображаем его в textEdit с помощью setPlainText() , что требует добавления дополнительных директив #includes в textfinder.cpp:
#include Для слота on_findButton_clicked() мы извлекаем строку поиска и используем функцию find() для поиска строки в текстовом файле. Это описано в куске кода ниже: Void TextFinder::on_findButton_clicked()
{
QString searchString = ui->lineEdit->text();
ui->textEdit->find(searchString, QTextDocument::FindWholeWords);
}
После того как эти функции завершены, мы вызываем loadTextFile() в нашем конструкторе. TextFinder::TextFinder(QWidget *parent)
: QWidget(parent), ui(new Ui::TextFinder)
{
ui->setupUi(this);
loadTextFile();
}
Слот on_findButton_clicked() будет вызван автоматически в этой строчке: QMetaObject::connectSlotsByName(TextFinder);
в файле ui_textfinder.h , сгенерированном uic. Нам потребуется файл ресурсов (.qrc) в котором мы сохраним текстовый файл. Это может быть любой файл.txt с абзацем текста. Чтобы добавить файл ресурсов щёлкните правой кнопкой мыши на Файлы ресурсов
в обозревателе проектов
и выберите Добавить новый файл...
. Вы увидите диалог мастера, показанный ниже. Введите "textfinder" в поле Имя
и используйте заданный Путь
. Затем щёлкните Вперёд
. На этой странице вы можете выбрать в какой проект вы хотите добавить новый файл. Убедитесь, что пункт Добавить в проект
выбран, а "TextFinder" выбран как Проект
, и щёлкните на Завершить
. Ваш файл ресурсов будет отображён в редакторе ресурсов. Щёлкните на выпадающем списке Добавить
и выберите Добавить приставку
. Приставка, которая нам требуется, это просто косая черта (/). Щёлкните на Добавить
снова, но на этот раз выберите Добавить файлы
. Найдите текстовый файл, который вы хотите использовать, мы будем использовать input.txt . Снимок экрана выше что вы можете ожидать после того как успешно добавили файл ресурсов. Теперь, когда у вас есть все необходимые файлы, вы можете скомпилировать вашу программу, нажав на кнопку . Программирование с Qt Существуют версии Qt для unix-подобных операционных систем с X Window
System (например, X.Org (EN), Mac OS X и ОС
Windows). Также Qt Software портирует свой продукт на мобильные платформы:
Embedded Linux (EN), S60 (EN) и Windows CE. Qt предоставляет
большие возможности кросс-платформенной разработки самых разных программ,
не обязательно с графическим интерфейсом. На нем, в частности, основана
популярная среда рабочего стола KDE (EN). Инструментарий разбит на модули
, каждый из которых размещается в
отдельной библиотеке. Базовые классы находятся в QtCore ,
компоненты графических интерфейсов – в QtGui , классы для
работы с сетью – в QtNetwork и т.д. Таким образом, можно
собирать программы даже для платформ, где нет X11 или другой совместимой
графической подсистемы. Нам потребуется установить среду разработки Qt. Программное обеспечение
распространяется на условиях свободной лицензии GPL 3.0 или LGPL 2.1. Его
можно получить по адресу http://www.qtsoftware.com/downloads (EN). В репозиториях популярных дистрибутивов GNU/Linux уже есть готовые пакеты
со средой разработки Qt (например, в Debian, Fedora, Gentoo, Mandriva,
Ubuntu). Тем не менее, пользователь может собрать и установить
инструментарий из исходных текстов. Для систем, использующих X11, необходимо загрузить файл
qt-x11-opensource-src-4.x.y.tar.gz , где 4.x.y –
последняя доступная версия из стабильных. Мы будем устанавливать версию
4.5.0. В директории с файлом qt-x11-opensource-src-4.5.0.tar.gz
выполните следующие команды: Прежде чем собирать Qt, запустите скрипт configure . Полный
набор его опций выдается по команде./configure -help , но
обычно можно использовать типовые настройки. Параметр -prefix задает каталог для установки (по умолчанию
используется /usr/local/Trolltech/Qt-4.5.0). Также имеются
ключи для инсталляции различных компонентов (исполняемых файлов,
библиотек, документации, и т.д.) в разные директории. При запуске скрипт требует подтвердить согласие пользователя с условиями
лицензии GPL / LGPL. После выполнения можно запустить сборку и установку при помощи команд: Имейте в виду, что компиляция занимает много времени, а для установки Qt
могут потребоваться права суперпользователя (файлы записываются в
/usr/local/). Если в дальнейшем вам понадобится в той же директории заново
сконфигурировать и пересобрать Qt, удалите все следы предыдущей
конфигурации при помощи make confclean , прежде чем снова
запускать./configure . Путь к исполняемым файлам Qt нужно добавить в переменную окружения PATH. В
оболочках bash, ksh, zsh и sh это можно сделать, дописав в файл
~/.profile следующие строки: В csh и tcsh нужно дописать в ~/.login строку: Если вы используете другую оболочку, то обратитесь к соответствующим
разделам документации. Кроме того, необходимо добавить строку
/usr/local/Trolltech/Qt-4.5.0/lib в переменную
LD_LIBRARY_PATH , если компилятор не поддерживает RPATH. Мы
используем GNU/Linux и GCC (EN), поэтому
пропускаем этот шаг. Затем с помощью утилиты qtdemo запустите демонстрационные
приложения для проверки работоспособности установленного инструментария. Недавно появилась кросс-платформенная среда разработки Qt Creator. На сайте
Qt Software можно найти полный SDK, включающий IDE (помимо библиотек и
основных средств разработчика). Загрузите бинарный файл
qt-sdk-linux-x86-opensource-xxx.bin и запустите мастер
установки: Если не собираетесь устанавливать SDK в домашнюю директорию, то запускайте
инсталлятор с правами суперпользователя. В состав Qt включены инструменты разработчика с графическим или консольным
интерфейсом. В их числе: Утилита qmake используется для автоматического генерирования
Makefile на различных платформах. В целом qmake ориентируется на Qt. Если вас интересуют
кросс-платформенные системы сборки более широкого назначения, то можете
обратиться к CMake, которая также поддерживает Qt. Новичкам стоит остановиться на qmake. Полную документацию по этой утилите вы можете найти в Qt Assistant. Также с
Qt поставляются страницы руководства, в том числе qmake(1)
(наберите в командной строке man qmake). Здесь мы приведем
основные указания, которые помогут вам собирать код примеров статьи, а
также свои простые проекты. В качестве примера создадим директорию myproject и добавим
туда файлы hello.h, hello.cpp и main.cpp . В
hello.h опишем прототип функции hello(): Реализацию hello() поместим в hello.cpp: Здесь qDebug() используется для вывода отладочной информации.
Ее можно убрать, объявив при компиляции символ
QT_NO_DEBUG_OUTPUT . Также имеется функция
qWarning() , выдающая предупреждения, и qFatal() ,
завершающая работу приложения после вывода сообщения о критической ошибке
в STDERR (то же самое, но без завершения работы, делает
qCritical()). В заголовочном файле Код основного приложения (здесь мы следуем соглашению, по которому
main() помещается в файл main.cpp): Чтобы создать файл проекта, запустите После этого должен появиться файл myproject.pro примерно
такого содержания: Оператор = используется для присвоения значений переменным, += добавляет
новую опцию к переменной, -= удаляет указанную опцию. TEMPLATE = app обозначает, что мы собираем приложение; для
библиотеки используется TEMPLATE = lib . TARGET – имя целевого файла (укажите
TARGET = foobar , чтобы получить исполняемый файл
foobar). DEPENDPATH – директории для поиска при разрешении
зависимостей. INCLUDEPATH – директории с заголовочными файлами. После запуска на основе myproject.pro в GNU/Linux будет создан обычный
Makefile: Опции qmake влияют на содержимое Makefile. Например,
qmake -Wall добавит к флагам компилятора -Wall –
вывод всех предупреждений. По команде make мы получим исполняемый файл
myproject , который выводит на экран строку «Hello,
World!». Эта схема может показаться слишком сложной, но в реальных проектах
qmake берет на себя большую часть работы по сборке (например,
запускает компилятор метаобъектов). Описанных выше инструментов достаточно для разработки приложений. Вы можете
использовать любимый текстовый редактор, например GNU Emacs или Vim. С Qt
работают также традиционные IDE, такие как KDevelop. Однако не так давно Qt Software выпустила свою кросс-платформенную IDE Qt
Creator. В неё встроены все инструменты разработчика, имеется редактор с
подсветкой и дополнением кода, отладчик (графический интерфейс для
gdb), а также реализована поддержка Perforce, SVN и Git. При работе в Qt Creator используется несколько режимов, которым
соответствуют вкладки на панели слева. Для быстрого переключения между
режимами можно использовать комбинации клавиш Ctrl+1, Ctrl+2 ,
и т.д. Основному режиму редактирования
соответствует
Ctrl+2 . Для навигации в редакторе применяется комбинация клавиш
Ctrl+K . После ее нажатия нужно указать один из префиксов: Таблица 1. Префиксы для навигации в Qt Creator
После префикса нажмите пробел и введите соответствующую информацию.
Например, для перехода на строку 93 текущего файла нужно напечатать
" l 93 " (то же самое можно сделать при помощи
Ctrl+L), для перехода к документации по теме
qobject_cast – "? qobject_cast" и т.д. В нижней части окна при этом отображается поле с автоматическим
дополнением. Таблица 2. Комбинации клавиш для редактора Qt Creator
Во встроенном редакторе реализовано «умное» дополнение кода, вызываемое
комбинацией клавиш Ctrl+<Пробел> . База символов
составляется на основе заголовочных файлов проекта из
INCLUDEPATH . Для чтения документации в IDE предусмотрен отдельный режим
справки
. Чтобы получить контекстную помощь по классу или методу,
просто передвиньте текстовый курсор к имени и нажмите F1 .
Также полезна клавиша F2 , перемещающая к определению в
заголовочных файлах. Чтобы переключиться из режима справки или отладки в основной режим
редактирования, нажмите Esc . В режиме редактирования
Esc переводит фокус из дополнительных окон (например, вывода
компиляции или контекстной справки) на редактор. Если нажать Esc еще раз,
то дополнительные окна закрываются. Как и qmake , Qt Creator использует файлы в формате.pro , поэтому в IDE легко импортируются старые проекты,
созданные вручную. Также доступен мастер, при помощи которого можно
создать заготовку нового проекта. Сейчас Qt Creator активно разрабатывается, но если вам нужна классическая
IDE для Qt, работающая на различных платформах, то это лучший вариант. В Qt используется CamelCasing
: имена классов выглядят как
MyClassName , а имена методов – как myMethodName . При этом имена всех классов Qt начинаются с Q , например
QObject, QList или QFont . Большинству классов соответствуют заголовочные файлы с тем же именем (без
расширения.h), т.е. нужно использовать: Поэтому в дальнейшем мы не будем отдельно оговаривать, где объявлен тот или
иной класс. Методы для получения и установки свойств
(getter
и
setter
) именуются следующим образом: свойство
fooBar можно получить при помощи метода fooBar()
и установить при помощи setFooBar() . При разработке собственных приложений на Qt стоит придерживаться этого
стиля. Для эффективной работы с классами на стадии выполнения в Qt используется
специальная объектная модель, расширяющая модель C++. В частности,
добавляются следующие возможности: Многие объекты определяются значением сразу нескольких свойств, внутренними
состояниями и связями с другими объектами. Они представляют собой
индивидуальные сущности, и для них не имеет смысла операция буквального
копирования, а также разделение данных в памяти. В Qt эти объекты
наследуют свойства QObject . В тех случаях, когда объект требовалось бы рассматривать не как сущность, а
как значение (например, при хранении в контейнере) – используются
указатели. Иногда указатель на объект, наследуемый от
QObject , называют просто объектом. Инструментарий спроектирован так, что для QObject и всех его
потомков конструктор копирования и оператор присваивания недоступны – они
объявлены в разделе private через макрос
Q_DISABLE_COPY() : Будьте внимательны и не используйте конструкцию Foo bar = Foo (baz); Другие объекты (например, контейнеры и строки) полностью определяются
представляемыми данными, поэтому в соответствующих классах имеются
операция присваивания и конструктор копирования. Кроме того, объекты,
представляющие одинаковые данные, могут прозрачно для программиста
разделять их в памяти. Часть расширений реализована стандартными методами C++, однако Qt
использует и более сложные синтаксические расширения, поэтому он
использует автоматическую генерацию кода. Для этого в C++ реализован механизм шаблонов, но он не предоставляет всех
необходимых Qt возможностей, плохо совместим с динамической объектной
моделью и в полной мере не поддерживается всеми версиями компиляторов. В сложных ситуациях Qt использует свой компилятор
метаобъектов
moc , преобразующий код с расширениями в
стандартный код C++. Для обозначения того, что класс использует
метаобъектные возможности (и, соответственно, должен обрабатываться
moc), в разделе private нужно указать макрос
Q_OBJECT . Если вы встречаете странные ошибки компиляции, сообщающие, что у класса не
определен конструктор, либо у него нет таблицы виртуальных функций
(vtbl), скорее всего вы забыли код, генерируемый moc. Обычно
это происходит, если не указан макрос Q_OBJECT . Во избежание ошибок Q_OBJECT лучше использовать во всех
классах, наследуемых от QObject (косвенно либо напрямую). Использование динамического подхода связано с определенными потерями в
производительности по сравнению со статическим, однако этими накладками
можно пренебречь, если принять во внимание полученные преимущества. В числе прочих, метаобъектный код добавляет метод virtual const QMetaObject* QObject::metaObject() const; который возвращает указатель на метаобъект объекта. На системе метаобъектов основаны сигналы, слоты и свойства. При наследовании от QObject помните об ограничениях,
налагаемых moc: Для динамического приведения QObject используется функция T qobject_cast (QObject *object); Она работает как стандартная операция dynamic_cast в C++, но
не требует поддержки со стороны системы динамической идентификации типов
(RTTI). Пусть у нас имеется класс MyClass1 , наследующий от
QObject и MyClass2 , наследующий от
MyClass1: Динамическое приведение иллюстрирует следующий код: Эти операции сработают корректно на стадии выполнения. Как и в случае с dynamic_cast , результат приведения можно
проверить: Система метаобъектов позволяет также проверить, наследует ли a класс
MyClass1: Однако предпочтителен предыдущий вариант с qobject_cast . Объекты классов, наследующих от QObject , могут быть
организованы в древовидную структуру. При удалении объекта Qt удаляет его
дочерние объекты
, которые в свою очередь удаляют свои
дочерние объекты, и т.д. Иными словами, удаление объекта приводит к
удалению всего поддерева, корнем которого он является. Пусть у нас имеются классы ClassA и ClassB: Здесь родительский объект устанавливается в конструкторе
QObject: QObject::QObject (QObject *parent = 0); Его можно установить в последующем при помощи метода
setParent() и получить при помощи parent() : void QObject::setParent (QObject *parent); Если создать в стеке по одному из объектов A и B, то сначала будет создан
A, потом B. В соответствии со стандартом C++, удаление происходит в
обратном порядке – сначала B, затем A: Если создать B в куче и назначить его дочерним объектом для A, то вместе с
A автоматически удалится B: Аналогично для более сложных деревьев: После удаления A удалится всё дерево. Таким образом, программист должен создавать объекты в куче и задавать
соответствующие иерархии, а заботу об управлении памятью Qt берет на себя. Если объект и его дочерние объекты созданы в стеке, то подобный порядок
удаления может привести к ошибкам. Здесь при выходе из области действия сначала будет удален объект A, так как
он был создан последним. При этом Qt удалит и его дочерний объект B. Но
потом будет сделана попытка удаления B, что приведет к ошибке. В другом случае проблем не будет, потому что при вызове деструктора
QObject объект удаляет себя из списка дочерних объектов
родительского объекта: Вообще говоря, дочерние объекты должны размещаться в куче. У каждого QObject есть свойство objectName , для
доступа к которому используются методы По умолчанию objectName – пустая строка. Через это свойство
объектам в дереве можно присвоить имена для последующего поиска. const QList – возвращает список дочерних объектов. T findChild (const QString& name = QString()) const; – возвращает дочерний объект с именем name
, который можно привести
к типу T, либо 0, если такой объект не найден. Без аргумента name
возвращает все дочерние объекты. Поиск осуществляется рекурсивно. QList – возвращает все дочерние объекты с именем name
, которые можно
привести к типу T
, либо пустой список, если таких объектов не
найдено. Без аргумента name
возвращает все дочерние объекты.
Поиск осуществляется рекурсивно. QList – аналогично, но с поиском по регулярному выражению regExp
. void dumpObjectTree(); – выводит отладочную информацию о дереве объектов с данным корнем. При создании графических пользовательских интерфейсов взаимодействие
объектов часто осуществляется через обратные вызовы, т.е. передачу кода
для последующего выполнения (в виде указателей на функции, функторов, и
т.д.). Также популярна концепция событий
и обработчиков
,
в которой обработчик действует как перехватчик события определенного
объекта. В Qt вводится концепция сигналов и слотов. Сигнал
отправляется при вызове соответствующего ему метода.
Программисту при этом нужно только указать прототип метода в разделе
signals . Слот
является методом, исполняемым при получении сигнала. Слоты
могут объявляться в разделе pulic slots, protected slots или
private slots . При этом уровень защиты влияет лишь на
возможность вызова слотов в качестве обычных методов, но не на возможность
подключения сигналов к слотам. Модель сигналов и слотов отличается от модели событий и обработчиков тем,
что слот может подключаться к любому числу сигналов, а сигнал может
подключаться к любому числу слотов. При отправке сигнала будут вызваны все
подключенные к нему слоты (порядок вызовов не определен). В качестве типичного примера слота рассмотрим метод получения свойства
(getter
). Методу установки свойства (setter
) при
этом будет соответствовать сигнал. Обратите внимание на макрос Q_OBJECT , сигнализирующий Qt о
том, что используются возможности системы метаобъектов. Ключевое слово emit отвечает за отправку сигнала. Для сигнала задается только прототип, причем сигнал не может возвращать
значение (т.е., указывается void). За реализацию отвечает
компилятор метаобъектов, он же преобразует расширенный синтаксис с
ключевыми словами signals, slots, emit в стандартный код C++. На самом деле, ключевые слова можно заменить на макросы
Q_SIGNALS, Q_SLOTS и Q_EMIT . Это полезно, если вы используете
сторонние библиотеки, в которых уже используются слова
signals, slots или emit . Обработка ключевых слов отключается флагом no_keywords . В файл
проекта qmake (.pro) добавьте CONFIG += no_keywords Вы можете посмотреть на результат работы компилятора метаобъектов в файле
moc_slots.cpp , который генерируется на основе
slots.h и компилируется вместе с остальными.cpp . Здесь при помощи QObject::connect сигнал объекта
a соединяется со слотом объекта b (передаются
указатели на QObject). Макросы SIGNAL и
SLOT формируют строковые сигнатуры методов. Их аргументы
должны содержать прототипы без указания имен переменных, т.е.
SIGNAL(valueChanged(int x)) – недопустимый вариант. Сигнатуры используются для сверки типов: сигнатура сигнала должна
соответствовать сигнатуре слота. При этом у слота сигнатура может быть
короче, если дополнительные аргументы игнорируются. Другой вариант вызова QObject::connect: b.connect (&a, SIGNAL(valueChanged(int)), SLOT(setValue(int))); Таким образом, здесь вызов MyClass::setValue для
a задействует MyClass::setValue для
b . Обратите внимание на строку if (x_ == x) return; . Она нужна,
чтобы избежать проблем при циклических соединениях. Например, следующий
код сработает: QObject::connect возвращает true , если соединение
успешно установлено, и false в противном случае – например,
когда сигнал или слот не обнаружен, либо их сигнатуры несовместимы. Если добавить при помощи QObject::connect одинаковые
соединения, то слот будет вызываться несколько раз. Для отключения сигнала от слота используется
QObject::disconnect: При успешном отключении возвращается true . Если вместо сигнала (SIGNAL(...)) указать 0, то данный
получатель сигнала (b) и слот отключаются от любого сигнала: QObject::disconnect (&a, 0, &b, SLOT(setValue(int))); Если 0 указать вместо получателя сигнала (b) и слота
(SLOT(...)) , то отключено будет всё, что подключено к данному
сигналу: QObject::disconnect (&a, SIGNAL(valueChanged(int)), 0, 0); Если 0 указать вместо слота (SLOT(...)) , то отключено будет
всё, что подключено к данному получателю сигнала (b): QObject::disconnect (&a, SIGNAL(valueChanged(int)), &b, 0); Получаем следующие варианты вызова QObject::disconnect: При удалении одного из объектов соединения Qt автоматически удаляет само
соединение. У компилятора метаобъектов имеется ряд ограничений, которые
распространяются и на работу с сигналами и слотами. Макросы нельзя использовать в любых участках кода,
которые должны обрабатываться moc . В частности, через
них нельзя указать базовый класс. Однако некоторые
возможности препроцессора использовать можно. Доступны простые
условные конструкции (с директивами
#if, #ifdef, #ifndef, #else, #elif, #endif , а также
специальным оператором defined). Для создания
объявлений у moc имеется опция командной строки
-D . Утилита qmake передает
moc все объявления, перечисленные в параметре проекта
DEFINES . Например, moc правильно
обработает также будет обработан, только если вызвать moc -DFOO ,
либо если до него имеется строка
#define FOO . Типы должны быть указаны полностью, так как
QObject::connect() сравнивает их буквально. В
частности, если внутри класса Foo определяется
перечисление Bar , то в аргументах сигнала нужно
указывать Foo::Bar: В качестве параметров сигналов и слотов нельзя использовать
указатели на функции. Например, не является допустимым аргументом. Можно использовать typedef: Обычно вместо указателей лучше применять наследование и виртуальные
функции. Класс, наследующий QObject , может содержать объявление
свойства при помощи макроса Q_PROPERTY() : Q_PROPERTY(type name
READ getFunction
Обязательные параметры макроса: Не обязательные параметры макроса: Методы могут быть виртуальными либо унаследованными от базового класса. При
множественном наследовании они должны принадлежать первому классу в
списке. Для не обязательных атрибутов
DESIGNABLE, SCRIPTABLE, STORED, USER допускается указание
булевых значений: Например, QWidget объявляет, в числе прочих, следующие
свойства: Q_PROPERTY
(QSize minimumSize READ minimumSize WRITE setMinimumSize)
Q_PROPERTY(int minimumWidth READ minimumWidth WRITE
setMinimumWidth STORED false DESIGNABLE false)
Q_PROPERTY(int minimumHeight READ minimumHeight WRITE
setMinimumHeight STORED false DESIGNABLE false) Свойство minimumSize имеет тип QSize и может быть
получено при помощи QSize minimumSize() const и установлено
при помощи void setMinimumSize
(const QSize&). minimumWidth и
minimumHeight вычисляются через minimumSize ,
поэтому для них указано STORED false . Пример свойства с атрибутом USER – text в QLineEdit: Для считывания и записи свойства используются методы: property() возвращает значение свойства либо неправильный
вариант
QVariant , если такого свойства нет. setProperty() возвращает true , если у объекта
есть указанное свойство с типом, совместимым с переданным значением. В
противном случае возвращается false . Если в классе нет указанного свойства, то добавляется динамическое
свойство
объекта. Перечень динамических свойств можно получить
при помощи Рассмотрим пример использования свойств. Пусть класс MyClass
имеет строковое свойство text (типа QString): Работа со свойством: Программа должна вывести на экран следующее: Разумеется, безопаснее и быстрее вызывать методы конкретного класса для
считывания и записи свойств. property() и
setProperty() нужны в том случае, когда о классе ничего не
известно кроме имен и типов свойств. Если для класса не известен даже перечень свойств и методов, можно
использовать метаобъект. Метаобъект возвращается методом QObject::metaObject() С его помощью можно динамически получить информацию о классе, как,
например, в Java Reflecion API (EN). Имя класса возвращает const char * QMetaObject::className() const; Указатель на метаобъект базового класса – const QMetaObject* superClass() const; Через систему метаобъектов доступны только те методы и конструкторы, перед
объявлениями которых указан макрос Q_INVOKABLE: Для доступа к методам (в том числе сигналам и слотам) используйте Методы и свойства класса проиндексированы. Доступ к методу по индексу
осуществляется через QMetaObject::method() . Общее число методов, с учетом наследованных, возвращает
QMetaObject::methodCount() . Смещение
методов класса
возвращается QMetaObject::methodOffset() , оно показывает, с
какого индекса начинаются методы данного класса. Смещение увеличивается
при наследовании и показывает число методов базовых классов. Пример прохода по методам: Если бы мы начали с индекса 0, то получили бы методы всех базовых классов,
в том числе QObject: Методы, начинающиеся с _q_ , используются внутри Qt и не
являются частью API. Конструкторы указываются отдельно: Например, получим перечень конструкторов QObject: Результат: Индекс метода, сигнала, слота или конструктора можно получить по его
сигнатуре: Для конструкторов, методов или сигналов ожидаются нормализованные
сигнатуры
. Их можно получить при помощи статического метода Например, возвращает " int*foo(QString,QObject*) ". Аналогично работает Это текстовое приведение к каноническому виду, используемое, в частности,
при проверке совместимости сигнала и слота. Аналогично можно работать со свойствами. (Если просмотреть все свойства, включая наследованные, то вы увидите, по
меньшей мере, objectName из QObject .) Индекс свойства можно получить по его имени: Перечисления регистрируются в классе при помощи макроса
Q_ENUMS() . Перечисление, значения которого можно комбинировать при помощи побитового
ИЛИ, называется флагом
и должно регистрироваться при помощи
Q_FLAGS() . Флаги используются следующим образом: Динамическая работа с перечислениями: Результат работы: Индекс перечисления можно получить по его имени: При помощи макроса Q_CLASSINFO() к метаобъекту можно добавлять
пары имя–значение. Например, Эти пары наследуются, и их можно получить из метаобъекта по той же схеме: Для примера выше: Результат: Индекс CLASSINFO можно получить по его имени: Передача аргументов осуществляется через объекты
QGenericArgument и QGenericReturnArgument . Они
создаются макросами Q_ARG и Q_RETURN_ARG . Пример использования: Для создания нового экземпляра класса используется метод метаобъекта
newInstance() , которому можно передать до 10 аргументов. В случае ошибки возвращается 0. Для вызова метода используется invokeMethod() : При асинхронном вызове значение не может быть вычислено. Имеются перегруженные версии invokeMethod() . Если вы не
укажете тип вызова, то будет использоваться
Qt::AutoConnection . Если вы не укажете возвращаемое значение,
то оно будет проигнорировано. Те же возможности предоставляет класс QMetaMethod: Точно так же, тип соединения и/или возвращаемое значение можно не
указывать. Асинхронный вызов используется в том случае, когда вычисления занимают
слишком много времени, поэтому их результат не ожидается в точке вызова.
Подобные вычисления обычно помещают в отдельный поток, поэтому по
умолчанию (Qt::AutoConnection) методы объектов из внешних
потоков вызываются асинхронно. Рассмотрим следующий класс: Обращение к конструктору и методам: text() и setText() вызываются таким образом лишь
в качестве простого примера работы с
QMetaObject::invokeMethod() . Как вы уже знаете, эти два
метода должны быть связаны со свойством. Также обратите внимание, что text() возвращает
QString , но не const QString& . Иначе бы
система метаобъектов считала, что text() возвращает
void . Для эффективной работы с классами на стадии выполнения Qt использует
специальную объектную модель, в которой при помощи наследования от
QObject и генерирования кода компилятором метаобъектов
реализованы: В следующей статье мы рассмотрим типы, варианты, ссылки и разделение
данных. С каждым годом становится все больше операционных систем, и потому разработчикам все труднее удовлетворять потребности пользователей. Три самые популярные компьютерные платформы - Windows, Linux и Mac OS, а также три мобильные - Android, iOS и Windows Mobile - продолжают активно бороться между собой. А это значит, что качественное приложение должно работать на всех основных платформах. Справиться с этой проблемой помогает кроссплатформенная разработка. Об одной из самых популярных кроссплатформенных сред разработки - Qt Creator - и пойдёт речь в этой статье. Мы рассмотрим как выполняется установка и настройка Qt Creator, а также как работать в Qt Creator. Qt Creator (не так давно имевший название Greenhouse) - это одна из самых распространенных кроссплатформенных IDE. Ее плюсы - удобство, быстрота работы, а также - свободность, так как это ПО с открытым исходным кодом. Поддерживаются такие языки, как C, С++, QML. Программа была написана компанией под названием Trolltech, которая в полной мере выполнила цель создания среды - работу с графическим фреймворком Qt. Удобный графический интерфейс с поддержкой Qt Widgets и QML, а также большое число поддерживаемых компиляторов позволяют быстро и удобно создать свое кроссплатформенное приложение. Главная задача этой IDE - обеспечить наиболее быструю кроссплатформенную разработку, используя собственный фреймворк. Благодаря этому разработчики получают прекрасную возможность не писать приложения нативно (т. е. отдельно под каждую платформу), а создать общий код, и, возможно, подогнать его под особенности используемых ОС. Qt Creator также включает в себя утилиту Qt Designer, что позволяет обработать внешний вид окна приложения, добавляя и перетаскивая элементы (аналогично Windows Forms в Visual Studio). В качестве систем сборки используются qmake, cmake и autotools. Итак, пора рассмотреть как установить Qt Creator. Если для Windows разработчики позаботились и сделали оффлайн-установщик, то в Linux 32-bit этой возможности не предусмотрено. Поэтому во время установки вам может потребоваться стабильное интернет-соединение (~20-30 минут). Для начала скачаем установщик: После окончания загрузки переходим в папку с файлом, нажимаем правой кнопкой мыши и выбираем пункт "Свойства"
. Теперь перейдем на вкладку "Права"
и поставим галочку "Разрешить запуск этого файла в качестве программы"
. Запускаем программу. Теперь нажимаем "Next"
. Здесь необходимо выбрать существующий аккаунт или создать его. Данное действие необходимо для проверки лицензии (коммерческой или некоммерческой). Нажимаем "Next"
. Выбираем директорию, в которой будет находиться Qt. Важно, чтобы в пути не было кириллицы и пробелов! В этом меню находится выбор компонентов. К примеру, можно выбрать установку инструментов для разработки на Android, или же исходных компонентов (это нужно для статической сборки, если кому-то это нужно - напишите в комментариях, и я напишу отдельную статью). Если Вы не уверены, нужны Вам эти компоненты или нет, оставьте их пока так - даже после установки Qt будет возможным удаление и добавление элементов. В этом окне принимаем лицензию. Жмем "Next"
. Если Вы готовы, начинайте установку. У Вас запросят пароль суперпользователя (sudo), после чего начнется скачивание и извлечение файлов. Альтернативный способ - установка через терминал. Для начала необходимо обновить список пакетов. Скачиваем и устанавливаем Qt: sudo apt install qt5-default Теперь установка Qt Creator: sudo apt install qtcreator И, если нужно, исходники. sudo apt install qtbase5-examples qtdeclarative5-examples После окончания установки перезагрузите компьютер и запустите Qt Creator. Перейдите в меню "Инструменты" -> "Параметры"
. Здесь следует рассмотреть несколько вкладок. 1. Среда
- это настройка внешнего вида самой IDE, а также изменение сочетаний клавиш и управление внешними утилитами. 2. Текстовый редактор
- здесь идет настройка внешнего вида, шрифтов и расцветки редактора. 3. C++
- подсветка синтаксиса, работа с расширениями файлов и UI (т. е. формами). 4. Android
- здесь собраны пути к необходимым инструментам, а также в этом меню настраиваются подключаемые или виртуальные устройства. Если вдруг так случилось, что Вы забыли установить какой-то компонент, или, наоборот, хотите его удалить, то на помощь придет Qt Maintenance Tool. Это инструмент, позволяющий управлять всеми компонентами Qt Creator. Чтобы запустить его, перейдите в меню приложений, выберите пункт "Разработка" -> "Qt Maintenance Tool"
. Выберите необходимый пункт (Удалить/добавить компоненты, обновить компоненты или удалить Qt). После выполните необходимые операции и закройте окно. Ну что же, час пробил! Установка Qt Creator завершена. Пора сделать свое первое кроссплатформенное приложение на Linux, а затем скомпилировать его на Windows. Пусть это будет... программа, выводящая иконку Qt, кнопку и надпись, на которую по нажатию кнопки будет выводиться случайная фраза. Проект несложный, и, конечно же, кроссплатформенный! Для начала откроем среду разработки. Нажмем "Файл" -> "Создать файл или проект..."
. Выберем приложение Qt Widgets - его быстро и удобно сделать. А название ему - "Cross-Platphorm"
. Вот как! Комплект - по умолчанию. Главное окно тоже оставляем без изменений. Создаем проект. Для начала необходимо настроить форму - главное окно приложения. По умолчанию оно пустое, но это не останется надолго. Перейдем в папку "Формы" -> "mainwindow.ui"
. Откроется окно Qt Designer: Удаляем панель меню и панель инструментов на форму, нажав правой кнопкой мыши и выбрав соответствующий пункт. Теперь перетаскиваем элементы Graphics View, Push Button и Label таким образом: Чтобы изменить текст, дважды кликните по элементу. В свойствах Label (справа) выбираем расположение текста по вертикали и по горизонтали - вертикальное. Теперь пора разобраться с выводом иконки. Перейдем в редактор, слева кликнем по любой папке правой кнопкой мыши и выберем "Добавить новый..."
. Теперь нажимаем "Qt" -> "Qt Resource File"
. Имя - res. В открывшемся окне нажимаем "Добавить" -> "Добавить префикс"
, а после добавления - "Добавить файлы"
. Выбираем файл, а в появившемся окне "Неверное размещение файла"
кликаем "Копировать"
. Получилось! Сохраняем все. Снова открываем форму. Кликаем правой кнопкой мыши по Graphics View, выбираем "styleSheet..." -> "Добавить ресурс" -> "background-image"
. В левой части появившегося окна выбираем prefix1, а в правой - нашу картинку. Нажимаем "ОК"
. Настраиваем длину и ширину. Все! Теперь можно приступать к коду. Клик правой кнопкой мыши по кнопке открывает контекстное меню, теперь надо нажать "Перейти к слоту..." -> "clicked()"
. В окне набираем следующий код: Или вы можете скачать полный проект на GitHub . Работа с Qt Creator завершена, нажимаем на значок зеленой стрелки слева, и ждем запуска программы (если стрелка серая, сначала нажмите на значок молотка). Запустилось! Ура!0
4
10
15
21
29
36
51
68
66.7
71.0
76.3
В первой строке файла хранится количество экспериментальных точек, в следующих двух строках - массивы абсцисс и ординат экспериментальных точек. В четвёртой строке хранится количество (3) и точки (25, 32, 45), в которых необходимо вычислить ожидаемое значение.Настройка вашей среды
Настройка проекта
Заполнение недостающих кусков
Проектирование пользовательского интерфейса
Заголовочный файл
Файл исходных кодов
Файл ресурсов
Сборка и запуск вашего приложения
Часть 1. Введение. Инструменты разработчика и объектная модель
Серия контента:
1. Введение
2. Установка Qt
2.1. Базовые библиотеки и инструменты
2.2. SDK
3. Инструменты разработчика
3.1. qmake
Листинг 1.1. Объявления функций программы
«Hello, World!»
// hello.h
void hello();
Листинг 1.2. Реализации функций программы «Hello,
World!»
// hello.cpp
#include Листинг 1.3. Функция main() программы «Hello, World!»
// main.cpp
#include "hello.h"
int main()
{
hello();
return 0;
}
####################################
# Automatically generated by qmake
####################################
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
# Input
HEADERS += hello.h
SOURCES += hello.cpp main.cpp
####### Compile
hello.o: hello.cpp hello.h
$(CXX) -c $(CXXFLAGS) $
(INCPATH) -o hello.o hello.cpp
main.o: main.cpp hello.h
$(CXX) -c $(CXXFLAGS) $
(INCPATH) -o main.o main.cpp
####### Install
install: FORCE
uninstall: FORCE
FORCE:
3.2. Qt Creator
Рисунок 5. Поле для навигации в Qt
Creator
Ctrl+[
Перейти к началу
блока
Ctrl+]
Перейти к концу
блока
Ctrl+U
Выделить блок
Ctrl+Shift+U
Снять
выделение блока
Ctrl+I
Выровнять блок
Ctrl+<
Свернуть блок
Ctrl+>
Развернуть блок
Ctrl+/
Закомментировать
блок
Ctrl+Shift+
Переместить
строку вверх
Ctrl+Shift+↓
Переместить
строку вниз
hift+Del
SУдалить строку
4. Стиль Qt
5. Объектная модель
5.1. Система метаобъектов
5.2. qobject_cast
5.3. Деревья объектов
Листинг 2.1. Объявление MyClass для программы,
демонстрирующей порядок создания и удаления объектов
// myclass.h
#include Листинг 2.2. Определение методов MyClass для
программы, демонстрирующей порядок создания и удаления объектов
// myclass.cpp
#include
QObject* QObject::parent() const;Листинг 2.3. Создание экземпляров MyClass в стеке
// main.cpp
#include "myclass.h"
int main()
{
MyClass a ("A");
MyClass b ("B");
return 0;
}
Листинг 2.4. Создание экземпляра A класса MyClass в
стеке, а экземпляра B – в куче, как дочернего для A
// main.cpp
#include "myclass.h"
int main()
{
MyClass a ("A");
MyClass *b = new MyClass ("B", &a);
return 0;
}
Рисунок 8. Пример многоуровневого дерева
объектов
Листинг 2.5. Многоуровневое дерево объектов с корнем в
стеке
// main.cpp
#include "myclass.h"
int main()
{
MyClass a ("A");
MyClass *b = new MyClass ("B", &a);
MyClass *c = new MyClass ("C", &a);
MyClass *d = new MyClass ("D", c);
MyClass *e = new MyClass ("E", c);
return 0;
}
5.4. Сигналы и слоты
5.4.1. Объявление сигналов и слотов,
отправка сигналов
Листинг 3.1. Класс MyClass со слотом void setValue
(int x) и сигналом void valueChanged (int x)
// myclass.h
#include Листинг 3.2. Реализация методов класса MyClass со
слотом void setValue (int x) и сигналом void valueChanged (int x)
// myclass.cpp
#include 5.4.2. Подключение сигнала к слоту
Листинг 3.3. Подключение сигнала void
MyClass::valueChanged (int x) к слоту void MyClass::setValue (int x)
// main.cpp
#include Листинг 3.4. Циклическое соединение сигналов void
MyClass::valueChanged (int x) со слотами void MyClass::setValue (int
x)
// main.cpp
#include 5.4.3. Отключение
5.4.4. Ограничения
Блок #ifdef FOO
// ...
#endif
5.5. Свойства
Листинг 4.1. Объявление класса MyClass со свойством
text
// myclass.h
#include Листинг 4.2. Определение методов класса MyClass со
свойством text
// myclass.cpp
#include Листинг 4.3. Работа со свойством text объекта MyClass
// main.cpp
#include 5.6. Работа с метаобъектами
5.6.1. Основная информация
5.6.2. Методы
Листинг 5. Вывод конструкторов QObject через систему
метаобъектов
#include 5.6.3. Свойства
5.6.4. Перечисления
Листинг 6.1. Класс MyClass с перечислением Type и
флагом Mode
class MyClass
{
Q_OBJECT
Q_ENUMS(Type)
Q_FLAGS(Mode)
public:
enum Type { A, B, C };
enum Mode
{
Read = 0x1,
Write = 0x2,
Execute = 0x4
};
// ...
};
Листинг 6.2. Вывод перечислений и флагов MyClass через
систему метаобъектов
MyClass obj;
const QMetaObject* m_obj = obj.metaObject();
for (int i = m_obj->enumeratorOffset()
; i < m_obj->enumeratorCount(); i++)
{
QMetaEnum me = m_obj->enumerator(i);
if (me.isValid()) // Есть имя
{
if (me.isFlag()) // Флаг
{
qDebug() << "" <<
me.scope() << "::" << me.name();
}
else
{
qDebug() << me.scope()
<< "::" << me.name();
}
}
}
5.6.5. CLASSINFO
Листинг 7.1. Класс MyClass с CLASSINFO
class MyClass
{
Q_OBJECT
Q_CLASSINFO("author", "Bob Dobbs")
Q_CLASSINFO("version", "0.23")
// ...
};
Листинг 7.2. Вывод CLASSINFO класса MyClass
MyClass obj;
const QMetaObject* m_obj = obj.metaObject();
for (int i = m_obj->classInfoOffset();
i < m_obj->classInfoCount(); i++)
{
QMetaClassInfo mci = m_obj->classInfo(i);
qDebug() << mci.name()
<< ":" << mci.value();
}
5.6.6. Вызов конструкторов и методов
Листинг 8.1. Класс MyClass с конструктором и методами,
доступными системе метаобъектов
class MyClass: public QObject
{
Q_OBJECT
public:
Q_INVOKABLE MyClass (QString text, QObject *parent = 0);
Q_INVOKABLE QString text() const;
Q_INVOKABLE void setText (const QString& text);
private:
QString text_;
};
Листинг 8.2. Вызов конструкторов и методов класса
MyClass через систему метаобъектов
MyClass foo ("foo");
const QMetaObject* m_foo = foo.metaObject();
// Создать новый экземпляр:
MyClass *bar = qobject_castЗаключение
Что такое Qt Creator
Установка Qt Creator
Настройка Qt Creator
Установка компонентов Qt Creator
Работа с Qt Creator - первый проект