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.
精彩评论