Qt之打印功能

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();
        }
    */

程序界面:

Qt之打印功能_第1张图片

预览效果:

Qt之打印功能_第2张图片

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添加

其实还是那句,本来是生成图片后再打印,这样你打印的是图片,你们可以保存这张图片看看,本身就已经糊了打印的怎么可能不是糊了的,所以就不中间生成图片打印,可能这个效果不是我上面的效果,因为这个是我从上面拷贝下来直接修改的,但是思路就是这样

你可能感兴趣的:(Qt,qt,开发语言)