Выбрать главу

Затем мы печатаем каждую страницу. Внешний цикл for определяется количеством копий, запрошенных пользователем. Большинство драйверов принтеров поддерживают печать нескольких копий, поэтому для них функция QPrinter::numCopies() всегда возвращает 1. Если драйвер принтера не может печатать несколько копий, numCopies() возвращает количество копий, запрошенное пользователем, и за печать этого количества копий отвечает приложение. (В примере с QImage, приведенном ранее в данном разделе, мы для простоты проигнорировали numCopies().)

Рис. 8.15 аналогичен 8.13.

Внутренний цикл for выполняется по всем страницам. Если страница не первая, мы вызываем newPage(), чтобы сбросить на печатающее устройство старую страницу и начать рисование новой страницы. Мы вызываем printPage() для распечатки каждой страницы.

01 void PrintWindow::printPage(QPainter *painter,

02 const QStringList &entries, int pageNumber)

03 {

04 painter->save();

05 painter->translate(0, LargeGap);

06 foreach (QString entry, entries) {

07 QStringList fields = entry.split(": ");

08 QString title = fields[0];

09 QString body = fields[1];

10 printBox(painter, title, titleFont, Qt::lightGray);

11 printBox(painter, body, bodyFont, Qt::white);

12 painter->translate(0, MediumGap);

13 }

14 painter->restore();

15 painter->setFont(footerFont);

16 painter->drawText(painter->window(),

17 Qt::AlignHCenter | Qt::AlignBottom,

18 QString::number(pageNumber));

19 }

Функция printPage() обрабатывает в цикле все элементы справочника цветов и печатает их при помощи двух вызовов функции printBox(): один для заголовка (название цветка) и другой для «тела» (описание цветка). Она также отображает номер страницы внизу по центру страницы.

01 void PrintWindow::printBox(QPainter *painter, const QString &str,

02 const QFont &font, const QBrush &brush)

03 {

04 painter->setFont(font);

05 int boxWidth = painter->window().width();

06 int textWidth = boxWidth - 2 * SmallGap;

07 int maxHeight = painter->window().height();

08 QRect textRect = painter->boundingRect(SmallGap, SmallGap,

09 textWidth, maxHeight, Qt::TextWordWrap, str);

10 int boxHeight = textRect.height() + 2 * SmallGap;

11 painter->setPen(QPen(Qt::black, 2, Qt::SolidLine));

12 painter->setBrush(brush);

13 painter->drawRect(0, 0, boxWidth, boxHeight);

14 painter->drawText(textRect, Qt::TextWordWrap, str);

15 painter->translate(0, boxHeight);

16 }

Рис. 8.16. Компоновка страницы справочника по цветам.

Функция printBox() вычерчивает контур блока, затем отображает текст внутри него.

Графические средства OpenGL

OpenGL является стандартным программным интерфейсом, предназначенным для воспроизведения графики 2D и 3D. Приложения Qt могут отображать графику 3D, используя модуль QtOpenGL, который рассчитан на применение системной библиотеки OpenGL. При изложении данного раздела предполагается, что вы знакомы с OpenGL. Если вы не знакомы с OpenGL, хорошо начинать его изучение с посещения сайта http://www.opengl.org/.

Рис. 8.17. Приложение Тетраэдр.

Вывод графики при помощи OpenGL в приложении Qt выполняется достаточно просто: мы должны создать подкласс QGLWidget, переопределить несколько виртуальных функций и собрать приложение вместе с библиотеками QtOpenGL и OpenGL. Из-за того, что QGLWidget наследует QWidget, большая часть наших знаний остается применимой и здесь. Основное отличие заключается в том, что вместо QPainter для выполнения графических операций мы используем стандартные функции библиотеки OpenGL.

Для демонстрации этого подхода мы рассмотрим программный код приложения Тетраэдр, показанного на рис. 8.17. Это приложение отображает в пространстве тетраэдр или четырехгранник, грани которого имеют различные цвета. Пользователь может поворачивать тетраэдр, нажимая кнопку мышки и перемещая ее. Пользователь может задавать цвет поверхности грани путем двойного щелчка с последующим выбором цвета в диалоговом окне QColorDialog, которое выдается на экран.

01 class Tetrahedron : public QGLWidget

02 {

03 Q_OBJECT

04 public:

05 Tetrahedron(QWidget *parent = 0);

06 protected:

07 void initializeGL();

08 void resizeGL(int width, int height);

09 void paintGL();

10 void mousePressEvent(QMouseEvent *event);

11 void mouseMoveEvent(QMouseEvent *event);