Интегрированная среда разработки
Qt-приложений, QDevelop, ориентирована на создание и редактирование
проектов с включением ui-форм, т.е. xml-заготовок будущих окон
приложения с возможностью их редактирования в Qt Designer по технологии
WYSIWYG (что видишь, то и получишь). Подобная технология весьма
популярна, поскольку позволяет быстро разрабатывать программу,
занимаясь лишь логикой её работы и не отвлекаясь на тонкости
программирования пользовательского интерфейса.
Однако нередко возникает ситуация,
когда удобнее программировать главное окно приложения по-старинке,
средствами C++ классов Qt, например, при динамическом изменении
внешнего вида формы. Хотя QDevelop лишён средств по созданию подобных
проектов, однако данная среда обладает инструментами, которые позволят
сделать разработку данного типа проекта более удобным и приятным.
В качестве примера работы с написанным
вручную проектом мы рассмотрим создание электронной версии классической
головоломки "Пятнашки" (Fifteen-puzzle game), которая традиционно
является учебным примером для начинающих программистов.
Сама мысль написать "Пятнашки" для
Linux возникла у меня давным-давно, ещё во времена версии 4.1
библиотеки Qt в связи с вопросом 130703
и вопросом
83102 рассылки по C/C++ RusFAQ. Предварительно программа была
написана с использованием Qt 3.3.8, а затем портирована на Qt 4.2 с
некоторым расширением функциональности (был добавлен режим работы
"Собери картинку"). При работе над программой я обратил
внимание, что мною были так или иначе затронуты если не все, то
основные возможности, заложенные в Qt, поэтому созданная
программа Klikit
является хорошим учебным примером, по освоению работы с этой
библиотекой. Собственно, именно поэтому и была написана эта статья.
В настоящее время созданы определённые
нормы поэтапной разработки приложений для Linux, которых мы и будем
придерживаться.
Формулировка цели и задач проекта
Целью проекта является разработка и
внедрение компьютерной реализации настольной игры "Пятнашки".
Задачами проекта являются:
Создание кроссплатформенного приложения (как минимум для
Linux и Windows);
Возможность переключения между двумя режимами: классическим
(фишки с номерами) и "собери картинку";
Предусмотреть в программе настраиваемый интерфейс с
возможностью сохранения и загрузки настроек;
Расширяемая локализация приложения с возможностью
добавления новых языков интерфейса без необходимости повторной
компиляции исполняемого модуля.
Поиск научно-патентной информации для установления степени
разработки вопроса сторонними авторами
Приняв решение написать игру,
заинтересовался: а много ли написано на C++ кроссплатформенных
"Пятнашек"? Ориентируясь на количество исходников для MS DOS и MS
Windows, ожидал обвала, но с удивлением обнаружил, что даже для
исключительно Linux "Пятнашек" раз-два и обчёлся: имеется пара древних
проектов с
псевдографическим интерфейсом, плюс Jesper Thomschütz aka Jespersaur
добавил в плазмоиды KDE 4 свою версию головоломки.
Критика аналогов
Из кроссплатформенных компьютерных
реализаций головоломки я обнаружил лишь один проект на Python с
интерфейсом на Tcl/Tk, что выглядит несовременно....
Критика прототипа
В качестве прототипа "Пятнашек" я
выбрал плазмоид KDE 4 Jesper Thomschütz aka Jespersaur. Хотя, строго
говоря, проект не является кроссплатформенным, но его легко сделать
таковым, поскольку в качестве библиотеки разработки пользовательского
интерфейса была выбрана библиотека Qt 4.x. Однако изучение работы
программы показало её низкую функциональность: слабо настраиваемый
интерфейс и недостаточно проработанные механизмы взаимодействия с
пользователем, в частности, отсутствие проверки на выигрыш (при решении
головоломки программа никак на это не реагирует). На рисунке ниже
представлен вышеупомянутый плазмоид (слева) и моё видение программы
(справа):
Выбор языка и средств разработки проекта
В соответствии с задачами проекта
программу напишем на языке C++. Для проектирования пользовательского
интерфейса будем использовать версию библиотеки Qt 4.2 для
достижения целей совместимости со старыми версиями дистрибутивов Linux
(тем не менее, код полностью совместим со старшими версиями библиотеки).
В качестве IDE используем QDevelop, как среду разработки,
ориентированную на работу с Qt.
Проектирование основного интерфейса программы
Создание проекта
Создайте в каталоге Ваших проектов
папку Klikit. В этой папке создайте текстовый файл main.cpp. Откройте
файл в любом текстовом редакторе и наберите следующий текст:
QApplication MyProgramme(iArgc, psArgv); // Создаём
экземпляр класса
приложения
TMainForm MainWindow; // Создаём экземпляр класса
главного окна
MainWindow.show(); // Показываем главное окно
return MyProgramme.exec(); // Запускаем главный
цикл прложения
}
Несмотря на то, что подключаемый
заголовочный файл TMainForm.h ещё не существует, мы уже можем создать
проект. Для этого воспользуемся утилитой qmake, входящей в состав
библиотеки Qt. Перейдём в консоли в папку программы (Klikit) и наберём:
qmake -project
N.B.! Если Вы пользователь так называемого dual-qt дистрибутива
Linux (т.е. такого, в котором имеются как 3-я, так и 4-я версии
библиотеки), то набирайте команду qmake с указанием полного пути к
ней:
Тем самым в папке программы будет
создан проект Qt, файл с расширением имени *.pro - Klikit.pro. Иногда
его называют
платформо-независимым файлом проекта. В принципе на его основе можно
создать платформо-зависимый файл проекта (Makefile) - набор инструкций
конкретному компилятору по сборке исполняемого файла. Для этого
достаточно набрать в консоли qmake Klikit.pro. Но вручную это мы
делать не будем, поскольку в QDevelop этот процесс автоматизирован.
Добавление в проект нового класса
Откройте созданный файл проекта в
QDevelop, выбрав в меню Проект -
Открыть проект... Теперь нам предстоит создать класс главной формы
приложения. Дабы упростить процесс создания и включения в проект
необходимых файлов, а также для, того, чтобы сгенерировать часть кода,
выберите в меню QDevelop Проект - Добавить новый класс...
В появившемся диалоговом окне "Добавить
новый класс" в поле "Имя класса" внесите TMainForm; в поле "Параметры
конструктора" - QWidget* pParent, Qt::WindowFlags Flag; в поля
"Родительский класс" и "Имя файла родительского класса" внесите
QMainWindow; в выпадающем списке "Тип наследования" выберите public;
отметьте флажковый переключатель "Наследование другого класса"; в
поле "Имя файла заголовка" внесите TMainForm.h, а в поле "Имя файла
реализации" - TMainForm.cpp. Нажмите OK:
На вкладке "Файлы" окна "Состав
проекта" QDevelop
раскройте древовидные списки "Исходники" и "Заголовки". Дважды щёлкните
по названиям файлов объявления и реализации, чтобы открыть их в
редакторе QDevelop. Присвойте параметру конструктора TMainForm pParent
значение 0, а параметру Flag значение Qt::Window:
TMainForm(QWidget* pParent = 0, Qt::WindowFlags Flag =
Qt::Window);
Не забудьте добавить параметры в
конструктор QMainWindow в файле реализации класса TMainForm:
Перейдите на вкладку "Классы" окна
"Состав проекта" QDevelop. В древовидном списке проекта (Klikit.pro)
щёлкните правой кнопкой мыши по названию класса
(TMainForm) и в контекстном меню выберите "Добавить Метод...":
В открывшемся диалоговом окне "Добавить
новый метод в класс" в поле "Имя Метода" введите LanguageChangeSlot; в
выпадающем списке "Возвращаемый тип" оставьте значение void; а в
выпадающем списке "Тип наследования" выберите public slots. Нажмите OK,
чтобы сгенерировать заготовки кода объявления и реализации метода
(слота) класса.
Данный слот в будущем будет отвечать за
интернационализацию (перевод строк интерфейса) нашей программы.
Поскольку мы будем вызывать слот в различных местах программы, мы
объявили его открытым (public). Добавим в наш слот функциональности.
Перейдите к заготовке реализации слота и наберите в ней this->.
В появившемся окне автодополнения кода наберите setW, после чего
выберите setWindowTitle и нажмите ENTER. Внутри функции
this->setWindowTitle(); наберите tr("Klikit - 15-puzzle").
Функция setWindowTitle отвечает за
отображение заголовка окна. В том случае, если она не была вызвана, в
заголовке окна отображается название приложения. Все строки программы,
которые мы в будущем намерены переводить, необходимо "обрамлять"
функцией tr - именно она сообщает переводчику о необходимости замены
строки интерфейса программы на переведённую строку.
Разумеется, мы могли бы просто набрать
setWindowTitle(tr("Klikit - 15-puzzle")); вручную, не обращаясь к this,
но автодополнение кода сильно ускоряет работу.
Для того, чтобы метод вызывался во
время работы программы, добавим его в конструктор класса TMainForm.
Задание размеров формы
Как правило, если геометрия виджета не
была задана явно, то он отображается в минимально допустимом размере,
определяемом обычно его (виджета) содержимым. Поскольку главное окно
нашего приложения пустое, оно будет выглядеть не слишком красиво.
Зададим его размеры явно с помощью
функции resize. Наберите в конструкторе класса TMainForm
resize(344, 344);
В качестве параметров функция принимает
целые числа (ширина и высота виджета). Поскольку в нашем примере эти
характеристики главного окна приложения будут определяться размером
игрового поля с набором фишек, то в будущем мы эту функцию уберём из
конструктора.
Отредактируйте исходные тексты класса
TMainForm, чтобы они выглядели так:
Откомпилируйте программу и запустите её
на выполнение (F7 - F5). Убедитесь, что происходит показ главного окна
приложения с заданными размерами и заголовком.
К слову, данный код является неплохой
заготовкой для создания будущих приложений, так что рекомендую
сохранить нашу заготовку на будущее.
На следующем этапе нам предстоит работа
с файлом ресурсов и создание заготовок меню, а также панелей
инструментов и состояния будущей программы.
Вопрос № 165157: Уважаемые эксперты,помогите -будьте так добры Дана матрица D[N,M]. Найти в каждой строке матрицы максимальный и минимальный элементы и поменять их местами с первым и последним элементом строки соответственно....Вопрос № 165160: Здравствуйте, уважаемые эксперты. Прошу вашей помощи в решении задачи!! <u><i>Тема:</i></u> <u>Строки</u> <u><i>Задача:</i></u> Ввести
текст на русском языке. Преобразовать его таким образом, чтобы в каждом слове слоги шли в обратном порядке...Вопрос № 165168: Доброго времени суток, уважаемые эксперты. Просьба помочь в следующей задаче: Даны натуральные числа K и N. Составить программу формирования массива А, элементами которого являются числа, сумма цифр которых равна К и которые не больше N. З...
Вопрос № 165.157
Уважаемые эксперты,помогите -будьте так добры Дана матрица D[N,M]. Найти в каждой строке матрицы максимальный и минимальный элементы и поменять их местами с первым и последним элементом строки соответственно.
Отправлен: 16.04.2009, 22:59
Вопрос задал: Redman (статус: Посетитель)
Всего ответов: 1 Мини-форум вопроса >>> (сообщений: 6)
Ответ отправил: Micren (статус: Практикант)
Ответ отправлен: 17.04.2009, 06:53
Как сказать этому эксперту "спасибо"?
Отправить SMS
#thank 247676 на номер 1151 (Россия) | Еще номера >>
Вам помогли? Пожалуйста, поблагодарите эксперта за это!
Оценка за ответ: 4
Вопрос № 165.160
Здравствуйте, уважаемые эксперты. Прошу вашей помощи в решении задачи!! Тема:Строки Задача: Ввести текст на русском языке. Преобразовать его таким образом, чтобы в каждом слове слоги шли в обратном порядке. Например: "мама мыла раму" -> "мама ламы мура". Если можно с объяснениями. Заранее спасибо.
Отправлен: 16.04.2009, 23:29
Вопрос задал: Terqu
Всего ответов: 1 Мини-форум вопроса >>> (сообщений: 2)
Отвечает: Ilkras
Здравствуйте, Terqu! Решение такое:
Код:
/* Ввести текст на русском языке. Преобразовать его таким образом, чтобы в каждом слове слоги шли в обратном порядке. Например: "мама мыла раму" -> "мама ламы мура". */
while(!isalpha(in_str[i])&& i < len)//ищем следующую букву - начало слова i++; } printf("You typed: %s
", in_str); printf("I type: %s
", out_str);
}
Вводим: The quick brown fox jumps over the lazy dog Получаем: You typed: The quick brown fox jumps over the lazy dog I type: ehT kciuq nworb xof spmuj revo eht yzal god
Ответ отправил: Ilkras (статус: Студент)
Ответ отправлен: 20.04.2009, 02:07
Как сказать этому эксперту "спасибо"?
Отправить SMS
#thank 247864 на номер 1151 (Россия) | Еще номера >>
Вам помогли? Пожалуйста, поблагодарите эксперта за это!
Оценка за ответ: 5
Вопрос № 165.168
Доброго времени суток, уважаемые эксперты. Просьба помочь в следующей задаче: Даны натуральные числа K и N. Составить программу формирования массива А, элементами которого являются числа, сумма цифр которых равна К и которые не больше N.
Заранее благодарю.
Отправлен: 17.04.2009, 00:50
Вопрос задал: Falc0n (статус: 2-й класс)
Всего ответов: 2 Мини-форум вопроса >>> (сообщений: 0)
Отвечает: Ilkras
Здравствуйте, Falc0n! решение вашей задачи ниже. Если есть вопросы - пишите в форуме.
Приложение:
Ответ отправил: Ilkras (статус: Студент)
Ответ отправлен: 17.04.2009, 02:51
Как сказать этому эксперту "спасибо"?
Отправить SMS
#thank 247672 на номер 1151 (Россия) | Еще номера >>
Вам помогли? Пожалуйста, поблагодарите эксперта за это!
Оценка за ответ: 5 Комментарий оценки: Большое спасибо
Отвечает: Терсков Сергей
Здравствуйте, Falc0n! Вот вариант с использованием класса STL - vector. Функция int digit_summ(int number) считает сумму цифр в переменной number.
Код:
#include <vector> #include <iostream>
using namespace std;
int digit_summ(int number) {
int result
= 0;
while(number != 0) {
result += number%10; number /= 10; }
return result; }
int main(int argc, char *argv[]) {
int N = 500; int K = 10;
vector<int> A;
cout << "N = " << N << endl << "K = " << K << endl << endl;
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.