1、普通打印图片,例如
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
image.load("flower.jpg");//导入图片
}
void MainWindow::printImage()
{
QPrinter printer(QPrinter::HighResolution);
QPrintDialog printDialog(&printer,this);
if(printDialog.exec())
{
QPainter painter(&printer);
QRect rect=painter.viewport();
QSize size=image.size();
size.scale(rect.size(),Qt::KeepAspectRatio);//保证图片显示完整,当源区域和目标区域大小不同时,源区域将会按指定的内容缩放以符合目标区域,缩放比例取决于Qt::AspectRatioMode
painter.setViewport(rect.x(),rect.y(),size.width(),size.height());
painter.setWindow(image.rect());
painter.drawImage(0,0,image);//绘制图片
}
}
2、抓取窗口并打印,例如
PrintImage::PrintImage(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
labImage = new QLabel(this);
labImage->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
labImage->setScaledContents(true);
setCentralWidget(labImage);
if(image.load("background.png"))
{
labImage->setPixmap(QPixmap::fromImage(image));//窗口显示图片
resize(image.width(),image.height());
}
}
void PrintImage::print()
{
QPrinter printer;
QPrintDialog printDlg(&printer,this);
if(printDlg.exec())
{
QPainter painter(&printer);
QRect rect = painter.viewport();
QSize size = image.size();
size.scale(rect.size(),Qt::KeepAspectRatio);
painter.setViewport(rect.x(),rect.y(),size.width(),size.height());
painter.setWindow(image.rect());
painter.drawPixmap(0,0,QPixmap::grabWidget(this,this->rect()));//抓取窗口
}
}
3、打印前预览,例如
void Widget::preView()
{
QPrinter printer(QPrinter::HighResolution);
QPrintPreviewDialog preview(&printer,0);
connect(&preview, SIGNAL(paintRequested(QPrinter *)),this,SLOT(print(QPrinter *)));//<span style="font-family: Arial, Helvetica, sans-serif;">print(QPrinter *)函数自己实现</span>
preview.exec();//等待预览界面退出,预览界面含有打印功能
}
4、打印特殊窗口部件,例如Graphics View框架
Graphics View框架通过场景的QGraphicsScene::render()函数和视图的QGraphicsView::render()函数均可以完成打印。这两个函数的差别在于坐标不同。GraphicsScene::render()函数通常用来绘制没有变换的场景,如几何函数、文本文档。QGraphicsView::render()函数用来实现屏幕快照,它默认的行为是将视口的数据绘制到指定的绘图设备。
void MainWindow::print()
{
QPrinter printer;
if (QPrintDialog(&printer).exec() == QDialog::Accepted) {
QPainter painter(&printer);
painter.setRenderHint(QPainter::Antialiasing);
view->render(&painter);//打印视图
//scene->render(&painter);//打印场景
}
}
其他典型窗口部件的打印函数
QSvgWidget----------------------QSvgRenderer::render()
QTextEdit ----------------------QTextDocument::print()
QTextLayout----------------------QTextLayout::draw()
QTextLine ----------------------QTextLine::draw()
5、打印文本,例如
void MainWindow::print(const QString &strHtml,const QString &strPdfFile, int iFormat = 1)
{
// strHtml是HTML格式的打印内容,strPdfFile是PDF文件路径
QString strPdfFile("./document1.pdf");//最终pdf上显示的可能是乱码
QPrinter printer;
QTextDocument doc;
doc.setHtml(strHtml);
if (iFormat == 1)
{
printer.setPageSize(QPrinter::A4);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(strPdfFile);
doc.print(&printer);
}
else
{
doc.setPageSize(QSizeF(printer.logicalDpiX()*(80/25.4),printer.logicalDpiY()*(297/25.4)));
printer.setOutputFormat(QPrinter::NativeFormat);
doc.print(&printer);
}
}
6、打印表格,例如(此处参考了http://blog.csdn.net/prochsh/article/details/5529944)
void QCurveQueryTool::printTable(QPrinter *printer)
{
QString title = QString("曲线打印");
printTableWidget(table,title,printer);
}
void QCurveQueryTool::printTableWidget(const QTableWidget* view,QString stitile,QPrinter *printer) //printFlag =1,打印表格
{
double totalWidth = 0.0;
double totalHeight = 0.0;
double totalPageHeight=0.0;
int rows = view->model()->rowCount(); //行总数
const int cols = view->model()->columnCount(); //列总数
for (int c = 0; c < cols; ++c) //求出列宽
{
totalWidth += view->columnWidth(c);
}
for (int r = 0; r < rows; ++r) //求出行宽
{
totalHeight += view->rowHeight(r);
}
QPainter painter(printer);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
painter.begin(printer);
QRect area = printer->paperRect();// paperRect();
QVector<int> startRow;
QVector<int> endRow;
int iCount = 0;
qreal left,top,right,bottom;
printer->getPageMargins(&left,&top,&right,&bottom,QPrinter::Point);
cout << "left = " << left << ", right = " << right << ", top = " << top << ", bottom = " << bottom << endl;
area.setHeight( int(area.height() - top - bottom) );
area.setWidth( int(area.width() - left - right) );
for (int p=0; p < rows; p++) //rows中保存了所有的行数 , 找出每次打印的开始行和结束行
{
totalPageHeight += view->rowHeight(p); //求出所有的列高度
int pageFooter = 50 ; //页脚的高度
int pageHeader = 50; //页眉的高度
if (startRow.size() == 0)
{
pageFooter = 50 ;
pageHeader = 500;
}
if ((totalPageHeight >= (area.height() - pageFooter - pageHeader)) || (p == rows -1)) //如果目前累加列的高度大于或者等于可用页面高度 || 到达最后一行
{
totalPageHeight = view->rowHeight(p);
if (p == rows -1)
{
if (p - iCount - 2 < 0)
{
startRow.push_back(0);
}
else
{
startRow.push_back(p - iCount - 2);
}
endRow.push_back(p);
//cout << startRow.at(startRow.size() - 1) << " " << endRow.at(endRow.size() - 1) << endl;
}
else
{
if (p - iCount - 2 < 0)
{
startRow.push_back(0);
endRow.push_back(p - 2);
}
else
{
startRow.push_back(p - iCount - 1);
endRow.push_back(p - 3);
}
//cout << startRow.at(startRow.size() - 1) << " " << endRow.at(endRow.size() - 1) << endl;
}
iCount = 0;
}
iCount++;
}
QTableWidget *printTable = new QTableWidget();
//printTable->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
//printTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
//printTable->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
//printTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
const double xscale = area.width() / totalWidth;
const double yscale = area.height() / totalHeight;
//const double pscale = area.height() / totalPageHeight;
//painter.scale(xscale , yscale); // With the scaling 3 It is Printing all
//painter.translate(area.x() + xscale, area.y() + pscale); //This is original
painter.translate(area.x() + xscale, area.y() + yscale);
//painter.save(); //commented
//int y=0 ;// This is introduced for the columns
//view->paintEvent(&event);
//QPainter paint(this);
//paint.setPen(Qt::red);
//paint.drawRect(0, 0, 0, 0);
QStyleOptionViewItem option;
QPen pen;
pen.setColor(Qt::black);
pen.setWidth(1);
painter.setPen(pen);
int irowcount = -1;
float rate = 1;
for(int ipage = 0; ipage < startRow.size();ipage++) //startRow有大,就有多少页需要打印
{
printTable->setColumnCount(view->columnCount() + 1); //打印的列数为view的列数
printTable->setRowCount(endRow[ipage] - startRow[ipage] + 2); //设置当前打印页的行数
for(int c = 1;c < cols + 1;c++)
{
printTable->setColumnWidth( c,(view->columnWidth(c - 1)) );
QTableWidgetItem *newItem = printTable->item(0,c);
if (!newItem) //如果printTable的首行不存在,添加文字或者序号
{
if (view->horizontalHeaderItem(c - 1)) //Returns the horizontal(水平的) header item for column
newItem = new QTableWidgetItem(view->horizontalHeaderItem(c - 1)->text());
else
newItem = new QTableWidgetItem(QString::number(c));
printTable->setItem(0,c ,newItem);
}
else //否则,直接设置文字或者序号
{
if (view->horizontalHeaderItem(c - 1))
newItem->setText(view->horizontalHeaderItem(c - 1)->text());
else
newItem->setText(QString::number(c));
}
}
/求出合适的比率,用来完美表格的显示
QRect firstTable , lastTable;
QModelIndex firstIndex = printTable->model()->index(0,0);
QModelIndex lastIndex = printTable->model()->index(0,cols);
firstTable = printTable->visualRect(firstIndex);
lastTable = printTable->visualRect(lastIndex);
float totalTableWidth = lastTable.topRight().x() - firstTable.topLeft().x();
float pagerWidth = printer->paperRect().width() - 20 - 20;
rate = totalTableWidth/pagerWidth;
cout << "totalTableWidth = " << totalTableWidth << ", pagerWidth = " << pagerWidth << ", rate = " << rate << endl;
/求出合适的比率,用来完美表格的显示
for(int c = 1;c < cols + 1;c++) //重设宽度
{
printTable->setColumnWidth( c,int((view->columnWidth(c - 1))/rate) );
}
printTable->setColumnWidth(0,view->verticalHeader()->width()); //Returns the table view's vertical header.
int iRow = 0;
for(int ir = startRow[ipage]; ir <= endRow[ipage];ir++) //ir变量用来标识当前打印的是哪些行,设置当前打印页的首行
{
printTable->setRowHeight(iRow,view->rowHeight(ir)); //Sets the height of the given row to be height.
for(int ic = 0; ic < view->columnCount(); ic++) //设置每个单元格的内容
{
QTableWidgetItem *newItem = printTable->item(iRow + 1,ic + 1);
if (!newItem)
{
if (view->item(ir,ic))
newItem = new QTableWidgetItem(view->item(ir,ic)->text());
else
newItem = new QTableWidgetItem("");
printTable->setItem(iRow + 1,ic + 1,newItem);
}
else
{
if (view->item(ir,ic))
newItem->setText(view->item(ir,ic)->text());
else
newItem->setText("");
}
}
iRow++;
}
qreal ioffx = (area.width() - totalWidth)/2;
qreal ioffy = 50;
if (ipage == 0)
{
ioffy = 500;
QwtPlotPrintFilter filter;
int options = QwtPlotPrintFilter::PrintAll;
options &= ~QwtPlotPrintFilter::PrintBackground;
options |= QwtPlotPrintFilter::PrintFrameWithScales;
filter.setOptions(options);
d_plot->print(&painter,QRect(50,65,650,400),filter);
}
rows = printTable->rowCount();
iRow = 1;
for(int ir = startRow[ipage] ; ir <= endRow[ipage] ; ir++) //ir变量用来标识当前打印的是哪些行,设置当前打印页的首列序号
{
QTableWidgetItem *newItem = printTable->item(iRow,0);
if (!newItem)
{
if (view->verticalHeaderItem(ir))
newItem = new QTableWidgetItem(view->verticalHeaderItem(ir)->text());
else
newItem = new QTableWidgetItem(QString::number(iRow));
printTable->setItem(iRow,0,newItem);
}
else
{
if (view->verticalHeaderItem(ir))
newItem->setText(view->verticalHeaderItem(ir)->text());
else
newItem->setText(QString::number(iRow));
}
iRow ++;
}
QPointF offPt(20,ioffy); //20表示边框的空格
for (int r = 0; r < rows; r++)
{
QRect rt1,rt2;
QModelIndex idx1 = printTable->model()->index(r,0);
QModelIndex idx2 = printTable->model()->index(r,cols);
rt1 = printTable->visualRect(idx1);
rt2 = printTable->visualRect(idx2);
painter.drawLine( (rt1.bottomLeft() + offPt) , (rt2.bottomRight() + offPt) );
if (r == 0)
{
painter.drawLine( (rt1.topLeft() + offPt) , (rt2.topRight() + offPt) );
}
}
for (int c = 0; c < cols + 1; c++)
{
QRect rt1,rt2;
QModelIndex idx1 = printTable->model()->index(0,c);
QModelIndex idx2 = printTable->model()->index(rows - 1,c);
rt1 = printTable->visualRect(idx1);
rt2 = printTable->visualRect(idx2);
painter.drawLine( (rt1.topLeft() + offPt) , (rt2.bottomLeft() + offPt) );
if (c == cols)
{
painter.drawLine( (rt1.topRight() + offPt) , (rt2.bottomRight() + offPt) );
}
}
for (int r = 0; r < rows; r++)
{
irowcount ++;
for(int c = 0; c < cols + 1; c++)
{
QModelIndex idx = printTable->model()->index(r,c);
option.rect = printTable->visualRect(idx);
if (printTable->item(r,c))
{
QRectF rt(option.rect.left() + 3,option.rect.top(),option.rect.width(),option.rect.height());
rt = rt.translated(offPt);
if (r != 0 && c == 0)
{
painter.drawText(rt,Qt::AlignCenter,QString("%1").arg(irowcount));
}
else
{
if (r == 0)
{
painter.drawText(rt,Qt::AlignCenter,printTable->item(r,c)->text());
}
else
{
painter.drawText(rt,Qt::AlignVCenter,printTable->item(r,c)->text());
}
}
}
}
}
//ipage
if (ipage == 0) //设置标题
{
QRectF rttt(area.left(),area.top(),area.width(),50);
painter.drawText(rttt,Qt::AlignCenter,stitile);
}
QRectF rttt(area.left(),area.bottom() - 65,area.width(),25);
painter.drawText(rttt,Qt::AlignCenter,QString::number(ipage + 1));
if (ipage < startRow.size() - 1)
{
printer->newPage();
irowcount--;
}
}
painter.end();
}