qt实现界面显示和打印部分分离

来源:互联网 发布:dji视频编辑软件 编辑:程序博客网 时间:2024/05/01 10:06

1.需求

要求实现pos端结算时弹出找零界面同时进行打开钱箱打印,找零界面是阻塞对话框,

2.解决

1.采用多线程解决找零界面是ui 打印因为是通过html打印也是ui线程 qt规定所有ui只能在ui线程中 故无法导通
2.通过将html打印成图片 开打印线程将图片绘制到打印纸上 出现打印出来的东东较为模糊 故无法导通
3.将打印单独拎出来 打印时直接调用打印进程来搞 可以导通

3.代码

调用部分代码
void myprinter::on_testbtn_clicked(){    QString strExePath("");    strExePath = QCoreApplication::applicationDirPath() + "\\catprinter.exe";    //if (m_process.isOpen())    QString strHtml("");    strHtml += QString("<html>"        "<head><style type=\"text/css\">"        "body {margin-left:5%;}"        "h1 {font-size:110%;text-align:center;width:100%;line-height:90%}"        "h2 {font-size:100%;text-align:center;width=100%;line-height:90%}"        "h3 {font-size:90%;text-align:center;width:100%;line-height:90%}");    strHtml += QString("th {font-size:%1%;text-align:left;margin-left:0;line-height:90%}"        "td {font-size:%1%;text-align:left;margin-left:0;line-height:90%}"        "table {border:0;width:90%}</style></head>").arg(65);    //头部    strHtml += QString("<body>");    strHtml += QString("<h2>");    strHtml += QStringLiteral("8637品牌工厂店部分");    strHtml += QString("</h2>");    strHtml += QString("</body></html>");    QStringList list;    list.push_back(strHtml);    list.push_back(QString("80"));    list.push_back(QString("1"));    list.push_back(QString("GP-80160(Cut) Series"));    list.push_back(QString("1"));    list.push_back(QString("ST-1234567898776"));    //QProcess process;    m_process.startDetached(strExePath, list);    //QMessageBox::information(this, "msg", "test");}
打印进程 main.cpp
#include "catprinter.h"#include <QtWidgets/QApplication>#include <QtPrintSupport\QPrinter>#include <QtPrintSupport\QPrintDialog>#include <QtWebKitWidgets\QWebFrame>#include <QtWebKitWidgets\QWebPage>#include <QtWebKit\QWebElement>#include <QtGui\QPageSize>#include <QtCore\QRectF>#include <QtGui\QPainter>#include <QtGui\QTextDocument>#include <QtCore\QFile>#include <QtCore\QTextCodec>#include <QPrinterInfo>#include <windows.h>#include <QStringList>#include "zint.h"#ifdef _DEBUG#pragma comment(lib, "../Win32/Debug/zintd.dll.lib")#else#pragma comment(lib, "../Win32/Release/zint.dll.lib")#endiftypedef struct stHtml{    bool bBarcode;    int nTicketSize;    int nPages;    QString strPrinterName;    QString strTicket;}S_HTML;void printHtml(const QString &strHtml, S_HTML &shtml);bool drawBarcode(QPainter &painter, const QString &strImagePath, const QRect &rtBarcode, int width);int main(int argc, char *argv[]){    QApplication a(argc, argv);    QString strHtml("");    QStringList list = QCoreApplication::arguments();    S_HTML shtml;    if (list.count() > 6)    {        strHtml = list[1];        shtml.nTicketSize = list[2].toInt();//stSetInfo.nTicketSize;        shtml.nPages = list[3].toInt();//stSetInfo.nPages;        shtml.strPrinterName = list[4];//stSetInfo.strPrinterName;        shtml.bBarcode = list[5].toInt();//mapFormat[E_PRINT_BARCODE];           //modified by zrq 20150930        shtml.strTicket = list[6];//stInfo.strTicket;        printHtml(strHtml, shtml);        //return a.exec();    }    else        //return 0;    //这里调用打印机进行打印    return 0; //a.exec();}void printHtml(const QString &strHtml, S_HTML &shtml){    if (shtml.strPrinterName.isEmpty())        return;    QPrinter printer;    printer.setPrinterName(shtml.strPrinterName);    //貌似没什么用,不过我还是设置了下    printer.setFullPage(true);    //计算在打印机的DPI下,58mm对应的点数    int dpi=printer.logicalDpiX();    int width=min(shtml.nTicketSize, printer.paperRect(QPrinter::Millimeter).width())*(dpi*1.0/25.4);//58mm    //使用QWebPage来解析并输出解析后的文档到打印机    QWebPage page;      page.mainFrame()->setHtml(strHtml);    QWebFrame *frame=page.mainFrame();    //设置网页视口大小,因为我在html文档中用相对大小布局的    page.setViewportSize(QSize(width,frame->findFirstElement("body").geometry().height()));    if (!shtml.bBarcode)    {        for (int npage = 0; npage < shtml.nPages;)        {            QPainter painter(&printer);            if (painter.isActive())                frame->render(&painter);            ++npage;        }    }    else    {        QString strTicket(shtml.strTicket);        if (strTicket.length() > 3)            strTicket = strTicket.mid(3);        QString strImagePath("");        strImagePath = QCoreApplication::applicationDirPath() + "//test.png";        struct zint_symbol * my_symbol = ZBarcode_Create();        my_symbol->symbology = BARCODE_CODE93;//BARCODE_CODE11;        strcpy(my_symbol->outfile, strImagePath.toLocal8Bit().toStdString().c_str());        ZBarcode_Encode(my_symbol, (unsigned char*)strTicket.toLocal8Bit().toStdString().c_str(), 0);        ZBarcode_Print(my_symbol, 0);         ZBarcode_Delete(my_symbol);        QSize imgsize(width, frame->findFirstElement("table.barcode").geometry().height());        QRect rtBarcode(2, frame->findFirstElement("table.barcode").geometry().top(),                         imgsize.width(), imgsize.height());        for (int npage = 0; npage < shtml.nPages;)        {            //这里修改下直接打印到图片上看下效果            QPainter painter(&printer);            if (painter.isActive())                frame->render(&painter);            drawBarcode(painter, strImagePath, rtBarcode, width);            ++npage;        }    }}bool drawBarcode(QPainter &painter, const QString &strImagePath, const QRect &rtBarcode, int width){    QImage image(strImagePath, "PNG");    QRect rt1 = image.rect();    QRect rtwindow = painter.window();    QRect rtview = painter.viewport();    int nmax = 0;    if (image.width() + 20 < width)        nmax = max(image.width() + 20, width);    else        nmax = min(image.width() + 20, width);    QRect rtimage(0, 0, nmax, rtwindow.height());    QRect rtimageview(0, 0, nmax, rtview.height());    int nmin = min(image.width(), nmax - 80);    QRectF rtdes(40, rtBarcode.top(), nmin, rtBarcode.height());    QRectF rtsrc(0, 0, image.width(), image.height());    painter.setWindow(rtimage);    painter.setViewport(rtimageview);    painter.drawImage(rtdes, image, rtsrc);      painter.setWindow(rtwindow);    painter.setViewport(rtview);    return true;}

4.备注

1.完整测试部分代码:http://download.csdn.net/detail/zhang_ruiqiang/9173255
2.调用时也可以将调用打印部分放在线程中,在线程中调用打印进程
0 0
原创粉丝点击