qt实现打印机功能

1.头文件

复制代码
#pragma once
#ifndef __PRINTERMANAGER_H__
#define __PRINTERMANAGER_H__


#include <QObject>
#include <QString>
#include <QImage>
#include <QRect>
#include <QPrinter>
#include <QPainter>
#include <functional>
#include <QPixmap>

class PrinterManager : public QObject
{
    Q_OBJECT

public:

//单例
    static PrinterManager* instance();

//打印接口
    Q_INVOKABLE bool printImage(const QImage& magePath,bool showDialog = true);
    Q_INVOKABLE bool printPixmap(const QPixmap& pixmap,bool showDialog = true);

private:
      
    explicit PrinterManager(QObject* parent = nullptr);
//操作函数
    bool executePrint(std::function<void(QPainter&)> paintFunction,bool showDialog);
//计算rect(起始位置和长宽)
    QRect calculateImageRect(const QImage& image,const QRect& pageRect);
    
private:
    static PrinterManager* m_instance;
};
#endif

2.cpp文件

复制代码
#include "Printer/printerManager.h"
#include <QPrintDialog>
#include <QDebug>

PrinterManager* PrinterManager::m_instance = nullptr;

PrinterManager* PrinterManager::instance()
{
    if(!m_instance)
    {
        m_instance = new PrinterManager();
    }
    return m_instance;
}

PrinterManager::PrinterManager(QObject* parent) : QObject(parent)
{
    qDebug()<<"打印机管理器初始化完成";
}

bool PrinterManager::printPixmap(const QPixmap& pixmap,bool showDialog)
{
    if(pixmap.isNull())
    {
        qWarning()<<"pixmap为空";
        return false;
    }
    QImage image = pixmap.toImage();

   printImage(image,showDialog);
}

bool PrinterManager::printImage(const QImage& image,bool showDialog)
{
    if(image.isNull())
    {
        qWarning()<<"待打印图片为空";
        return false;
    }

    return executePrint([this,&image](QPainter& painter){
        QRect pageRect = painter.viewport();
        QRect targetRect = calculateImageRect(image,pageRect);
        painter.drawImage(targetRect,image);
    },showDialog);
}

bool PrinterManager::executePrint(std::function<void(QPainter&)> paintFunction,bool showDialog)
{
    QPrinter printer;
    if(showDialog)
    {
        QPrintDialog dialog(&printer);
        if(dialog.exec() != QDialog::Accepted)
        {
            qDebug()<<"用户取消打印";
            return false;
        }
    }

    QPainter painter;
    if(!painter.begin(&printer))
    {
        qWarning()<<"无法启动打印机绘图";
        return false;
    }

    try
    {
        paintFunction(painter);
        painter.end();
        qDebug()<<"打印完成";
        return true;
    }
    catch(const std::exception& e)
    {
        painter.end();
        qCritical()<<"打印过程中发生错误";
        return false;
    }
}

QRect PrinterManager::calculateImageRect(const QImage& image,const QRect& pageRect)
{
    QSize imageSize = image.size();
    imageSize.scale(pageRect.size(),Qt::KeepAspectRatio);
    int x = pageRect.x()+(pageRect.width() - imageSize.width())/2;
    int y = pageRect.y()+(pageRect.height()-imageSize.height())/2;
    return QRect(x,y,imageSize.width(),imageSize.height());
}
相关推荐
九转成圣8 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
SmartRadio8 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
laowangpython8 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
我叫汪枫8 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch8 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI8 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_0018 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
念2348 小时前
f5 shape分析
开发语言·javascript·ecmascript
苍穹之跃8 小时前
某量JS逆向
开发语言·javascript·ecmascript
思茂信息8 小时前
CST软件如何进行参数化扫描?
运维·开发语言·javascript·windows·ecmascript·软件工程·软件需求