Теория и технология программирования Объектно-ориентированное программирование на языке C++ Лекция 9. Использование Qt Глухих Михаил Игоревич, к.т.н., доц. mailto: glukhikh@mail.ru Пример - графический мини-редактор Задача - рисование на экране простых фигур, таких, как прямоугольники и эллипсы Иерархия классов фигур Базовый класс – фигура ее можно нарисовать в заданном QPainter как задать, где находится фигура? Иерархия классов фигур Базовый класс – фигура ее можно нарисовать в заданном QPainter как задать, где находится фигура? например – по двум точкам, или по одной точке и размеру какие еще общие действия? Иерархия классов фигур Базовый класс – фигура ее можно нарисовать в заданном QPainter как задать, где находится фигура? например – по двум точкам, или по одной точке и размеру какие еще общие действия? передвижение, изменение размера Определение класса class Figure { protected: QPoint upp_left, size; public: Figure(const QPoint& ul, const QPoint& s): upp_left(ul), size(s) {} void moveTo(const QPoint& to); void resize(const QPoint& lr); virtual void paint(QPainter& painter) = 0; }; Разновидности фигуры class Square: public Figure { public: Square(const QPoint& ul, const QPoint& s): Figure(ul, s) {} virtual void paint(QPainter& painter); }; class Circle: public Figure { // ... }; Объектно-ориентированное программирование на языке C++ 7 Отрисовка фигур void Square::paint(QPainter &painter) { painter.drawRect(QRect(upp_left, upp_left + size)); } void Circle::paint(QPainter &painter) { QPoint radius = size / 2; painter.drawEllipse(upp_left + radius, radius.x(), radius.y()); } Объектно-ориентированное программирование на языке C++ 8 Окно, действия, меню, панель инструментов См. дизайнер Действие – то, что можно выполнить, часто разными способами: командой меню клавишей на ToolBar обычной клавишей ... Наполнение окна class MainWindow : public QMainWindow { Q_OBJECT QList<Figure*> figures; // Уже созданы Figure* current; // Создается сейчас FigureType type; QTimer* timer; bool blink; // Показать/убрать // ... }; Обработчик действия void MainWindow::on_actionSquare_activated() { type = FT_SQUARE; current = 0; repaint(); } Объектно-ориентированное программирование на языке C++ 11 Триггерное действие void MainWindow::on_actionSquare_triggered( bool checked) { type = checked ? FT_SQUARE : FT_NONE; ui->actionCircle->setChecked(false); current = 0; repaint(); } Объектно-ориентированное программирование на языке C++ 12 Отрисовка void MainWindow::paintEvent(QPaintEvent *event) { QPainter painter; painter.begin(this); QListIterator<Figure*> it(figures); while (it.hasNext()) { Figure* fig = it.next(); fig->paint(painter); } // ... painter.end(); } Объектно-ориентированное программирование на языке C++ 13 Создание фигуры мышью Нажать клавишу Передвинуть мышь ... Передвинуть мышь Отпустить клавишу Объектно-ориентированное программирование на языке C++ 14 Обработчики сообщений мыши void MainWindow::mousePressEvent(QMouseEvent * ev) { if (type==FT_NONE) return; if (ev->button() != Qt::LeftButton) return; if (type==FT_SQUARE) { current = new Square(ev->pos(), QPoint(0, 0)); } else { current = new Circle(ev->pos(), QPoint(0, 0)); } } Объектно-ориентированное программирование на языке C++ 15 Обработчики сообщений мыши void MainWindow::mouseMoveEvent(QMouseEvent * ev) { if (current != 0) { current->resize(ev->pos()); repaint(); } } Объектно-ориентированное программирование на языке C++ 16 Обработчики сообщений мыши void MainWindow::mouseReleaseEvent(QMouseEvent* ev) { if (ev->button() != Qt::LeftButton) return; if (current != 0) { current->resize(ev->pos()); figures.append(current); current = 0; repaint(); } } Объектно-ориентированное программирование на языке C++ 17 Другой способ создания фигуры Двумя щелчками мыши Что требуется изменить? Объектно-ориентированное программирование на языке C++ 18 Таймер Qt Формирует определённое сообщение один раз за определённый период времени в рамках Qt таймер QTimer формирует сигнал timeout() у нас используется для мигания timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(onTimeout())); Объектно-ориентированное программирование на языке C++ 19 Обработчик таймера void MainWindow::onTimeout() { blink = !blink; repaint(); } // Часть paintEvent... if (current && !blink) { painter.setPen(QPen(Qt::red)); current->paint(painter); } // timer->start(period) – запуск таймера // timer->stop() – остановка таймера Объектно-ориентированное программирование на языке C++ 20 Изменение цвета Добавить свойство "цвет" каждой фигуре Добавить диалог для выбора цвета См. дизайнер Объектно-ориентированное программирование на языке C++ 21 Диалог выбора цвета void MainWindow:: on_actionChooseColor_activated() { // Стандартный диалог QColorDialog QColorDialog* dialog = new QColorDialog(this); color = dialog->getColor(); } Объектно-ориентированное программирование на языке C++ 22 Привязка изображения к действию См. дизайнер Объектно-ориентированное программирование на языке C++ 23 Контекстное меню Создаётся на базе QMenu См. текст программы Объектно-ориентированное программирование на языке C++ 24