Qt做多了没有人逃得过打印模板这个功能,有的话只是时候未到,注释都在代码里了,直接上代码了
1、获取打印机的名称
if(index == 1)
{
QPrinterInfo info;
QStringList list = info.availablePrinterNames(); // 所有打印机名字
ui->cB_print->clear();
ui->cB_print->setEnabled(true);
foreach (QString str, list) {
ui->cB_print->addItem(str);
}
}
else
{
QPrinterInfo info;
QString name = info.defaultPrinterName(); // 默认打印机名字
ui->cB_print->clear();
ui->cB_print->setEnabled(false);
ui->cB_print->addItem(name);
}
2、预览
QPrinter printer(QPrinter::HighResolution);
//自定义纸张大小,特别重要,不然预览效果极差
printer.setPageSize(QPrinter::Custom);
printer.setPaperSize(QSizeF(600, 800),
QPrinter::Point);
QPrintPreviewDialog preview(&printer, this);// 创建打印预览对话框
preview.setMinimumSize(1000,600);
/*
* QPrintPreviewDialog类提供了一个打印预览对话框,里面功能比较全,
* paintRequested(QPrinter *printer)是系统提供的,
* 当preview.exec()执行时该信号被触发,
* drawPic(QPrinter *printer)是自定义的槽函数,图像的绘制就在这个函数里。
*/
connect(&preview, SIGNAL(paintRequested(QPrinter*)), SLOT(drawPic(QPrinter*)));
preview.exec();
然后drawPic定义:
//在预览窗口显示图片
void MainWindow::drawPic(QPrinter *printerPixmap)
{
QPixmap pix = QPixmap(800,600);
//这个函数算是画模板的函数吧,毕竟打印时有模板的
createPix(&pix);
pix.save(sFilePix);
//纵向:Portrait 横向:Landscape
printerPixmap->setOrientation(QPrinter::Landscape);
//获取界面的图片
QPainter painterPixmap(this);
painterPixmap.begin(printerPixmap);
QRect rect = painterPixmap.viewport();
int x = rect.width() / pix.width();
int y = rect.height() / pix.height();
//设置图像长宽是原图的多少倍
painterPixmap.scale(x, y);
painterPixmap.drawPixmap(0, 0, pix);
painterPixmap.end();
}
void MainWindow::createPix(QPixmap *pix)
{
QPainter *painter = new QPainter(this);
painter->begin(pix);
painter->setRenderHint(QPainter::Antialiasing, true);
// 设置画笔颜色、宽度
painter->setPen(QPen(QColor(255, 255, 255), 2));
// 设置画刷颜色
painter->setBrush(QColor(255, 255, 255));
QRect rect(0,0,800,600);
//整张图设置画刷白底
painter->fillRect(rect,QColor(255, 255, 255));
painter->drawRect(rect);
//画数据部分的线条
painter->setPen(QPen(QColor(0, 0, 0), 1));
QVector lines;
lines.append(QLine(QPoint(50,50),QPoint(750,50)));//上边
lines.append(QLine(QPoint(750,50),QPoint(750,550)));//右边
lines.append(QLine(QPoint(50,550),QPoint(750,550)));//下边
lines.append(QLine(QPoint(50,50),QPoint(50,550)));//左边
lines.append(QLine(QPoint(50,120),QPoint(750,120)));//名称下边
lines.append(QLine(QPoint(50,180),QPoint(750,180)));//信息下边
lines.append(QLine(QPoint(50,200),QPoint(750,200)));//条目下边
lines.append(QLine(QPoint(50,490),QPoint(750,490)));//数据下边
lines.append(QLine(QPoint(120,180),QPoint(120,200)));//类型分割边
lines.append(QLine(QPoint(190,180),QPoint(190,200)));//类型分割边
lines.append(QLine(QPoint(260,180),QPoint(260,200)));//类型分割边
lines.append(QLine(QPoint(330,180),QPoint(330,200)));//类型分割边
lines.append(QLine(QPoint(400,180),QPoint(400,490)));//结果和曲线分割边
painter->drawLines(lines);
QFont font;
font.setPointSize(13);
font.setFamily("黑体");
font.setItalic(true);
painter->setFont(font);
//第一部分
painter->drawText(50,50,700,40,Qt::AlignCenter,ui->lE_unit->text());//单位名称
painter->drawText(QPoint(650,110),"No:");
font.setPointSize(20);
painter->setFont(font);
painter->drawText(50,80,700,40,Qt::AlignCenter,ui->lE_report->text());//报告名称
font.setPointSize(10);
painter->setFont(font);
//第二部分
painter->drawText(50,120,700,60,Qt::AlignVCenter,QString("样本ID: ")+QString("11111111"));
painter->drawText(210,120,700,60,Qt::AlignVCenter,QString("标本类型: ")+QString("ABC"));
painter->drawText(370,120,700,60,Qt::AlignVCenter,QString("检测方法: ")+ui->lE_means->text());
painter->drawText(600,120,700,60,Qt::AlignVCenter,QString("仪器: ")+ui->lE_instrument->text());
//第三部分
painter->drawText(50,180,70,20,Qt::AlignCenter,"序号");
painter->drawText(120,180,70,20,Qt::AlignCenter,"检测项目");
painter->drawText(190,180,70,20,Qt::AlignCenter,"Ct");
painter->drawText(260,180,70,20,Qt::AlignCenter,"检测下限");
painter->drawText(330,180,70,20,Qt::AlignCenter,"结果");
//第四部分
painter->drawText(50,210,70,20,Qt::AlignCenter,"1");
painter->drawText(120,210,70,20,Qt::AlignCenter,"我");
painter->drawText(190,210,70,20,Qt::AlignCenter,"真的");
painter->drawText(260,210,70,20,Qt::AlignCenter,"不知道");
painter->drawText(330,210,70,20,Qt::AlignCenter,"写啥");
//第五部分
painter->drawText(50,490,700,30,Qt::AlignVCenter,QString("送检者: ")+ui->lE_inspect->text());
painter->drawText(230,490,700,30,Qt::AlignVCenter,QString("代码: ")+ui->lE_code->text());
painter->drawText(410,490,700,30,Qt::AlignVCenter,QString("检验者: ")+ui->lE_detection->text());
painter->drawText(590,490,700,30,Qt::AlignVCenter,QString("审核者: ")+ui->lE_audit->text());
painter->drawText(50,520,700,30,Qt::AlignVCenter,QString("送检日期: ")+ui->lE_inspectDate->text());
painter->drawText(410,520,700,30,Qt::AlignVCenter,QString("报告日期: ")+ui->lE_reportDate->text());
painter->end();
}
3、打印
this->close();
//将文件保存
writeFile();
// 创建打印机对象
QPrinter printerPixmap;
QPixmap pix = QPixmap(800,600);
//将生成图片并保存,保不保存无所谓
createPix(&pix);
pix.save(sFilePix);
//纵向:Portrait 横向:Landscape
printerPixmap.setOrientation(QPrinter::Landscape);
//设置纸张大小
printerPixmap.setPageSize(QPrinter::A4);
QPainter painterPixmap;
//选取打印机,特别重要
printerPixmap.setPrinterName(ui->cB_print->currentText());
//开始打印
painterPixmap.begin(&printerPixmap);
//设置图像在A4中的开始坐标是什么
painterPixmap.drawPixmap(0, 0 , pix);
painterPixmap.end();
/*
* QPrintDialog print(&printerPixmap, this);
* 这个是点击会会出现弹框的打印,太low放弃
* 用法:
* QPrintDialog print(&printerPixmap, this);
* if (print.exec())
{
QPainter painterPixmap;
painterPixmap.begin(&printerPixmap);
QRect rect = painterPixmap.viewport();
int x = rect.width() / pixmap.width();
int y = rect.height() / pixmap.height();
painterPixmap.scale(x, y);
painterPixmap.drawPixmap(0, 0, pixmap);
painterPixmap.end();
}
*/
程序界面:
预览效果:
20210203追加,解决打印字体模糊,不清晰,失真效果:
我后来发现,打印的字体和图片总是有类似锯齿一样的,字体不清晰,后面放大了字体后发现,打印的情况类似于点阵,所以打印的效果总是不好,如图所示:
于是改进后:
具体做法:
将原本的
painterPixmap.drawPixmap(0, 0 , pix);
改为createPix函数内容即可,就是不用添加了中间步骤创建pix,直接打印出最后的界面结果
这里其实也是可以直接打印的,但是太low了,不想用
有需要的也可以下载:printTemplate.zip-QT代码类资源-CSDN下载
最近有人问我怎么模糊的改动怎么改,我今天才看到于是就上来更新了一下,不过我没有测试,只是按照之前写的把改动的写了上去
void MainWindow::drawPic(QPrinter *printerPixmap)
{
QPixmap pix = QPixmap(800,600);
//这个函数算是画模板的函数吧,毕竟打印时有模板的
//纵向:Portrait 横向:Landscape
printerPixmap->setOrientation(QPrinter::Landscape);
//获取界面的图片
QPainter painterPixmap(this);
painterPixmap.begin(printerPixmap);
QRect rect = painterPixmap.viewport();
int x = rect.width() / pix.width();
int y = rect.height() / pix.height();
//设置图像长宽是原图的多少倍
painterPixmap.scale(x, y);
//20211229添加
createPix(&pix,&painterPixmap);
painterPixmap.drawPixmap(0, 0, pix);
painterPixmap.end();
}
void MainWindow::createPix(QPixmap *pix,QPainter *in_paint)
{
//20211229添加
QPainter *painter = nullptr;
if(in_paint == nullptr){
painter = new QPainter(this);
painter->begin(pix);
}else{
painter = paint;
}
painter->begin(pix);
painter->setRenderHint(QPainter::Antialiasing, true);
// 设置画笔颜色、宽度
painter->setPen(QPen(QColor(255, 255, 255), 2));
// 设置画刷颜色
painter->setBrush(QColor(255, 255, 255));
QRect rect(0,0,800,600);
//整张图设置画刷白底
painter->fillRect(rect,QColor(255, 255, 255));
painter->drawRect(rect);
//画数据部分的线条
painter->setPen(QPen(QColor(0, 0, 0), 1));
QVector lines;
lines.append(QLine(QPoint(50,50),QPoint(750,50)));//上边
lines.append(QLine(QPoint(750,50),QPoint(750,550)));//右边
lines.append(QLine(QPoint(50,550),QPoint(750,550)));//下边
lines.append(QLine(QPoint(50,50),QPoint(50,550)));//左边
lines.append(QLine(QPoint(50,120),QPoint(750,120)));//名称下边
lines.append(QLine(QPoint(50,180),QPoint(750,180)));//信息下边
lines.append(QLine(QPoint(50,200),QPoint(750,200)));//条目下边
lines.append(QLine(QPoint(50,490),QPoint(750,490)));//数据下边
lines.append(QLine(QPoint(120,180),QPoint(120,200)));//类型分割边
lines.append(QLine(QPoint(190,180),QPoint(190,200)));//类型分割边
lines.append(QLine(QPoint(260,180),QPoint(260,200)));//类型分割边
lines.append(QLine(QPoint(330,180),QPoint(330,200)));//类型分割边
lines.append(QLine(QPoint(400,180),QPoint(400,490)));//结果和曲线分割边
painter->drawLines(lines);
QFont font;
font.setPointSize(13);
font.setFamily("黑体");
font.setItalic(true);
painter->setFont(font);
//第一部分
painter->drawText(50,50,700,40,Qt::AlignCenter,ui->lE_unit->text());//单位名称
painter->drawText(QPoint(650,110),"No:");
font.setPointSize(20);
painter->setFont(font);
painter->drawText(50,80,700,40,Qt::AlignCenter,ui->lE_report->text());//报告名称
font.setPointSize(10);
painter->setFont(font);
//第二部分
painter->drawText(50,120,700,60,Qt::AlignVCenter,QString("样本ID: ")+QString("11111111"));
painter->drawText(210,120,700,60,Qt::AlignVCenter,QString("标本类型: ")+QString("ABC"));
painter->drawText(370,120,700,60,Qt::AlignVCenter,QString("检测方法: ")+ui->lE_means->text());
painter->drawText(600,120,700,60,Qt::AlignVCenter,QString("仪器: ")+ui->lE_instrument->text());
//第三部分
painter->drawText(50,180,70,20,Qt::AlignCenter,"序号");
painter->drawText(120,180,70,20,Qt::AlignCenter,"检测项目");
painter->drawText(190,180,70,20,Qt::AlignCenter,"Ct");
painter->drawText(260,180,70,20,Qt::AlignCenter,"检测下限");
painter->drawText(330,180,70,20,Qt::AlignCenter,"结果");
//第四部分
painter->drawText(50,210,70,20,Qt::AlignCenter,"1");
painter->drawText(120,210,70,20,Qt::AlignCenter,"我");
painter->drawText(190,210,70,20,Qt::AlignCenter,"真的");
painter->drawText(260,210,70,20,Qt::AlignCenter,"不知道");
painter->drawText(330,210,70,20,Qt::AlignCenter,"写啥");
//第五部分
painter->drawText(50,490,700,30,Qt::AlignVCenter,QString("送检者: ")+ui->lE_inspect->text());
painter->drawText(230,490,700,30,Qt::AlignVCenter,QString("代码: ")+ui->lE_code->text());
painter->drawText(410,490,700,30,Qt::AlignVCenter,QString("检验者: ")+ui->lE_detection->text());
painter->drawText(590,490,700,30,Qt::AlignVCenter,QString("审核者: ")+ui->lE_audit->text());
painter->drawText(50,520,700,30,Qt::AlignVCenter,QString("送检日期: ")+ui->lE_inspectDate->text());
painter->drawText(410,520,700,30,Qt::AlignVCenter,QString("报告日期: ")+ui->lE_reportDate->text());
//20211229添加
if(in_paint == nullptr){
painter->end();
}
}
改动的点已经备注了:20211229添加
其实还是那句,本来是生成图片后再打印,这样你打印的是图片,你们可以保存这张图片看看,本身就已经糊了打印的怎么可能不是糊了的,所以就不中间生成图片打印,可能这个效果不是我上面的效果,因为这个是我从上面拷贝下来直接修改的,但是思路就是这样