- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Шрифт:
Интервал:
Закладка:
Обратите внимание на то, что кнопка Color menu исчезла. Она не нужна, пока открыто меню. Щелкнем на кнопке blue и получим следующий результат.
Теперь линии стали синими, а кнопка Color menu вновь появилась на экране.
Для того чтобы достичь такого эффекта, мы добавили кнопку Color menu и модифицировали функцию “pressed”, настроив видимость меню и кнопки. Вот как выглядит класс Lines_window после всех этих модификаций.
struct Lines_window:Window {
Lines_window(Point xy, int w, int h, const string& title );
private:
// данные:
Open_polyline lines;
// элементы управления окном:
Button next_button; // добавляет (next_x,next_y) к линиям
Button quit_button; // завершает работу программы
In_box next_x;
In_box next_y;
Out_box xy_out;
Menu color_menu;
Button menu_button;
void change(Color c) { lines.set_color(c); }
void hide_menu() { color_menu.hide(); menu_button.show(); }
// действия, инициирующие обратные вызовы:
void red_pressed() { change(Color::red); hide_menu(); }
void blue_pressed() { change(Color::blue); hide_menu(); }
void black_pressed() { change(Color::black); hide_menu(); }
void menu_pressed() { menu_button.hide(); color_menu.show(); }
void next();
void quit();
// функции обратного вызова:
static void cb_red(Address, Address);
static void cb_blue(Address, Address);
static void cb_black(Address, Address);
static void cb_menu(Address, Address);
static void cb_next(Address, Address);
static void cb_quit(Address, Address);
};
Обратите внимание на то, что все члены, кроме конструкторов, являются закрытыми. В принципе этот класс и является программой. Все, что происходит, происходит с помощью обратных вызовов, поэтому никакого кода, кроме этого класса, не требуется. Мы упорядочили объявления, чтобы определение класса стало более удобочитаемым. Конструктор передает аргументы всем своим подобъектам и связывает их с окном.
Lines_window::Lines_window(Point xy,int w,int h,
const string&title)
:Window(xy,w,h,title),
next_button(Point(x_max()–150,0),70,20,
"Next point", cb_next),
quit_button(Point(x_max()–70,0),70,20,"Quit",cb_quit),
next_x(Point(x_max()–310,0),50,20,"next x:"),
next_y(Point(x_max()–210,0),50,20,"next y:"),
xy_out(Point(100,0),100,20,"current (x,y):")
color_menu(Point(x_max()–70,30),70,20,Menu::vertical,"color"),
menu_button(Point(x_max()–80,30),80,20,
"color menu",cb_menu),
{
attach(next_button);
attach(quit_button);
attach(next_x);
attach(next_y);
attach(xy_out);
xy_out.put("нет точек");
color_menu.attach(new Button(Point(0,0),0,0,"red",cb_red));
color_menu.attach(new Button(Point(0,0),0,0,"blue",cb_blue));
color_menu.attach(new Button(Point(0,0),0,0,"black",cb_black));
attach(color_menu);
color_menu.hide();
attach(menu_button);
attach(lines);
}
Обратите внимание на то, что инициализация выполняется в порядке определения данных-членов. Это правильный порядок инициализации. Фактически инициализация членов всегда происходит в порядке их объявления. Некоторые компиляторы выдают предупреждения, если конструктор базового класса или члена нарушает этот порядок.
16.8. Отладка программы графического пользовательского интерфейса
После того как программа графического пользовательского интерфейса начнет работать, ее отладка будет довольно простой: что видите, то и получите. Однако иногда возникает трудный фрустрационный период перед появлением первой фигуры или элемента управления окном и даже перед появлением самого окна на экране. Протестируем функцию main().
int main()
{
Lines_window (Point(100,100),600,400,"lines");
return gui_main();
}
Вы видите ошибку? Независимо от того, видите ли вы ее или нет, эту программу следует испытать; она компилируется и выполняется, но вместо линий на экране в лучшем случае появляется какое-то мерцание. Как найти ошибку в такой программе? Для этого можно сделать следующее.
• Тщательно исследовать части программы (классы, функции, библиотеки).
• Упростить все добавления, понемногу увеличивая объем программы, начиная с простейшей версии и тщательно отслеживая строку за строкой.
• Проверить все установки редактора связей.
• Сравнить ее с уже работающей программой.
• Объяснить код другу.
Среди всех этих предложений самым трудным является отслеживание выполнения кода. Если вы умеете работать с отладчиком программ, у вас есть шанс, но простая вставка операторов вывода в данном случае бесполезна — проблема заключается в том, что никакой вывод на экране не появится. Даже отладчики иногда испытывают проблемы, поскольку в компьютере несколько действий выполняется одновременно (многопоточность), так как ваша программа — не единственная программа, пытающаяся взаимодействовать с экраном. Главное — упростить код и систематически его исследовать.
Итак, в чем же проблема? Вот правильная версия (см. раздел 16.5).
int main()
{
Lines_window win(Point(100,100),600,400,"lines");
return gui_main();
}
Мы забыли указать имя win объекта класса Lines_window. Поскольку на самом деле мы не используем это имя, это кажется разумным, но компилятор решит, что, поскольку вы не используете окно, его можно сразу удалить. Ой! Это окно существовало всего несколько миллисекунд. Ничего удивительно, что мы его не заметили.
Другая распространенная проблема заключается в том, что окно располагается точно поверх другого окна. Это выглядит так, будто на экране открыто только одно окно. А куда делось другое? Мы можем долго искать несуществующие ошибки в своей программе. Та же самая проблема может возникнуть, если вы размещаете одну фигуру поверх другой.
И в заключение (чтобы еще больше огорчить читателей) отметим, что при работе с библиотеками графического пользовательского интерфейса исключения не всегда срабатывают так, как мы от них ожидаем. Поскольку наша программа управляется библиотекой графического пользовательского интерфейса, сгенерированное исключение может никогда не попасть к своему обработчику — библиотека или операционная система может “съесть” его (т.е. использовать механизмы обработки ошибок, отличающиеся от исключения языка С++).
К типичным проблемам, выявляемым при отладке, относится и отсутствие изображений объектов Shape и Widget из-за отсутствия связи с окном или неправильного поведения объекта. Однако их описание выходит за рамки нашей книги. Посмотрите, как программист может создать и связать кнопку с меню, породив проблемы.
// вспомогательная функция для загрузки кнопки в меню
void load_disaster_menu(Menu& m)
{
Point orig(0,0);
Button b1(orig,0,0,"flood",cb_flood);
Button b2(orig,0,0,"fire",cb_fire);
// ...
m.attach(b1);
m.attach(b2);
// ...
}
int main()
{
// ...
Menu disasters(Point(100,100),60,20,Menu::horizontal,"disasters");
load_disaster_menu(disasters);
win.attach(disasters);
// ...
}

