Язык программирования C++_6D.ppt
- Количество слайдов: 32
Глава 6 Д. Библиотека Qt МГТУ им. Н. Э. Баумана Факультет Информатика и системы управления Кафедра Компьютерные системы и сети Лектор: д. т. н. , проф. Иванова Галина Сергеевна 1
6. 1 Простейшая программа с Qt интерфейсом Пример 6. 1 Приложение Hello Объект QWidget – виджет управления окном Объект QLabel Окно приложения Объект QPush. Button Каждому элементу оконного интерфейса соответствует виджет – объект интерфейсного класса библиотеки Qt. Виджеты визуальных компонентов управляются контейнером – главным виджетом – виджетом управления окном приложения. В качестве такого виджета может использоваться объект класса QWidget. 2
Текст программы #include <Qt. Gui> int main(int argc, char *argv[]) { Объект-приложение QApplication app(argc, argv); Объект управления окном QWidget win; win. set. Window. Title("Hello"); Метка QLabel *hello. Label=new QLabel("Hello!", &win); Кнопка QPush. Button *exit. Button= new QPush. Button("Close", &win); Компоновщик QHBox. Layout *layout = new QHBox. Layout(&win); layout->add. Widget(hello. Label); layout->add. Widget(exit. Button); Связь сигнала со слотом QObject: : connect(exit. Button, SIGNAL(clicked(bool)), &win, SLOT(close())); win. show(); Визуализация окна app. exec(); 3 Запуск цикла обработки сообщений }
Контейнерные свойства виджетов Объект класса QWidget – win – контейнер, который отвечает за визуализацию компонентов и освобождение ими памяти. Компоновщик – контейнер, который отвечает за политику изменения размеров визуальных компонентов. 4
6. 2 Организация класса окна Диаграмма классов Пример 6. 2. Файл hello. h: #ifndef hello_h #define hello_h #include <Qt. Gui> class Win: public QWidget { QLabel *hello. Label; QPush. Button *exit. Button; public: Win(QWidget *parent = 0); }; #endif Диаграмма компоновки приложения Предотвращение повторной компиляции заголовка 5
Конструктор класса окна и русификация интерфейса Файл hello. cpp: #include "win. h" Win: : Win(QWidget *parent): QWidget(parent) Перекодировщик { QText. Codec *codec = QText. Codec: : codec. For. Name("Windows-1251"); set. Window. Title(codec->to. Unicode("Приветствие")); hello. Label = new QLabel(codec->to. Unicode("Привет!"), this); exit. Button = new QPush. Button(codec->to. Unicode("Выход"), this); QHBox. Layout *layout = new QHBox. Layout(this); layout->add. Widget(hello. Label); layout->add. Widget(exit. Button); connect(exit. Button, SIGNAL(clicked(bool)), this, SLOT(close())); } 6
Основная программа Файл main. cpp: #include "hello. h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Win win(0); win. show(); return app. exec(); } 7
6. 3 Механизм сигналов и слотов Пример 6. 3 Возведение числа в квадрат. Объявление новых слотов. Нормальное состояние 8
Файл win. h. Описание класса окна #ifndef win_h #define win_h #include <Qt. Gui> class Win: public QWidget // класс окна { Q_OBJECT // макрос Qt для реализации сигналов и слотов protected: QText. Codec *codec; // перекодировщик QFrame *frame; // рамка QLabel *input. Label; // метка ввода QLine. Edit *input. Edit; // строчный редактор ввода QLabel *output. Label; // метка вывода QLine. Edit *output. Edit; // строчный редактор вывода QPush. Button *next. Button; // кнопка Следующее QPush. Button *exit. Button; // кнопка Выход public: Win(QWidget *parent = 0); // конструктор public slots: void begin(); // инициализация интерфейса void calc(); // реализация вычислений }; 9
Файл win. h. Описание класса валидатора class Str. Validator: public QValidator // класс проверки ввода { public: Str. Validator(QObject *parent): QValidator(parent){} virtual State validate(QString &str, int &pos)const { return Acceptable; // метод всегда принимает // вводимую строку } }; #endif Объект валидатора при создании связывается с объектом строчного редактора. Метод validate() автоматически вызывается для проверки вводимой строки. Если метод возвращает Acceptable, то редактор генерирует сигналы editing. Finished() – завершение редактирования и return. Pressed() – нажатие клавиши Enter. 10
Файл win. cpp. Создание и настройка виджетов #include "win. h" Win: : Win(QWidget *parent): QWidget(parent) { codec = QText. Codec: : codec. For. Name("Windows-1251"); set. Window. Title(codec->to. Unicode("Возведение в квадрат")); frame = new QFrame(this); frame -> set. Frame. Shadow(QFrame: : Raised); frame -> set. Frame. Shape(QFrame: : Panel); input. Label = new QLabel(codec->to. Unicode("Введите число: "), this); input. Edit = new QLine. Edit("", this); Str. Validator *v=new Str. Validator(input. Edit); input. Edit -> set. Validator(v); output. Label = new QLabel(codec->to. Unicode("Результат: "), this); output. Edit = new QLine. Edit("", this); next. Button = new QPush. Button(codec->to. Unicode("Следующее"), this); exit. Button = new QPush. Button(codec->to. Unicode("Выход"), this); 11
Файл win. cpp. Компоновка виджетов QVBox. Layout *v. Layout 1 = new QVBox. Layout(frame); v. Layout 1 ->add. Widget(input. Label); v. Layout 1 ->add. Widget(input. Edit); v. Layout 1 ->add. Widget(output. Label); v. Layout 1 ->add. Widget(output. Edit); v. Layout 1 ->add. Stretch(); QVBox. Layout *v. Layout 2 = new QVBox. Layout(); v. Layout 2 ->add. Widget(next. Button); v. Layout 2 ->add. Widget(exit. Button); v. Layout 2 ->add. Stretch(); QHBox. Layout *h. Layout = new QHBox. Layout(this); h. Layout->add. Widget(frame); h. Layout->add. Layout(v. Layout 2); 12
Файл win. cpp. Инициализация интерфейса и связывание сигналов и слотов begin(); // инициализация интерфейса // связь нажания кнопки Выход и закрытия главного окна connect(exit. Button, SIGNAL(clicked(bool)), this, SLOT(close())); // связь нажания кнопки Следующее и инициализации интерфейса connect(next. Button, SIGNAL(clicked(bool)), this, SLOT(begin())); // связь нажания клавиши Enter и вычислений connect(input. Edit, SIGNAL(return. Pressed()), this, SLOT(calc())); } 13
Файл win. cpp. Метод начальной настройки (инициализации) интерфейса void Win: : begin() { input. Edit->clear(); // очистка строки ввода next. Button->set. Enabled(false); // деактивация кнопки Следующее next. Button->set. Default(false); // отмена активации кнопки // Следующее при нажатии Enter input. Edit->set. Enabled(true); // активация строки ввода output. Label->set. Visible(false); // сокрытие метки результата output. Edit->set. Visible(false); // сокрытие строки результата input. Edit->set. Focus(); // установка фокуса на строку ввода } 14
Файл win. cpp. Метод вычислений: выдача результата void Win: : calc() { bool Ok=true; float r, a; QString str=input. Edit->text(); // копирование введенной строки a=str. to. Double(&Ok); // преобразование строки в число if (Ok) // если преобразование успешно, то { r=a*a; // возводим число в квадрат str. set. Num(r); // преобразуем число в строку output. Edit->set. Text(str); // заносим результат в окно результата input. Edit->set. Enabled(false); // деактивируем окно ввода output. Label->set. Visible(true); // показываем метку результата output. Edit->set. Visible(true); // показываем окно результата next. Button->set. Default(true); // назначаем Следующее кнопкой // активируемой по нажатию клавиши Enter next. Button->set. Focus(); // устанавливаем фокус на // кнопку Следующее } 15 }
Файл win. cpp. Метод вычислений: выдача сообщения об ошибке ввода else if (!str. is. Empty()) { QMessage. Box msg. Box(QMessage. Box: : Information, codec->to. Unicode("Возведение в квадрат. "), codec->to. Unicode("Введено неверное значение. "), QMessage. Box: : Ok); msg. Box. exec(); } } 16
Файл main. cpp #include "win. h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Win win(0); win. show(); return app. exec(); } 17
6. 4 Обработка событий. Рисование. Таймеры Пример 6. 4 Создание движущихся изображений 18
Диаграмма объектов приложения Приложение включает 6 объектов: n окно; n кнопка Выход; n холст для рисования; n таймер; n линия; n квадрат. Диаграмма объектов 19
Диаграмма последовательностей действий 20
Диаграмма классов приложения События: • show. Event() – при визуализации области рисования – включаем таймер; • timer. Event() – при получении сообщения от таймера – инициируем перерисовку окна; • paint. Event() – при получении запроса на перерисовку области рисования – перерисовываем фигуры; 21 • hide. Event() – при сокрытии области рисования – выключаем таймер.
Диаграмма компоновки приложения Модуль Фигура содержит описание классов Фигура, Линия и квадрат. Модуль Область рисования содержит описание класса Холст. Модуль Окно содержит описание класса окна приложения. 22
Файл figura. h. Класс Фигура: #ifndef figura_h #define figura_h #include <Qt. Gui> class Figura { protected: int x, y, halflen, dx, dy, r; virtual void draw(QPainter *Painter)=0; public: Figura(int X, int Y, int Halflen): x(X), y(Y), halflen(Halflen){} void move(float Alpha, QPainter *Painter); }; 23
Файл figura. h. Классы Линия и Квадрат: class My. Line: public Figura { protected: void draw(QPainter *Painter); public: My. Line(int x, int y, int halflen): Figura(x, y, halflen){} }; class My. Rect: public Figura { protected: void draw(QPainter *Painter); public: My. Rect(int x, int y, int halflen): Figura(x, y, halflen){} }; #endif 24
Файл figura. cpp #include <math. h> #include "figura. h" void Figura: : move(float Alpha, QPainter *Painter) { dx=halflen*cos(Alpha); dy=halflen*sin(Alpha); draw(Painter); // необходим сложный полиморфизм! } void My. Line: : draw(QPainter *Painter) { Painter->draw. Line(x+dx, y+dy, x-dx, y-dy); } void My. Rect: : draw(QPainter *Painter) { Painter->draw. Line(x+dx, y+dy, x+dy, y-dx); Painter->draw. Line(x+dy, y-dx, x-dx, y-dy); Painter->draw. Line(x-dx, y-dy, x-dy, y+dx); Painter->draw. Line(x-dy, y+dx, x+dx, y+dy); } 25
Файл area. h #include "figura. h" class Area : public QWidget { int my. Timer; // идентификатор таймера float alpha; // угол поворота public: Area(QWidget *parent = 0); ~Area(); My. Line *myline; My. Rect *myrect; protected: // обработчики событий void paint. Event(QPaint. Event *event); void timer. Event(QTimer. Event *event); void show. Event(QShow. Event *event); void hide. Event(QHide. Event *event); }; #endif 26
Файл area. cpp. Обработка событий визуализации и перерисовки #include "area. h" Area: : Area(QWidget *parent): QWidget(parent) { set. Fixed. Size(QSize(300, 200)); // фиксируем размер Холста myline=new My. Line(80, 100, 50); // создаем объект Линия myrect=new My. Rect(220, 100, 50); // создаем объект Квадрат alpha=0; } void Area: : show. Event(QShow. Event *) { my. Timer=start. Timer(50); // включаем таймер } void Area: : paint. Event(QPaint. Event *) { QPainter painter(this); // создаем контент рисования на Холсте painter. set. Pen(Qt: : red); // задаем красное Перо myline->move(alpha, &painter); // рисуем Линию myrect->move(alpha*(-0. 5), &painter); // рисуем Квадрат } 27
Файл area. cpp. Обработка событий таймера и сокрытия Холста void Area: : timer. Event(QTimer. Event *event) { if (event->timer. Id() == my. Timer) // если наш таймер { alpha=alpha+0. 2; update(); // обновить внешний вид } else QWidget: : timer. Event(event); // иначе передать далее } void Area: : hide. Event(QHide. Event *) { kill. Timer(my. Timer); // выключить таймер } Area: : ~Area() { delete myline; delete myrect; } 28
Файл window. h #ifndef window_h #define window_h #include <Qt. Gui> #include "area. h" class Window : public QWidget { protected: QText. Codec *codec; Area * area; // область отображения рисунка QPush. Button * btn; public: Window(); }; #endif 29
Файл window. cpp #include "window. h" Window: : Window() { codec = QText. Codec: : codec. For. Name("Windows-1251"); this->set. Window. Title(codec->to. Unicode("Обработка событий")); area = new Area( this ); btn = new QPush. Button(codec->to. Unicode("Завершить"), this ); QVBox. Layout *layout = new QVBox. Layout(this); layout->add. Widget(area); layout->add. Widget(btn); connect(btn, SIGNAL(clicked(bool)), this, SLOT(close())); }; 30
Файл main. cpp #include "window. h" int main(int argc, char *argv[]) { QApplication appl(argc, argv); Window win; win. show(); return appl. exec(); } 31
32
Язык программирования C++_6D.ppt