即使Qt的文档声明它的打印API可以在所有平台上工作, Qt print support,它似乎并不适用于iOS。相反,看起来你需要去UIPrintInteractionController解决方案。这很容易做到。让我给你一个简单的例子。让我假设你选择Qt的,因为你希望你的应用程序是便携式的,并且你有一个专门的类PrinterManager来处理打印在你的框架:
// this is PrinterManager.hpp
class PrinterManagerImpl;
class PrinterManager : public QObject
{
Q_OBJECT
public:
PrinterManager(QObject* a_Parent = Q_NULLPTR);
virtual ~PrinterManager();
Q_INVOKABLE void setupPrinter();
Q_INVOKABLE void print(const QString& a_PathToImg) const;
private:
Q_DISABLE_COPY(PrinterManager)
private:
std::unique_ptr<PrinterManagerImpl> m_Impl;
};
与以下实现沿:
// this is PrinterManager.cpp
#include "PrinterManager.hpp"
#include "PrinterManagerImpl.hpp"
#ifndef Q_OS_IOS
PrinterManager::PrinterManager(QObject* a_Parent)
: QObject(a_Parent)
, m_Impl(new MyStandardPrinterManagerImpl) // implementation for any case except iOS
{ }
#endif
PrinterManager::~PrinterManager()
{ }
void PrinterManager::setupPrinter()
{
m_Impl->setupPrinter();
}
void PrinterManager::print(const QString& a_PathToImg) const
{
m_Impl->print(a_PathToImg);
}
像这样指定,PrinterManager可以很容易地在QML中使用。
整个诀窍在于用PIMPL语言编写PrinterManager,即将类实现封装在成员m_Impl中。然后,基于您编译代码的平台,您将提供任何PrinterManagerImpl是必需的。
随着上述PrinterManager实现(CPP文件),您需要定义以下毫米文件(目标C++代码),其中包含了IOS-具体实施PrinterManager的构造:
// this is PrinterManager.mm
#import "PrinterManager.hpp"
#import "IosPrinterManagerImpl.hpp"
PrinterManager::PrinterManager(QObject* a_Parent)
: QObject(a_Parent)
, m_Impl(new IosPrinterManagerImpl()) // special iOS implementation
{ }
当你编译这个代码,考虑mm和cpp文件(如果你按照你的项目的.pro文件下面的建议)。当你为iOS编译它时,在cpp文件中找不到构造函数实现。可以在我们定义IosPrinterManagerImpl的mm文件中找到实现。让我们来看看PrinterManagerImpl:
// this is PrinterManagerImpl.hpp
class PrinterManagerImpl
{
public:
PrinterManagerImpl() { }
virtual ~PrinterManagerImpl() { }
virtual void setupPrinter() = 0;
virtual void print(const QString& a_PathToImg) const = 0;
private:
Q_DISABLE_COPY(PrinterManagerImpl)
};
的IosPrinterManagerImpl看起来像这样(从this video末this advice启发):
// IosPrinterManagerImpl.hpp
#import "PrinterManagerImpl.hpp"
#import <UIKit/UIPrinter.h>
class QWidget;
class IosPrinterManagerImpl : public PrinterManagerImpl
{
public:
IosPrinterManagerImpl();
virtual ~IosPrinterManagerImpl();
virtual void setupPrinter() override;
virtual void print(const QString& a_PathToImg) const override;
private:
UIPrinter* m_Printer;
QWidget* m_Dialog;
};
它的实施是
// IosPrinterManagerImpl.mm
#import "IosPrinterManagerImpl.hpp"
#import <QApplication>
#import <QWidget>
#import <QWindow>
#import <UIKit/UIPrinterPickerController.h>
#import <UIKit/UIPrintInteractionController.h>
#import <UIKit/UIPrintInfo.h>
IosPrinterManagerImpl::IosPrinterManagerImpl()
: PrinterManagerImpl()
, m_Dialog(new QWidget(QApplication::activeWindow()))
{
m_Dialog->setGeometry(0, 0, 100, 100);
}
IosPrinterManagerImpl::~IosPrinterManagerImpl()
{ }
void IosPrinterManagerImpl::setupPrinter()
{
// this displays an UI where you can select the printer you want from your local network
auto picker = [UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:m_Printer];
if(auto view = reinterpret_cast<UIView*>(m_Dialog->window()->winId()))
{
[picker presentFromRect:view.bounds inView:view animated:YES
completionHandler:^(UIPrinterPickerController* controller, BOOL userDidSelect, NSError* /*err*/)
{
if(userDidSelect)
{
m_Printer = controller.selectedPrinter;
}
}
];
}
}
void IosPrinterManagerImpl::print(const QString& a_PathToImg) const
{
auto printInfo([UIPrintInfo printInfo]);
printInfo.jobName = @"Test";
printInfo.outputType = UIPrintInfoOutputPhoto;
auto imgUrl([NSURL fileURLWithPath:a_PathToImg.toNSString()]);
auto canPrint([UIPrintInteractionController canPrintURL: imgUrl]);
auto controller = [UIPrintInteractionController sharedPrintController];
if(controller && canPrint)
{
controller.printInfo = printInfo;
controller.printingItem = imgUrl;
// this allows your app to directly print to the selected printer
[controller printToPrinter: m_Printer
completionHandler: ^(UIPrintInteractionController* /*printCtrl*/, BOOL completed, NSError* err)
{
if(completed && !err)
{
qInfo() << "Print successful";
}
}];
}
}
在你pro文件,您需要按以下方式添加上述objective-C++文件:
ios {
OBJECTIVE_SOURCES += $${PRINTERMANAGER_FOLDER}/PrinterManager.mm \
$${PRINTERMANAGER_FOLDER}/IosPrinterManagerImpl.mm \
$${PRINTERMANAGER_FOLDER}/IosPrinterManagerImpl.hpp
}
我不是专家的Objective-C++代码编写器。例如,我非常肯定你可以以更聪明的方式将setupPrinter()方法中创建的打印机选取器小部件集成到Qt GUI中。然而,这段代码可能解决了你的问题......
我想你需要在'UIPrintInteractionController'上工作。看看一些例子https://stackoverflow.com/questions/34206207/printing-the-view-in-ios-with-swift – GIJOW
我忘了添加qt标签,但我希望能用ct直接在C++中使用qt ,如果这是可能的话。我认为可以混合使用C++和objective-c,但是如果可能的话,我宁愿使用一种语言,到目前为止,已经决定使用C++与qt进行开发。 – Shikamu