1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00

使用Rect的QQtWord

This commit is contained in:
AbelTian 2018-07-30 12:32:36 +08:00
parent f321fff8e8
commit a1c9c3b8d0
5 changed files with 367 additions and 290 deletions

View File

@ -1,4 +1,4 @@
#include "qqt-qt.h"
#include "qqt-qt.h"
#include "qqtcore.h"
#include "qqtprinter.h"
#include "qqtgraphicsscene.h"
@ -9,83 +9,14 @@ QQtWord::QQtWord(QObject* parent) :
QObject ( parent ),
fmt ( 0 ), headerFmt ( 0 ), titleFmt ( 0 ), title2Fmt ( 0 ), mainFmt ( 0 )
{
//setup printer
/**
MIPS bug: you must use QQtPrinter(QPrinter::HighResolution)
Other constructer won't work well
*/
pr = new QQtPrinter(QPrinter::HighResolution);
pr->setFullPage(true);
pr->setColorMode(QPrinter::Color);
pr->setPaperSize(QPrinter::A4);
pr->setOrientation(QPrinter::Portrait);
pr->setOutputFormat(QPrinter::PdfFormat);
logicalDpiX = logicalDpiY = 300;
sceneRect = QRectF ( 0, 0, 2480, 3508 );
/*
* Font目标是打印纸上
* Pos目标不是纸上的DPI
* 使
* View 142,138 //PCView 96 //打印机View 1200
* 1200
* DrawText可用空间减小甚至切掉一部分
*/
#ifdef __EMBEDDED_LINUX__
/*
*
*/
logicalDpiX = 136;
logicalDpiY = 156;
#else
/*
*
*/
logicalDpiX = 96;
logicalDpiY = 96;
#endif
QRect rect = pr->paperRect();
sceneRect = QRectF(0.0, 0.0, logicalDpiX * rect.width() / pr->logicalDpiX(),
logicalDpiY * rect.height() / pr->logicalDpiY());
#if 0
//1200 9917,14033 printerRect 固定
//116 958,1356 sceneRect
//142 1113,1660 sceneRect
pline() << pr->logicalDpiX() << pr->logicalDpiY();
pline() << logicalDpiX << logicalDpiY << pr->pageRect() << sceneRect;
pline() << pr->paperRect(QPrinter::DevicePixel);
pline() << pr->paperRect(QPrinter::Millimeter);
pline() << pr->paperRect(QPrinter::Point);
pline() << pr->paperRect(QPrinter::Inch);
pline() << pr->paperRect(QPrinter::Pica);
pline() << pr->paperRect(QPrinter::Didot);
pline() << pr->paperRect(QPrinter::Cicero);
#endif
m_mainFont = QApplication::font();
if (mainFmt)
delete mainFmt;
mainFmt = new QFontMetrics(m_mainFont);
m_titleFont = QApplication::font();
m_titleFont.setPointSize(22);
if (titleFmt)
delete titleFmt;
titleFmt = new QFontMetrics(m_titleFont);
m_title2Font = QApplication::font();;
m_title2Font.setPointSize(16);
if (title2Fmt)
delete title2Fmt;
title2Fmt = new QFontMetrics(m_title2Font);
initConstFont();
setMargin();
setHeaderSize();
setFooterSize();
setHeaderHeight();
setFooterHeight();
setFont();
setHeaderFont();
@ -99,10 +30,10 @@ QQtWord::QQtWord(QObject* parent) :
void QQtWord::setMargin ( qreal left, qreal right, qreal top, qreal botoom )
{
leftMargin = 134.6;
rightMargin = 134.6;
topMargin = 177.7;
bottomMargin = 177.7;
leftMargin = left;
rightMargin = right;
topMargin = top;
bottomMargin = botoom;
}
QRectF QQtWord::clientRectF()
@ -122,11 +53,12 @@ QRectF QQtWord::paperRect()
void QQtWord::setFont ( QFont font )
{
//normal font 11
m_font = QApplication::font();
if ( font == QFont() )
font = QApplication::font();
m_font = font;
if ( fmt )
delete fmt;
fmt = new QFontMetrics ( m_font );
}
@ -321,26 +253,6 @@ void QQtWord::addTable(const QTableView* table, QPointF pos)
int QQtWord::pageNum() { return pageSceneVector.size(); }
void QQtWord::exportPdf(const QString& pdf)
{
// setup printer
pr->setOutputFileName(pdf);
// print pdf
QPainter p(pr);
QQtGraphicsScene* pageScene = 0;
foreach (pageScene, pageSceneVector)
{
pageScene->render(&p, pr->paperRect(), sceneRect);
if (pageScene != pageSceneVector.last())
pr->newPage();
}
}
QQtGraphicsScene* QQtWord::getPage ( int num )
{
if ( num < 1 || num > pageSceneVector.size() )
@ -349,11 +261,6 @@ QQtGraphicsScene* QQtWord::getPage(int num)
return pageSceneVector.at ( num - 1 );
}
void QQtWord::print()
{
pr->print();
}
void QQtWord::setHeaderFont ( QFont font )
{
//header font
@ -366,9 +273,9 @@ void QQtWord::setHeaderFont(QFont font)
headerFmt = new QFontMetrics ( m_headerFont );
}
void QQtWord::setHeaderSize(qreal size)
void QQtWord::setHeaderHeight ( qreal size )
{
headerSize = 70;
headerSize = size;
}
void QQtWord::setHeaderLine ( bool show )
@ -382,9 +289,14 @@ void QQtWord::setHeaderText(const QString& text, QFont font, Qt::Alignment align
paintPageHeader();
}
void QQtWord::setFooterSize(qreal size)
void QQtWord::setFooterFont ( QFont font )
{
footerSize = 70;
setHeaderFont ( font );
}
void QQtWord::setFooterHeight ( qreal size )
{
footerSize = size;
}
QFont QQtWord::font() { return m_font; }
@ -402,6 +314,32 @@ void QQtWord::setFooterText(const QString& text, QFont font, Qt::Alignment align
paintPageFooter();
}
void QQtWord::exportImage ( QList<QImage>& targetPapers, QRectF targetRect )
{
while ( !targetPapers.isEmpty() )
targetPapers.removeAt ( 0 );
if ( targetRect == QRectF() )
targetRect = sceneRect;
QQtGraphicsScene* pageScene = 0;
foreach ( pageScene, pageSceneVector )
{
QImage page ( targetRect.size().toSize(), QImage::Format_ARGB32 );
QPainter p ( &page );
//我写的这个类,QQtGraphicsScene这个类,还是有问题的,不能对改变了DPI的整体缩放.
//但是!这里可以对改变了DPI的进行清晰化和模糊化!
#if 1
p.scale ( targetRect.width() / sceneRect.width(),
targetRect.height() / sceneRect.height() );
pageScene->render ( &p, sceneRect, sceneRect );
#else
pageScene->render ( &p, targetRect, sceneRect );
#endif
targetPapers.push_back ( page );
}
}
void QQtWord::initWord()
{
while ( ! pageSceneVector.isEmpty() )
@ -569,3 +507,26 @@ QHash<int, ESpanFlags> QQtWord::tableSpans(const QTableView* table)
return spans;
}
void QQtWord::initConstFont()
{
//mainFont 正文
m_mainFont = QApplication::font();
if ( mainFmt )
delete mainFmt;
mainFmt = new QFontMetrics ( m_mainFont );
//标题
m_titleFont = QApplication::font();
m_titleFont.setPointSize ( 22 );
if ( titleFmt )
delete titleFmt;
titleFmt = new QFontMetrics ( m_titleFont );
//标题2
m_title2Font = QApplication::font();;
m_title2Font.setPointSize ( 16 );
if ( title2Fmt )
delete title2Fmt;
title2Fmt = new QFontMetrics ( m_title2Font );
}

View File

@ -29,6 +29,7 @@ Q_DECLARE_FLAGS ( ESpanFlags, ESpanFlag )
* , , .
* ,
* Widget,
* ,.
*
* DPI,.
* Rect1 : DPI1 = Rect2 : DPI2
@ -38,12 +39,13 @@ Q_DECLARE_FLAGS ( ESpanFlags, ESpanFlag )
* DWin屏幕(View) 800*600 136(x) 156(y) 142 138
* PC屏幕(View) 1920*1080 96 96
* Printer 9917*14033 1200
* Image 1920*1080 96 96
*
* Scene可以设置纸张类型, A3 DPI不变 SceneRect会变.Rect像素大小,PS.
*
*
* 1. ,,,.
*
* 2. Scene使用默认的分辨率300, rect根据纸的类型而变化.
*/
class QQTSHARED_EXPORT QQtWord : public QObject
{
@ -55,6 +57,9 @@ public:
* @brief initWord
*/
void initWord();
/**
* @brief addText
*/
void addText ( const QString& text, QFont m_font = QFont(),
Qt::Alignment align = Qt::AlignHCenter, QPointF point = QPointF ( 0, 0 ) );
void addTable ( const QTableView* table, QPointF pos = QPointF ( 0, 0 ) );
@ -65,28 +70,60 @@ public:
QRectF clientRectF();
QRectF paperRect();
void setMargin ( qreal left = 0, qreal right = 0,
qreal top = 0, qreal botoom = 0 );
void setLineSpacing ( qreal mainSpacing = 0 );
void setHeaderSize ( qreal size = 0 );
void setFooterSize ( qreal size = 0 );
//单位:像素. 可以结合Adobe PhotoShop和WPS Word进行计算.
void setMargin ( qreal left = 375.5898, qreal right = 375.5898,
qreal top = 299.9994, qreal botoom = 299.9994 );
void setLineSpacing ( qreal mainSpacing = 0 );
void setHeaderHeight ( qreal size = 195.32 );
void setFooterHeight ( qreal size = 195.32 );
//正文,正在使用中
QFont font();
//default: QApplication::font()
void setFont ( QFont m_font = QFont() );
void setHeaderFont ( QFont m_font = QFont() );
//header,使用中.
void setHeaderFont ( QFont font = QFont() );
void setHeaderLine ( bool show = false );
void setHeaderText ( const QString& text, QFont m_font = QFont(),
Qt::Alignment align = Qt::AlignHCenter );
//footer,使用中
void setFooterFont ( QFont font = QFont() );
void setFooterLine ( bool show = false );
void setFooterText ( const QString& text, QFont m_font = QFont(),
Qt::Alignment align = Qt::AlignHCenter );
/**
* @brief mainFont
*/
QFont mainFont() { return m_mainFont; }
QFont titleFont() { return m_titleFont; }
QFont title2Font() { return m_title2Font; }
QFont headerFont() { return m_headerFont; }
void setHeaderLine ( bool show = false );
void setFooterLine ( bool show = false );
void setHeaderText ( const QString& text, QFont m_font = QFont(),
Qt::Alignment align = Qt::AlignHCenter );
void setFooterText ( const QString& text, QFont m_font = QFont(),
Qt::Alignment align = Qt::AlignHCenter );
void exportPdf ( const QString& pdf );
void print();
/**
* @brief exportImages Word导出为多个图纸.
*/
//内部有默认的大小和分辨率,根据这些获取目标Rect. 导出图片要用这个Rect.
//sceneRect / sceneDPI = targetRect / targetDPI 注释:DPI为logicDPI.
//可选输入: 桌面屏幕 96; DWIN屏 136,156; 打印机 1200; 其他 待测试;
//DPI保证了(屏幕)所见即(A4纸)所得
QRectF getTargetRectF ( qreal targetDPIX, qreal targetDPIY ) {
QRectF targetRect;
targetRect = QRectF ( 0.0, 0.0, targetDPIX * sceneRect.width() / logicalDpiX /*300*/,
targetDPIY * sceneRect.height() / logicalDpiY /*300*/ );
return targetRect;
}
//如果targetRect为空,那么按照SceneRect的大小,分辨率300DPI(内部默认)导出.
//虽然这里导出图片,但是通过图片可以导出PDF(QQtPrinter),可以显示(QQtWidget),
//相当于把pageScene按照确定比例投影到确定大小的画纸(幕布)上,是个列表,很多页.
//sceneRect dpi1 300
//imageRect dpi2 96
//printerPaperRect dpi3 1200
//确定比值相同. dpi 像素每英寸 像素 / 像素每英寸 = 英寸 如果是A4纸,那么一定是固定值咯.
void exportImage ( QList<QImage>& targetPapers , QRectF targetRect = QRectF() );
protected:
virtual void adjustdy ( qreal dy0 );
@ -99,11 +136,6 @@ signals:
public slots:
private:
/*
*
*/
QQtPrinter* pr;
/*
*
*/
@ -113,8 +145,8 @@ private:
/*
*
*/
int logicalDpiX;
int logicalDpiY;
qreal logicalDpiX;
qreal logicalDpiY;
QRectF sceneRect;
qreal xpos, xpos2, ypos, ypos2;
@ -175,6 +207,8 @@ private:
QHash<int, ESpanFlags> tableSpans ( const QTableView* table );
void initConstFont();
};
#endif // QQTWORD_H

View File

@ -1,5 +1,6 @@
#include "qqtprinter.h"
#include "stdlib.h"
#include <QImage>
#include <QPainter>
QQtPrinter::QQtPrinter ( QPrinter::PrinterMode mode ) :
QPrinter ( mode )
@ -15,6 +16,56 @@ QQtPrinter::QQtPrinter ( QPrinter::PrinterMode mode ) :
setPaperSize ( QPrinter::A4 );
setOrientation ( QPrinter::Portrait );
setOutputFormat ( QPrinter::PdfFormat );
#if 0
//setup printer
/**
MIPS bug: you must use QQtPrinter(QPrinter::HighResolution)
Other constructer won't work well
*/
pr = new QQtPrinter ( QPrinter::HighResolution );
pr->setFullPage ( true );
pr->setColorMode ( QPrinter::Color );
pr->setPaperSize ( QPrinter::A4 );
pr->setOrientation ( QPrinter::Portrait );
pr->setOutputFormat ( QPrinter::PdfFormat );
/*
* Font目标是打印纸上
* Pos目标不是纸上的DPI
* 使
* View 142,138 //PCView 96 //打印机View 1200
* 1200
* DrawText可用空间减小甚至切掉一部分
*/
#ifdef __EMBEDDED_LINUX__
/*
*
*/
logicalDpiX = 136;
logicalDpiY = 156;
#else
/*
*
*/
logicalDpiX = 96;
logicalDpiY = 96;
#endif
//1200 9917,14033 printerRect 固定
//116 958,1356 sceneRect
//142 1113,1660 sceneRect
pline() << pr->logicalDpiX() << pr->logicalDpiY();
pline() << logicalDpiX << logicalDpiY << pr->pageRect() << sceneRect;
pline() << pr->paperRect ( QPrinter::DevicePixel );
pline() << pr->paperRect ( QPrinter::Millimeter );
pline() << pr->paperRect ( QPrinter::Point );
pline() << pr->paperRect ( QPrinter::Inch );
pline() << pr->paperRect ( QPrinter::Pica );
pline() << pr->paperRect ( QPrinter::Didot );
pline() << pr->paperRect ( QPrinter::Cicero );
QRect rect = pr->paperRect();
sceneRect = QRectF ( 0.0, 0.0, logicalDpiX * rect.width() / pr->logicalDpiX(),
logicalDpiY * rect.height() / pr->logicalDpiY() );
#endif
}
void QQtPrinter::setOutputFileName ( const QString& name )
@ -23,12 +74,25 @@ void QQtPrinter::setOutputFileName ( const QString& name )
QPrinter::setOutputFileName ( m_outputname );
}
void QQtPrinter::generateToFile ( const QList<QImage>& imgs )
void QQtPrinter::generateToPdfFile ( const QList<QImage>& sourcePapers , QRectF sourceRect )
{
if ( sourceRect == QRectF() )
sourceRect = paperRect();
// print pdf
QPainter p ( this );
QListIterator<QImage> itor ( sourcePapers );
while ( itor.hasNext() )
{
const QImage& page = itor.next();
p.drawImage ( paperRect(), page, sourceRect );
if ( itor.hasNext() )
newPage();
}
}
void QQtPrinter::print()
void QQtPrinter::printPdf()
{
/*
*

View File

@ -12,11 +12,15 @@ public:
//输出到文件
void setOutputFileName ( const QString& );
//把QImage列表输出到上边的位置。QQtWord会输出这个list。
void generateToFile ( const QList<QImage>& imgs );
//把QImage列表输出(投影)到上边的位置。
//QQtWord会输出这个list。
//如果sourceRect为空,那么按照打印机的PaperRect,这说明sourcePaper使用了打印机的分辨率1200.
//只要纸张类型设置的正确,比如都是A4纸那样的长宽比,那么就不会失真.关键在长宽比和分辨率.
//分辨率决定是否失真. 长宽比决定是否变形.
void generateToPdfFile ( const QList<QImage>& sourcePapers, QRectF sourceRect = QRectF() );
//嵌入式系统里打印到打印机
void print();
void printPdf();
//输出到打印机
//内部实现

View File

@ -4,7 +4,7 @@
#include "qqtframe.h"
#include "qqtword.h"
#include "qqtcore.h"
#include "qqtprinter.h"
MainWindow::MainWindow ( QWidget* parent ) :
QMainWindow ( parent ),
@ -28,7 +28,10 @@ void MainWindow::on_pushButton_clicked()
return;
QQtWord word;
//所有对QQtWord的设置,做在这里.
word.initWord();
//work flow
word.setFooterText ( "Company T", word.headerFont(), Qt::AlignLeft );
word.setHeaderText ( "Company T Header", word.headerFont(), Qt::AlignLeft );
@ -36,6 +39,8 @@ void MainWindow::on_pushButton_clicked()
word.addText ( "Now, this is first section.", word.mainFont(), Qt::AlignLeft );
word.addText ( "Now, this is second section.", word.mainFont(), Qt::AlignLeft );
word.addText ( "Now, this is third section.", word.mainFont(), Qt::AlignLeft );
word.addText ( "Now, this is four section.", word.mainFont(), Qt::AlignLeft );
word.addText ( "八荣八耻", word.title2Font(), Qt::AlignLeft );
word.addText ( "以热爱祖国为荣、以危害祖国为耻。" );
@ -61,10 +66,19 @@ void MainWindow::on_pushButton_clicked()
tableWidget.query ( "" );
tableWidget.horizontalHeader()->setSectionResizeMode ( QQtHeaderView::ResizeToContents );
tableWidget.setFixedWidth ( 523.8 );
pline() << word.clientRectF();
pline() << word.clientRectF() << word.paperRect();
word.addTable ( &tableWidget );
word.addSignoffText ( "Reporter: Tianduanrui" );
word.exportPdf ( ui->lineEdit->text() );
QList<QImage> papers;
//分辨率可以随意一点.一般用于显示器正常显示,为96.
QRectF paperRect = word.getTargetRectF ( 300, 300 );
word.exportImage ( papers, paperRect );
pline() << papers;
QQtPrinter printer;
pline() << printer.logicalDpiX() << printer.logicalDpiY();
printer.setOutputFileName ( ui->lineEdit->text() );
printer.generateToPdfFile ( papers, paperRect );
}