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());
}
相关推荐
用户805533698036 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner6 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz11 天前
QML Hello World 入门示例
qt
xcyxiner14 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner14 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner15 天前
DicomViewer (添加模型类)3
qt
xcyxiner15 天前
DicomViewer (目录调整) 2
qt
xcyxiner16 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00617 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术17 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript