即使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