我正在尝试制作一款能够自动生成的应用程序"将图片打印到网络上的打印机。我是iOS和Qt的新手,但到目前为止我还没有找到如何进行打印。我找到了一些示例,告诉我如何使用bonjour(https://doc.qt.io/archives/qq/qq23-bonjour.html),我想我可以或多或少地找到这样的打印机,但到目前为止我还没有找到任何关于如何使用QPrinter的帮助自动连接到该打印机。 基本上我的代码到目前为止基本上是:
QPrinter printer;
printer.setOutputFormat(QPrinter::NativeFormat);
printer.setPrinterName("Canon SELPHY CP1200");
QPainter painter;
if(!painter.begin(&printer))
{
//failed, we actually hit this at the moment
return 1;
}
painter.drawText(10, 10, "Test !");
painter.end();
我认为问题在于我需要以某种方式将设备连接到佳能打印机,但我不知道该怎么做。任何见解将不胜感激:))
干杯!
答案 0 :(得分:1)
即使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);
}
如此指定,可以在QML中轻松使用PrinterManager。
整个技巧包括使用PIMPL惯用法编写PrinterManager,即在成员m_Impl中封装类实现。然后,根据您编译代码的平台,您将提供所需的任何PrinterManagerImpl。
除了上面的PrinterManager实现(cpp文件)之外,还需要定义以下mm文件(对于objective-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中。但是,这段代码可能解决了您的问题......