开发者

Qt: Print raw text

I need to output a ZPL script to a Zebra printer in a Qt application. The printer is on a smb share network configured as raw printer in the client computer.

Everything goes fine if I call cupsPrintFile( "printer_name", "./tmp_print_file.zpl", "", 0, NULL ) from a C++ test program.

If I use QTextDocument::print() using the same text in "./tmp_print_file.zpl" as document, nothing gets printed. I sniffed the network and found that the data being sent to the printer server is not raw data, but, a postscript!

Is there any way to get the data sent to the printer with no modification at all?

  • Let me be clear that I don't want to render a text, but just send the label script, that is ready to print, directly to the printer, that understands the ZPL protocol.

Thanks for all.


EDIT:

As @Martin said, I tried:

printer.setOutputFormat( QPrinter::NativeFormat );
QTextDocument   *doc = new QTextDocument( QString( label ), this );
doc->print( &pr开发者_运维技巧inter );

but it didn't work.


Before I start, must thank Dave. His suggestion to bypass the temporary file while printing with CUPs works fine.

Now, my conclusion: There is no easy way to print raw data using Qt only. Maybe creating custom QPainter or going down to the bits of QPrinter could give a solution, but it would take me too much time.

The final solution is simply use CUPs API inside my Qt application. Unfortunatelly, it is not portable.

Here is a snippet:

#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( ) );

And it's done.

Don't forget to link libcups (-lcups).

I still hope any buddy to add another solution prooving that Qt-only is possible. Meanwhile, it is enough.

Thanks everybody.


Could you just do exactly what you did in your test program:

  • Create a temporary file (QTemporaryFile).
  • Send the contents to the file.
  • Call your cupsPrintFile method.

Or there is probably a way with the CUPS API to bypass the temporary file. Disclaimer: I have absolutely no experience with the CUPS API; this is just based on a cursory look at some online documentation. Looks like perhaps the following sequence:

  • cupsCreateJob > cupsStartDocument > cupsWriteRequestData > cupsFinishDocument

If that works, you just need to convert your QString to the correct byte encoding.


Thanks for fljx's code, it is very useful for me.

I changed a litte for sending raw text to zebra printer .

const char* format = CUPS_FORMAT_RAW;


Take a look at QPrinter(),

QTextDocument is designed to render formatted text.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