基于Qt的收银点餐系统之小票打印(二)

本篇给出基于QPrinter+QPainter的小票打印代码。

一、说明

类ReceiptPainter继承了QPainter,专门用于打印小票,在方法doCustomerPrint()中进行打印。
其成员变量OrderDetailBean* orderDetail 是订单的详细信息。包含有:
时间、编号、总价、收款、找零,以及订单中每样商品的详细信息:名称、数量、单价
main函数中的调用代码:

QString targetPrinterName = "XX打印机";
QPrinterInfo targetPrinter = QPrinterInfo::printerInfo(targetPrinterName);
QPrinter printer(targetPrinter);
ReceiptPainter rPainter(&printer,orderDetailItem,shopName);

在使用QPrinter+QPainter进行小票打印中,打印内容以及排版在QPainter中进行设置。由下面代码将看出,与其说QPainter是对文字进行了排版,还不如说是QPainter对“矩形”进行了排版,然后才在各个矩形中填上了文字。这主要是由QPainter绘制文字的方式决定的。

QPainter::drawText ( const QRectF &rectangle,  const QString & text )

参考文章:http://www.qter.org/portal.php?mod=view&aid=40

二、代码

ReceiptPainter.h

#ifndef RECEIPTPAINTER_H
#define RECEIPTPAINTER_H
#include <QPaintEvent>
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>
#include <QPainter>
#include <QWidget>
#include <QList>

#include <QString>
#include <QChar>
#include <QVector>
#include "orderdetailbean.h"
#include "ordergoodsbean.h"

class ReceiptPainter : public QPainter
{
public:
    ReceiptPainter(QPrinter*,OrderDetailBean*,QString);
    ~ReceiptPainter();
    void doCustomerPrint();
    QString getSeperator(double);
private:
    //下面的数字单位是 像素
    // 字体大小
    enum {FONT_SIZE_NORMAL = 10,FONT_SIZE_MIDDLE = 12,FONT_SIZE_BIG = 20};  //正常、中等、大

    //预留尺寸
    enum {TOTAL_LENGTH = 140,GOODS_LENGTH = 40,GOODS_NUM_LENGTH = 40}; //小票每一行的可以打印的位数、商品名称的预留长度、商品数量的预留长度

    OrderDetailBean* orderDetail;  //订单的详细信息:时间、编号、总价、收款、找零,以及订单中每样商品的详细信息:名称、数量、单价
    QString shopName;
};

#endif // RECEIPTPAINTER_H

ReceiptPainter.cpp

#include "receiptpainter.h"
#include <QByteArray>
#include <QTextCodec>
#include <QDebug>
#include <QRect>
#include <QPen>
#include <QBrush>
#include <QFont>
ReceiptPainter::ReceiptPainter(QPrinter* printer,OrderDetailBean* od,QString sn):QPainter(printer)
{
    orderDetail = od;
    shopName = sn;
    doCustomerPrint();

}


QString ReceiptPainter::getSeperator(double width){
    int per = 12;  //360pt可以打30个*
    int cnt = width / per;
    QString sep;
    for(int i = 0; i < cnt; i++) sep.append("* ");
    return sep;
}

