- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 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);
// ...
}