Qt:打印原始文本

Posted

技术标签:

【中文标题】Qt:打印原始文本【英文标题】:Qt: Print raw text 【发布时间】:2011-04-05 20:41:11 【问题描述】:

我需要在 Qt 应用程序中将 ZPL 脚本输出到 Zebra 打印机。 打印机位于客户端计算机中配置为 原始打印机 的 smb 共享网络上。

如果我从 C++ 测试程序调用 cupsPrintFile( "printer_name", "./tmp_print_file.zpl", "", 0, NULL ),一切都会正常。

如果我使用 QTextDocument::print() 并在“./tmp_print_file.zpl”中使用相同的文本作为文档,则不会打印任何内容。 我嗅探网络,发现发送到打印机服务器的数据不是原始数据,而是后记!

有没有什么方法可以不加修改就将数据发送到打印机?

让我明确一点,我不想渲染文本,而只是将准备打印的标签脚本直接发送到理解 ZPL 协议的打印机。

谢谢大家。


编辑:

正如@Martin 所说,我试过了:

printer.setOutputFormat( QPrinter::NativeFormat );
QTextDocument   *doc = new QTextDocument( QString( label ), this );
doc->print( &printer );

但是没有用。

【问题讨论】:

【参考方案1】:

在我开始之前,必须感谢戴夫。他建议在使用 CUP 打印时绕过临时文件效果很好。

现在,我的结论是:仅使用 Qt 打印原始数据并不容易。 也许创建自定义 QPainter 或深入 QPrinter 可以提供解决方案,但这会花费我太多时间。

最终的解决方案是在我的 Qt 应用程序中简单地使用 CUPs API。不幸的是,它不便携。

这是一个sn-p:

#include    <cups/cups.h>

//...

int print_label( const char *text, const char *printer_name, const char *job_name )

    int jobId = 0;

    jobId = cupsCreateJob( CUPS_HTTP_DEFAULT, printer_name, job_name, 0, NULL );

    if ( jobId > 0 )
    
        qDebug( ) << "Printing job #" << jobId << " (\"" << job_name << "\").";

        const char* format = CUPS_FORMAT_TEXT;  // CUPS_FORMAT_POSTSCRIPT;

        cupsStartDocument( CUPS_HTTP_DEFAULT, printer_name, jobId, text, format, true );
        cupsWriteRequestData( CUPS_HTTP_DEFAULT, text, strlen( text ) );

        cupsFinishDocument( CUPS_HTTP_DEFAULT, printer_name );
    

    return jobId;


//...

// Now, inside any Qt function (may be a slot):

QPrinter printer;

QPrintDialog *dialog = new QPrintDialog( &printer, this );
dialog->setWindowTitle( tr( "Zebra label" ) );
if ( dialog->exec( ) != QDialog::Accepted )
    return;

    // This is the sample label. Can be anything.
const char  label[] =
    "^XA~TA000~JSN^LT0^MNW^MTD^PON^PMN^LH0,0^JMA^PR4,4^MD0^JUS^LRN^CI0^XZ\n"
    "^XA\n"
    "^MMT\n"
    "^LL0600\n"
    "^PW900\n"
    "^LS0\n"
    "^BY2,3,54^FT24,109^BCN,,Y,N\n"
    "^FD>;43210000>773>0000^FS\n"
    "^PQ1,0,1,Y^XZ\n";

    // Informative only.
ui->txtLabelScript->setPlainText( label );

    // Call the printing function.
if ( print_label( label, printer.printerName( ).toAscii( ), "Zebra_Label" ) == 0 )
    qDebug( ) << "CUPS Error: " << ippErrorString( cupsLastError( ) );

它已经完成了。

别忘了链接 libcups (-lcups)。

我仍然希望任何伙伴添加另一个解决方案来证明 Qt-only 是可能的。同时,也足够了。

谢谢大家。

【讨论】:

取决于你如何定义便携。它当然不是纯 QT。在我看来,这并不一定意味着不可移植。这不使用操作系统/设备特定的 api 调用。它使用两个多平台框架作品QT和CUPS。【参考方案2】:

你能不能完全按照你在测试程序中所做的那样做:

创建一个临时文件 (QTemporaryFile)。 将内容发送到文件中。 调用您的cupsPrintFile 方法。

或者 CUPS API 可能有一种方法可以绕过临时文件。 免责声明:我完全没有使用 CUPS API 的经验;这只是基于对一些在线文档的粗略查看。看起来可能是以下顺序:

cupsCreateJob > cupsStartDocument > cupsWriteRequestData > cupsFinishDocument

如果可行,您只需将QString 转换为正确的字节编码。

【讨论】:

当然这应该可行,但不会回答我的问题:如何在 Qt 中做到这一点。我会调查你关于如何绕过临时文件的建议。真的很感谢。 对不起,我不明白你的问题。我使用 Qt 的方式只是一个 C++ 框架——一个完整的应用程序不仅可以使用 Qt,还可以使用许多其他第三方库(Boost 等)。如果您已经可以在 C++ 中完成,则无需通过 Qt。您是否有特殊原因需要通过 Qt API 而不仅仅是直接在 C++ 中执行此操作? 它有效。正如@Dave 建议的那样,我必须从内存中打印,没有任何临时文件。我将更多地搜索仅 Qt 的解决方案(希望是可移植的)。如果我失败了,这将是响应。【参考方案3】:

感谢fljx的代码,对我很有用。

我改变了一点,将原始文本发送到斑马打印机。

const char* 格式 = CUPS_FORMAT_RAW;

【讨论】:

【参考方案4】:

看看QPrinter(),

QTextDocument 旨在呈现格式化文本。

【讨论】:

好的。 我应该在 QPrinter 中寻找什么?我看到通过 QPrinter 将数据发送到打印机的唯一方法是使用 QPainter,它会渲染我的文本,而不是发送原始数据。我错过了什么? 您不只是设置 outputformat=NativeFormat 并直接发送到打印机吗? outputformat=NativeFormat 没有用。我已经尝试过了,并相信这一定是正确的方法。除非我做错了,否则这不是解决方案。还是谢谢。 NativeFormat 在 QPrinter 的上下文中意味着使用本机打印系统的方法,即在 Windows 上这将是 GDI。这并不意味着表示打印机本身的本机方法。

以上是关于Qt:打印原始文本的主要内容,如果未能解决你的问题,请参考以下文章

Qt编写气体安全管理系统11-数据打印

使用 Qt 打印 PDF 文件

案例分享:Qt政务标签设计器,标签排版软件定制与打印

JS打印 - CSS文本颜色不显示

有没有办法打印这个未显示的标签文本? [复制]

如何从 QWebEngineView 打印