void ReceiptPainter::doCustomerPrint(){
    double rt = 0.38;
    QFont font1("宋体",FONT_SIZE_NORMAL,QFont::Bold);
    QFont font2("宋体",FONT_SIZE_NORMAL);
    QFont font3("宋体",FONT_SIZE_NORMAL,QFont::Bold);
    QFont font4("宋体",FONT_SIZE_MIDDLE);

    int xx1 = 50 * rt;
    int xx2 = 410 * rt;
    int xx3 = 545 * rt;

    //w1 w2 w3 分别是品名、数目、单价的所在栏占的宽度
    int w1 = 360 * rt;  
    int w2 = 135 * rt;
    int w3 = 150 * rt;

    //h1 h2 分别适用于两种字体大小
    int h1 = 48 * rt;
    int h2 = 35 * rt;
    int h3 = 60 * rt;

    QString seperator = getSeperator(w1+w2+w3);

    //打印店名
    QRect rect(xx1,0,w1+w2+w3,h1);
    this->setFont(font1);
    this->drawText(rect,Qt::AlignCenter,shopName);

    //打印订单号和时间
    rect.setY(rect.y()+rect.height());
    rect.setHeight(h2);
    this->setFont(font2);
    this->drawText(rect,"时间:"+orderDetail->getTime());

    rect.setY(rect.y()+rect.height());
    rect.setHeight(h2);
    this->drawText(rect,"堂食: "+ QString::number(orderDetail->getSerialNo()));
    //分隔符
    rect.setY(rect.y()+rect.height());
    rect.setHeight(h2);

    this->drawText(rect,seperator);

    //品名                数量 单价
    this->setFont(font3);
    rect.setY(rect.y()+rect.height());
    rect.setHeight(h2);
    rect.setX(xx1);
    rect.setWidth(w1);
    this->drawText(rect,Qt::AlignLeft,"品名");
    rect.setX(xx2);
    rect.setWidth(w2);
    this->drawText(rect,Qt::AlignLeft,"数量");
    rect.setX(xx3);
    rect.setWidth(w3);
    this->drawText(rect,Qt::AlignLeft,"单价");

    //打印商品
    this->setFont(font2);
    QList<OrderGoodsBean*> goodsList = orderDetail->getOrderGoodsList();
    OrderGoodsBean* orderGoodsItem = new OrderGoodsBean();
    for (int i = 0; i < goodsList.size(); i++) {
        orderGoodsItem = goodsList.at(i);
        QString nname = orderGoodsItem->getName();
        QString num = QString::number(orderGoodsItem->getAmount(),'g',10);
        QString price = QString::number(orderGoodsItem->getPrice(),'g',10);
        rect.setY(rect.y()+rect.height());
        rect.setHeight(h2);
        rect.setX(xx1);
        rect.setWidth(w1);
        this->drawText(rect,Qt::AlignLeft,nname);
        rect.setX(xx2);
        rect.setWidth(w2);
        this->drawText(rect,Qt::AlignLeft,num);
        rect.setX(xx3);
        rect.setWidth(w3);
        this->drawText(rect,Qt::AlignLeft,"¥" + price);
    }

    //分隔符
    rect.setY(rect.y()+rect.height());
    rect.setHeight(h2);
    rect.setX(xx1);
    rect.setWidth(w1+w2+w3);
    this->drawText(rect,seperator);

    //打印总价、付款、找零信息
    QString tp = QString::number(orderDetail->getTotalPrice(),'g',10);
    QString pm = QString::number(orderDetail->getPaidMoney(),'g',10);
    QString cg = QString::number(orderDetail->getChange(),'g',10);
    this->setFont(font4);
    rect.setY(rect.y()+rect.height());
    rect.setHeight(h1);
    rect.setX(xx1);
    rect.setWidth(w1+w2);
    this->drawText(rect,Qt::AlignLeft,"共计:");
    rect.setX(xx3);
    rect.setWidth(w3);
    this->drawText(rect,Qt::AlignLeft,tp);

    rect.setY(rect.y()+rect.height());
    rect.setHeight(h1);
    rect.setX(xx1);
    rect.setWidth(w1+w2);
    this->drawText(rect,Qt::AlignLeft,"已收款:");
    rect.setX(xx3);
    rect.setWidth(w3);
    this->drawText(rect,Qt::AlignLeft,pm);

    rect.setY(rect.y()+rect.height());
    rect.setHeight(h1);
    rect.setX(xx1);
    rect.setWidth(w1+w2);
    this->drawText(rect,Qt::AlignLeft,"找零:");
    rect.setX(xx3);
    rect.setWidth(w3);
    this->drawText(rect,Qt::AlignLeft,cg);


    //分隔符
    this->setFont(font2);
    rect.setY(rect.y()+rect.height());
    rect.setHeight(h2);
    rect.setX(xx1);
    rect.setWidth(w1+w2+w3);
    this->drawText(rect,seperator);

}

ReceiptPainter::~ReceiptPainter()
{

}

参考文章:

Qt中的打印操作:http://blog.csdn.net/amnes1a/article/details/70597506
QT的打印基础: http://blog.csdn.net/yavobo/article/details/5643441
QT打印过程:http://m.blog.csdn.net/qqbitqqbit/article/details/17722507
Qt学习之路(24): QPainter: http://devbean.blog.51cto.com/448512/235332/
Qt5之2D绘图(三)绘制文字:http://www.qter.org/portal.php?mod=view&aid=40

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值