Пример 2.
Печать отчета
Задание конструктивных параметов и отображение оптической системы
Реализация функций в диалоге (файл lens.cpp)
В реализацию диалога примера 1 надо добавить:
- подключение необходимых файлов
- создание связи между кнопками и функциями по их обработке
- реализацию нескольких функций:
//-------------------------------------------------------------------------------------------------
// обработка печати отчета (кнопка PrintReport), вызывает функцию PrintReport
void
DQtOpticalSystem::OnPrintReport()
{
#ifndef QT_NO_PRINTER
// создаем принтер и задаем параметры по умолчанию
QPrinter printer;
printer.setOrientation(QPrinter::Portrait);
printer.setPaperSize(QPrinter::A4);
printer.setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
// создаем стандартный диалог для выбора принтера
QPrintDialog qPrintDialog(&printer, this);
// если OK - вызываем функцию для печати
if(qPrintDialog.exec())
PrintReport(&printer);
#endif
}
//-------------------------------------------------------------------------------------------------
// обработка PrintPreview (кнопка PrintPreview), вызывает функцию PrintReport
void
DQtOpticalSystem::OnPrintPreview()
{
#ifndef QT_NO_PRINTER
// создаем принтер и задаем параметры по умолчанию
QPrinter printer;
printer.setOrientation(QPrinter::Portrait);
printer.setPaperSize(QPrinter::A4);
printer.setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
// создаем стандартный диалог для PrintPreview
QPrintPreviewDialog qPrintPreview(&printer, this, Qt::Window);
// устанавливаем функцию PrintReport в качестве обработчика события печати для диалога qPrintPreview
connect(&qPrintPreview, SIGNAL(paintRequested(QPrinter *)), SLOT(PrintReport(QPrinter *)));
// вызываем диалог qPrintPreview
qPrintPreview.exec();
#endif
}
//-------------------------------------------------------------------------------------------------
// печать отчета в принтер roPrinter_p
void
DQtOpticalSystem::PrintReport(QPrinter* poPrinter_p)
{
// устанавливем курсор - песочные часы
QApplication::setOverrideCursor(Qt::WaitCursor);
// параметры страницы принтера
QRect &qPageRect=poPrinter_p->pageRect();
// создаем QPainter, связанный с принтером
QPainter qPainter(poPrinter_p);
// документ html, в который будет записан отчет
QTextDocument qTextDoc;
qTextDoc.setTextWidth(qPageRect.width());
qTextDoc.setDocumentMargin(0);
// текст для начала и конца документа html
QString sHtmlHeader="<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body>";
QString sHtmlFooter="</body></html>";
//-----------------------------------------------------------------------
// создание html-таблицы конструктивных параметров
QString sTable=( "<h2>Конструктивные параметры</h2>");
// заголовок таблицы
sTable+="<table width=100% border=1 cellpadding=0 cellspacing=0><tr>";
sTable+="<td width=\"10%\">№</td>";
sTable+="<td width=\"23%\">Радиусы кривизны</td>";
sTable+="<td width=\"23%\">Осевые расстояния</td>";
sTable+="<td width=\"22%\">Световые высоты</td>";
sTable+="<td width=\"22%\">Показатель преломления</td></tr>";
// каждая строка таблицы - одна поверхность О.С.
for(int i=0; i<m_oSystem.size(); ++i)
{
sTable+="<tr>";
sTable+="<td width=\"4%\">" + QString::number(i) + "</td>";
sTable+="<td width=\"24%\">" + QString::number(m_oSystem[i].r) + "</td>";
sTable+="<td width=\"24%\">" + QString::number(m_oSystem[i].d) + "</td>";
sTable+="<td width=\"24%\">" + QString::number(m_oSystem[i].h) + "</td>";
sTable+="<td width=\"24%\">" + QString::number(m_oSystem[i].n) + "</td>";
sTable+="</tr>";
}
sTable+="</table><br>";
// печатаем номер страницы и общие параметры документа
PrintPageHeaderFooter(qPainter, qPageRect, 1);
//-----------------------------------------------------------------------
// создание html-заголовка для внешнего вида OC
QString sDrawLens=( "<h2><br>Оптическая схема</h2>");
// вычисляем размер изображения О.С. таким образом, чтобы изображение
// заняло 0.5 страницы в высоту и всю страницу в ширину
int iPictHeight=qPageRect.height()/2;
int iPictWidth =qPageRect.width();
//-----------------------------------------------------------------------
// проверяем, помещается ли все на одну страницу и печатаем html-документы
// устанавливаем текст страницы в html в документ qTextDoc
qTextDoc.setHtml(sHtmlHeader + sTable + sDrawLens + sHtmlFooter);
// определяем высоту получившегося документа
int iPrevHeight=qTextDoc.size().height();
// проверяем, помещается ли все на одну страницу
if((iPrevHeight + iPictHeight) <= qPageRect.height())
{
// если поместилось:
// печатаем таблицу и заголовок рисунка в qPainter, в область страницы
qTextDoc.drawContents(&qPainter, QRect(0,0, qPageRect.width(), qPageRect.height()));
}
else
{
// если не поместилось:
// печатаем только таблицу в qPainter, в область страницы
qTextDoc.setHtml(sHtmlHeader + sTable + sHtmlFooter);
qTextDoc.drawContents(&qPainter, QRect(0,0, qPageRect.width(), qPageRect.height()));
// переходим на новую страницу
poPrinter_p->newPage();
// печатаем номер страницы и общие параметры
PrintPageHeaderFooter(qPainter, qPageRect, 2);
// печатаем заголовок рисунка в qPainter, в область страницы
qTextDoc.setHtml(sHtmlHeader + sDrawLens + sHtmlFooter);
qTextDoc.drawContents(&qPainter, QRect(0,0, qPageRect.width(), qPageRect.height()));
// пересчитываем высоту последней страницы
iPrevHeight=qTextDoc.size().height();
}
//-----------------------------------------------------------------------
// рисуем оптическую систему в qPainter
// устанавливаем область рисования
qPainter.setViewport(0, iPrevHeight, iPictWidth, iPictHeight);
// рисуем О.С. в созданном qPainter
DrawOs(qPainter);
//-----------------------------------------------------------------------
// возвращаем обычный курсор
QApplication::restoreOverrideCursor();
}
//-------------------------------------------------------------------------------------------------
// печать параметров страницы в rqPainter_p
// rqPageRect_p - область рисования основной страницы, параметры страницы будут рисоваться над и под ней
// iPageNum_p - номер страницы
void
DQtOpticalSystem::PrintPageHeaderFooter(QPainter& rqPainter_p, QRect &rqPageRect_p, int iPageNum_p)
{
// печатаем верхнюю часть страницы (линия и текст над линией)
rqPainter_p.drawLine(0, 0, rqPageRect_p.width(), 0);
rqPainter_p.drawText(0, -rqPainter_p.fontMetrics().ascent()+5,
"Кафедра Прикладной и компьютерной оптики, Университет ИТМО, http://aco.ifmo.ru");
// печатаем нижнюю часть страницы (линия и номер страницы под линией)
rqPainter_p.drawLine(0, rqPageRect_p.height(), rqPageRect_p.width(), rqPageRect_p.height());
rqPainter_p.drawText(rqPageRect_p.width() - rqPainter_p.fontMetrics().width(QString::number(iPageNum_p)),
rqPageRect_p.height()+ rqPainter_p.fontMetrics().ascent()+5,
QString::number(iPageNum_p));
}
//-------------------------------------------------------------------------------------------------
Альтернативным вариантом рисования картинки может быть рисование ее в Pixmap и добавление в html в виде картинки. Такой вариант может быть удобен, если есть много мелких картинок, которые необходимо расположить в тексте или таблице:
//-----------------------------------------------------------------------
// создание изображения для внешнего вида OC
QString sDrawLens=( "<h2>Оптическая схема</h2>");
// вычисляем размер изображения О.С. таким образом, чтобы изображение
// заняло 0.5 страницы в высоту и всю страницу в ширину
int lHeight=qPageRect.height()/2;
int lWidth =qPageRect.width();
// создаем QPixmap, в который будет записано изображение
QPixmap qPixmap( lWidth, lHeight );
qPixmap.fill();
// создаем QPainter на основе pixmap
QPainter qPaintLens(&qPixmap);
// рисуем О.С. в созданном qPainter
DrawOs(qPaintLens);
// создаем в qTextDoc ресурс, связанный с созданным qPixmap
QString sPict="mydata://image_01.png";
qTextDoc.addResource(QTextDocument::ImageResource, QUrl(sPict), QVariant(qPixmap));
// создаем html для отображения картинки
sDrawLens+=("<p><img src=\"" + sPict + "\" width=" + QString::number(lWidth) +
" height="+ QString::number(lHeight) + "/></p>");
//-----------------------------------------------------------------------
|