C++,Qt实现条码控件&绘制接口

前面有了二维码,那么条码也必须安排上,不然就有点不完整了。

条码支持控件显示,生成QImage,QPixmap,复制到系统剪贴板图片,保存条码图片文件,提供绘制接口等功能。各种颜色,字体以及尺寸均可调整,支持14种条码编码方式。

有关技术交流其它交流可加入QQ群717743458探讨。

老规矩先上图

当然了,随机颜色怎么能少呢

生成图片

自定义风格结构体定义如下

 /// 条码风格数据结构体
  typedef struct LQBARCODECTRL_STYLE_{
    QColor                      cBkgColorsValue = QColor(255,255,255);  //控件背景色
    QColor                      cBarColorsValue = QColor(22,22,39);     //条码前景色
    QColor                      cBarCodeLineClr = QColor(22,22,39);        //条码分割线颜色

    QColor                      cOutBorderColor = QColor(33,33,49);     //条码外边框颜色
    QColor                      cInnBorderColor = QColor(44,44,59);     //条码内边框颜色
    QColor                      cPrefixTxtColor = QColor(33,33,49);     //条码前缀文本颜色
    QColor                      cPrefixBarColor = QColor(11,11,29);     //条码前缀和分割线颜色
    QColor                      cCodeTextColors = QColor(44,44,59);     //条码文本颜色

    double                      dInnBorderWidth = 0.75;                 //内边框宽度
    double                      dOutBorderWidth = 2.0;                  //外边框宽度
    double                      dBarRadiusValue = 0.5;                  //条码竖线圆角比例
    double                      dFrameRadiusVal = 0.02;                 //条码全局圆角比例

    uint                        uBarBorderStyle = 0;                    //边框分隔,0无边框,1单边框,2双边框
    uint                        uBarBorderAlign = 0;                    //边框停靠,0全局,1上,2下
    bool                        bDrawBarBkgdClr = true;                 //是否绘制背景
    bool                        bShowBarCodeTxt = true;                 //是否绘制条码内容

    bool                        bRandomBarColor = false;                //随机条码颜色
    bool                        bRandomTxtColor = false;                //随机数值颜色

    uint                        uBarCodePadding = 8;                    //条码边距

    ///条码编码方式,0-15之间,定义如下
    /* 0:choose best-fit 自动选择最合适的,根据输入内容自动匹配
     * 1:EAN,只支持数字。要求数字是 7位或者12位。通常用于商品的编码,长度必须按照要求。
     * 2:upc == 12-digit ean,要求字符串长度为 6、7、8(UPC-E)或者 11、12 (UPC-A)。长度必须按照要求并且字符只能是数字。
     * 3:isbn numbers (still EAN13),由十三位数字组成,格式固定,前三位为地区嘛 如978,并以四个连接号或四个空格加以分割,每组数字都有固定的含义。例如7-118-01984-4
     * 4:code 39,0-9,A-Z[不含小写],连接号(-),句号(.),空格,美圆符号($),斜扛(/),加号(+)以及百分号(%)等43个字符额外支持*,长度理论上没有限制,长度可变,此程序限定最大64
     * 5:code 128 (a,b,c: autoselection),自动选择,支持基本字符,比如字符和符号以及数字等,理论上长度不限,长度可变,此程序限定最大128
     * 6:code 128 (compact form for digits) 数字紧凑,仅限数字,并且长度只能为12
     * 7:code 128, full printable ascii,适用于ascii打印的条码,支持基本字符,比如字符和符号以及数字等,理论上长度不限,长度可变,此程序限定最大128
     * 8:interleaved 2 of 5 (only digits) 交错形式 仅限数字,理论上不限长度,长度可变,此程序限定最大64
     * 9:Raw code 128 (by Leonid A. Broukhis),仅限数字,长度可变,此程序限定最大32位长度,未能测试出此条码数据格式,因此此条码设置被忽略
     * 10:Codabar (by Leonid A. Broukhis),包含0-9.A-Z大写,长度可变,此程序限定最大48,使用字母时仅限头和尾各一个字符
     * 11:MSI (by Leonid A. Broukhis),仅限数字,长度理论上无限制,长度可变,此程序最大限定48
     * 12:Plessey (by Leonid A. Broukhis),包含数字和A-F六个大写字母, 理论不限长度,长度可变,此程序限定64
     * 13:code 93 (by Nathan D. Holmes),与Code39字符集相同,属性也相同,密度高,长度理论上没有限制,长度可变,此程序限定最大128
     * 14:code 11 (USD-8),数字0-9和字符“-”,长度理论不限,此程序限定48
     * 15:code 39 extended (by Ian Ward),与Code39接近,支持更多字符,长度理论上没有限制,长度可变,此程序限定最大64
    */
    uint                        uBarCodeEncoder = 0;                    //条码编码方式

    QFont                       fBarCodeFontObj;                        //条码字体对象

    bool operator == (const LQBARCODECTRL_STYLE_& rhs) // == 操作运算符重载
    {
      return (cBkgColorsValue == rhs.cBkgColorsValue)
          && (cBarColorsValue == rhs.cBarColorsValue)
          && (cBarCodeLineClr == rhs.cBarCodeLineClr)
          && (cOutBorderColor == rhs.cOutBorderColor)
          && (cInnBorderColor == rhs.cInnBorderColor)
          && (cPrefixTxtColor == rhs.cPrefixTxtColor)
          && (cPrefixBarColor == rhs.cPrefixBarColor)
          && (cCodeTextColors == rhs.cCodeTextColors)
          && (DoubleValCompare(dInnBorderWidth,rhs.dInnBorderWidth))
          && (DoubleValCompare(dOutBorderWidth,rhs.dOutBorderWidth))
          && (DoubleValCompare(dBarRadiusValue,rhs.dBarRadiusValue))
          && (DoubleValCompare(dFrameRadiusVal,rhs.dFrameRadiusVal))
          && (uBarBorderStyle == rhs.uBarBorderStyle)
          && (uBarBorderAlign == rhs.uBarBorderAlign)
          && (bDrawBarBkgdClr == rhs.bDrawBarBkgdClr)
          && (bShowBarCodeTxt == rhs.bShowBarCodeTxt)
          && (bRandomBarColor == rhs.bRandomBarColor)
          && (bRandomTxtColor == rhs.bRandomTxtColor)
          && (uBarCodePadding == rhs.uBarCodePadding)
          && (uBarCodeEncoder == rhs.uBarCodeEncoder);
    }

    bool operator != (const LQBARCODECTRL_STYLE_& rhs) // != 操作运算符重载
    {
      return !(*this == rhs);
    }
  }LQBARCODECTRL_STYLE,*PLQBARCODECTRL_STYLE;

重点头定义文件如下

 ///重写系统绘制事件
    virtual void paintEvent(QPaintEvent *event) override;

    /// 绘制条码
    /// \brief DrawBarCodeRender
    /// \param painter
    /// \param size
    ///
    virtual void DrawBarCodeRender(QPainter *painter,QSize size);

    /// 绘制边框图像
    /// \brief DrawQrCodeBorders
    /// \param painter
    ///
    virtual void DrawBarCodeBorder(QPainter *painter,QSize size);

    /// 绘制条码竖线
    /// \brief DrawBarCodesLines
    /// \param painter
    ///
    virtual void DrawBarCodesLines(QPainter *painter,QSize size);

    /// 绘制条码文本
    /// \brief DrawBarCodesTexts
    /// \param painter
    /// \param size
    ///
    virtual void DrawBarCodesTexts(QPainter *painter,QSize size);

    /// 绘制错误信息
    /// \brief DrawBarCodesError
    /// \param painter
    /// \param size
    ///
    virtual void DrawBarCodesError(QPainter *painter,QSize size);

    /// 将条码图像显示到控件
    /// \brief DrawBarCodeImgage
    /// \param pImage
    ///
    virtual void DrawBarCodeImgage(QPixmap pImage);

  private:
    /// 检查绘制字符串有效性
    /// \brief CheckStringValide
    /// \return
    ///
    bool CheckStringValide();

    /// 更新条码绘制信息
    /// \brief UpdateBarDrawInfo
    ///
    void UpdateBarDrawInfo(bool bUpdate = true);

    /// 计算条码数据宽度尺寸
    /// \brief CalBarCodeInfSize
    ///
    void CalBarCodeInfSize();
  protected:
    bool                bParseImageMode = false;   //是否为解析模式
    LQBARCODECTRL_STYLE tCtrlsStyleData;           //二维码图像风格数据结构体
    std::u16string      sBarCodeTextVal;           //二维码数据
    std::u16string      sBarErrorInfTxt;           //错误信息文本
    std::u16string      sOldBarCodeText;           //旧条码数据
    std::u16string      sErrorImagePath;           //绘制错误图像路径
    uint                uOldBarCodesEnc;           //旧条码编码索引
    QPixmap             pParseImageObjs;           //解析的图像对象
    Barcode_Item*       pBarcodeItemObj = nullptr; //条码对象指针
  public:
    /// 生成条码图像并输出QPixmap引用
    /// \brief BuildBarCodeImage
    /// \param sValue      :条码内容
    /// \param pPixmap     :生成的图像
    /// \param uSize       :生成的图片大小,图像大小边长不能小于48
    /// \param sError      :错误信息
    /// \param bDraw       :是否绘制到控件,默认不绘制
    /// \param bEnableDpi  :是否启用DPI缩放,默认启用这意味这实际大小是uSize*屏幕分辨率的缩放倍数,多显示器的情况下取主显示器DPI缩放
    /// \param uEncode     :条码编码方式,65535表示跟随全局配置,否则赋值0-15之间,编码定义参考风格数据结构体定义
    /// \return
    ///
    bool BuildBarCodeImage(const std::u16string& sValue,QPixmap& pPixmap,QSize pSize,std::u16string& sError,bool bDraw = false,bool bEnableDpi = true,uint uEncode = 65535);

    /// 生成条码码图像并输出QImage引用
    /// \brief BuildBarCodeImage
    /// \param sValue      :条码码内容
    /// \param pImage      :生成的图像
    /// \param uSize       :生成的图片大小
    /// \param sError      :错误信息
    /// \param bDraw       :是否绘制到控件,默认不绘制
    /// \param bEnableDpi  :是否启用DPI缩放,默认启用这意味这实际大小是uSize*屏幕分辨率的缩放倍数,多显示器的情况下取主显示器DPI缩放
    /// \param uEncode     :条码编码方式,65535表示跟随全局配置,否则赋值0-15之间,编码定义参考风格数据结构体定义
    /// \return
    ///
    bool BuildBarCodeImage(const std::u16string& sValue,QImage& pImage,QSize pSize,std::u16string& sError,bool bDraw = false,bool bEnableDpi = true,uint uEncode = 65535);

    /// 生成条码绘图信息
    /// 注意:这是一个纯绘制接口,绘制指针和结果均由开发者自行处理。可以用于打印,生成图片,嵌入绘制等各种操作
    /// \brief BuildBarCodePaint
    /// \param sValue        :条码数据
    /// \param painter       :绘图器指针,这个是关键,必须由开发者自行处理绘图前和绘图后的操作以及将图绘制在何处
    /// \param uSize         :绘图大小
    /// \param sError        :错误信息
    /// \param bDraw         :是否绘制到控件,默认不绘制
    /// \param bEnableDpi    :是否启用DPI缩放,默认启用这意味这实际大小是uSize*屏幕分辨率的缩放倍数,多显示器的情况下取主显示器DPI缩放
    /// \param uEncode       :条码编码方式,65535表示跟随全局配置,否则赋值0-15之间,编码定义参考风格数据结构体定义
    /// \return              :返回true之后处理painter数据,若返回false表示失败,失败原因参考sError信息
    ///
    bool BuildBarCodePaint(const std::u16string& sValue,QPainter *painter,QSize pSize,std::u16string& sError,bool bDraw = false,bool bEnableDpi = true,uint uEncode = 65535);

    /// 解析文件条码图像内容
    /// \brief ParseBarCodeImage
    /// \param sPath       :文件路径
    /// \param sError      :错误信息
    /// \return
    /// 提醒:此方法可识别二维码
    ///
    bool ParseBarCodeImage(const std::u16string& sPath,std::u16string& sError,bool bDraw = false);

    /// 解析URL条码图像内容
    /// \brief ParseQrCodesImage
    /// \param sUrl        :网络URL
    /// \param sError      :错误信息
    /// \param bDraw       :是否绘制打开的图像
    /// \return
    /// 注意:此功能默认返回false,因为考虑到网络功能会导致依赖项变大,所以不在此库中实现,因此此接口被设计成一个虚函数
    /// 您可以继承此控件然后重写此函数实现对网络条码的解析功能,您只需要根据URL获取到图像并将图像保存到本地或内存然后调用其他三个解析函数即可完成
    ///
    virtual bool ParseBarCodeImage(const QUrl& sUrl,std::u16string& sError,bool bDraw = false);

    /// 解析QPixmap对象条码图像内容
    /// \brief ParseBarCodeImage
    /// \param pImage      :QPixmap图像对象
    /// \param sError      :错误信息
    /// \param bDraw       :是否绘制打开的图像
    /// \return
    /// 提醒:此方法可识别二维码
    ///
    bool ParseBarCodeImage(const QPixmap& pImage,std::u16string& sError,bool bDraw = false);

    /// 解析QImage对象条码图像内容
    /// \brief ParseBarCodeImage
    /// \param pImage      :QImage图像对象
    /// \param sError      :错误信息
    /// \param bDraw       :是否绘制打开的图像
    /// \return
    /// 提醒:此方法可识别二维码
    ///
    bool ParseBarCodeImage(const QImage& pImage,std::u16string& sError,bool bDraw = false);

    /// 复制条码图像到剪贴板
    /// 注意:复制到剪贴板的图像只是拷贝输入的条码数据和和属性的图像,解析图像和BuildQrCodesImage的bDraw在false时将不会被绘制和复制
    /// \brief CopyBarCodesImage
    /// \param sError      :错误信息
    /// \return
    ///
    bool CopyBarCodesImage(std::u16string& sError);

    /// 保存条码图像到文件
    /// 注意:保存的图像只是拷贝输入的条码数据和和属性的图像,解析图像和BuildQrCodesImage的bDraw在false时将不会被绘制和保存
    /// \brief SaveBarCodesImage
    /// \param sFile       :要保存的文件路径
    /// \param sError      :错误信息
    /// \param bOverlay    :是否覆盖重复的文件,默认false,如果遇到同名文件会返回false
    /// \return
    ///
    bool SaveBarCodesImage(const std::u16string &sFile,std::u16string& sError,const bool bOverlay = false);

    /// 创建当前控件条码数据图像
    /// 注意:解析模式下的图像将不会被创建,此函数将依然根据输入的数据和配置属性创建条码图像
    /// \brief BuildBarCodeImage
    /// \return
    ///
    QPixmap BuildBarCodeImage();

为了保证输入的格式合法,需要处理输入的条码数据进行验证,但是并没有严格验证,只做了一般验证,验证代码如下

/// 检查条码数据有效性
  /// \brief CheckedBarCodeLen
  /// \param sValue     :数据内容
  /// \param sOutValue  :修订后的数据内容,主要修订长度不修订格式
  /// \param uEncode    :编码索引,0-15之间
  /// \return           :返回值
  ///
  inline bool CheckBarCodeValid(std::u16string sValue,std::u16string& sOutValue,uint uEncode)
  {
    if(sValue.length()<=0)return false;

    sOutValue =sValue;
    switch (uEncode) {
      case 0:{//长度最大128
          sOutValue = (sValue.length()>128)?sValue.substr(0,128):sValue;
          return true;
        }break;
      case 1:{//限定长度
          if(sValue.length()!=7&&sValue.length()!=12)return false;

          for(size_t s=0;s<sValue.length();s++)
            if(!(sValue[s]>=u'0'&&sValue[s]<=u'9'))return false;
          return true;
        }break;
      case 2:{//限定长度
          if(sValue.length()!=6&&sValue.length()!=7&&sValue.length()!=8&&sValue.length()!=11&&sValue.length()!=12)
            return false;

          for(size_t s=0;s<sValue.length();s++)
            if(!(sValue[s]>=u'0'&&sValue[s]<=u'9'))return false;
          return true;
        }break;
      case 3:{//限定正则格式
          std::regex rIsbn("^[1-9]\\-\\d{3}\\-\\d{5}-\\d{1}$");
          QString sAsciiVal = QString::fromStdU16String(sValue);
          return (std::regex_match(sAsciiVal.toStdString(), rIsbn));
        }break;
      case 4:{//0-9,A-Z[不含小写],连接号(-),句号(.),空格,美圆符号($),斜扛(/),加号(+)以及百分号(%)等43个字符,长度理论上没有限制,长度可变,此程序限定最大64
          sOutValue = (sValue.length()>64)?sValue.substr(0,64):sValue;

          size_t sLen = sOutValue.length();

          if(sLen<3)return false;

          for (size_t s = 0; s < sLen; s++)
            if (!((sOutValue[s] >= u'0' && sOutValue[s] <= u'9')||(sOutValue[s] >= u'A' && sOutValue[s] <= u'Z') || sOutValue[s] == u'-' || sOutValue[s] == u' ' || sOutValue[s] == u'.' || sOutValue[s] == u'$' || sOutValue[s] == u'/' || sOutValue[s] == u'+' || sOutValue[s] == u'%' ||sOutValue[s] == u'*'))
              return false;

          return true;
        }break;
      case 5:{//长度不超过128
          sOutValue = (sValue.length()>128)?sValue.substr(0,128):sValue;
          return true;
        }break;
      case 6:{//只能是12位数字
          if(sValue.length()<12)return false;
          sOutValue = (sValue.length()>=12)?sValue.substr(0,12):sValue;

          for(size_t s=0;s<sValue.length();s++)
            if(!(sOutValue[s]>=u'0'&&sOutValue[s]<=u'9'))return false;
          return true;
        }break;
      case 7:{//长度不超过128
          sOutValue = (sValue.length()>128)?sValue.substr(0,128):sValue;
          return true;
        }break;
      case 8:{//长度不超过64
          sOutValue = (sValue.length()>64)?sValue.substr(0,48):sValue;

          for(size_t s=0;s<sOutValue.length();s++)
            if(!(sOutValue[s]>=u'0'&&sOutValue[s]<=u'9'))return false;
          return true;
        }break;
      case 9:{//不支持此编码格式,无论如何都返回false
          return false;
        }break;
      case 10:{//长度不超过48
          sOutValue = (sValue.length()>48)?sValue.substr(0,48):sValue;

          size_t sLen = sOutValue.length();

          if(sLen<3)return false;

          for (size_t s = 1; s < sLen - 1; s++)
            if (!(sOutValue[s] >= u'0' && sOutValue[s] <= u'9'))
              return false;

          if (!((sOutValue[0] >= u'0' && sOutValue[0] <= u'9')||(sOutValue[0] >= u'A' && sOutValue[0] <= u'Z')))
            return false;

          size_t sLast = sLen - 1;
          if (!((sOutValue[sLast] >= u'0' && sValue[sLast] <= u'9')||(sOutValue[sLast] >= u'A' && sOutValue[sLast] <= u'Z')))
            return false;

          return true;
        }break;
      case 11:{//长度不超过48
          sOutValue = (sValue.length()>48)?sValue.substr(0,48):sValue;

          for(size_t s=0;s<sOutValue.length();s++)
            if(!(sOutValue[s]>=u'0'&&sOutValue[s]<=u'9'))return false;
          return true;
        }break;
      case 12:{//包含数字和A-F六个大写字母, 理论不限长度,长度可变,此程序限定64
          sOutValue = (sValue.length()>64)?sValue.substr(0,64):sValue;
          size_t sLen = sOutValue.length();
          for (size_t s = 0; s < sLen; s++)
            if (!((sOutValue[s] >= u'0' && sValue[s] <= u'9')||(sOutValue[s] >= u'A' && sOutValue[s] <= u'F')))
              return false;

          return true;
        }break;
      case 13:{//与code39雷同,最大支持128长度
          sOutValue = (sValue.length()>128)?sValue.substr(0,128):sValue;

          size_t sLen = sOutValue.length();

          if(sLen<3)return false;

          for (size_t s = 0; s < sLen; s++)
            if (!((sOutValue[s] >= u'0' && sOutValue[s] <= u'9')||(sOutValue[s] >= u'A' && sOutValue[s] <= u'Z') || sOutValue[s] == u'-' || sOutValue[s] == u' ' || sOutValue[s] == u'.' || sOutValue[s] == u'$' || sOutValue[s] == u'/' || sOutValue[s] == u'+' || sOutValue[s] == u'%' || sOutValue[s] == u'*'))
              return false;

          return true;
        }break;
      case 14:{//数字0-9和字符“-”,长度理论不限,此程序限定48
          sOutValue = (sValue.length()>48)?sValue.substr(0,48):sValue;
          size_t sLen = sOutValue.length();
          for (size_t s = 0; s < sLen; s++)
            if (!((sOutValue[s] >= u'0' && sValue[s] <= u'9')||sOutValue[s] == u'-'))
              return false;
          return true;
        }break;
      case 15:{//与Code39接近,支持更多字符,长度理论上没有限制,长度可变,此程序限定最大64
          sOutValue = (sValue.length()>64)?sValue.substr(0,64):sValue;

          size_t sLen = sOutValue.length();

          if(sLen<3)return false;

          for (size_t s = 0; s < sLen; s++)
            if (!((sOutValue[s] >= u'0' && sOutValue[s] <= u'9')||(sOutValue[s] >= u'A' && sOutValue[s] <= u'Z') || sOutValue[s] == u'-' || sOutValue[s] == u' ' || sOutValue[s] == u'.' || sOutValue[s] == u'$' || sOutValue[s] == u'/' || sOutValue[s] == u'+' || sOutValue[s] == u'%' || sOutValue[s] == u'*'))
              return false;

          return true;
        }break;
      }
    return false;
  }

核心绘制代码如下

/// 绘制条码
  /// \brief DrawBarCodeRender
  /// \param painter
  /// \param size
  ///
  void Lncf_QtBarcodeProc::DrawBarCodeRender(QPainter *painter,QSize size)
  {
    if(!pBarcodeItemObj){
        if(this->tCtrlsStyleData.bDrawBarBkgdClr){
            painter->setBrush(this->tCtrlsStyleData.cBkgColorsValue);
            painter->setPen(Qt::NoPen);
            double dBkgRadius = size.height()*this->tCtrlsStyleData.dFrameRadiusVal;
            painter->drawRoundedRect(QRectF(0,0,size.width(),size.height()),dBkgRadius,dBkgRadius);
          }

        if(this->tCtrlsStyleData.uBarBorderStyle!=0)
          DrawBarCodeBorder(painter,QSize(size.width(),size.height()));
        DrawBarCodesError(painter,QSize(size.width(),size.height()));
      }
    else{
        int    nCtrlWidth = size.width();                       //获取当前控件宽度
        double dCtlHeight = size.height();                      //获取当前控件高度

        int    nBcWidths = pBarcodeItemObj->width;              //设置条码原始宽度
        int    nBcHeight = pBarcodeItemObj->height;             //设置条码原始盖度
        float  nBcScalef = pBarcodeItemObj->scalef;             //设置条码原始比例

        double dCtlScales = 1.0;
        ///如果窗口小于条码则重新计算条码大小

        dCtlScales =nCtrlWidth / (pBarcodeItemObj->width+tCtrlsStyleData.uBarCodePadding*2); //计算条码原始与当前控件宽度比例
        pBarcodeItemObj->width = (pBarcodeItemObj->width * dCtlScales)-(this->tCtrlsStyleData.uBarCodePadding*2);
        pBarcodeItemObj->scalef = dCtlScales;
        pBarcodeItemObj->height = dCtlHeight -(this->tCtrlsStyleData.uBarCodePadding*2);

        //绘制背景
        if(this->tCtrlsStyleData.bDrawBarBkgdClr){
            painter->setBrush(this->tCtrlsStyleData.cBkgColorsValue);
            painter->setPen(Qt::NoPen);
            double dBkgRadius = size.height()*this->tCtrlsStyleData.dFrameRadiusVal;
            painter->drawRoundedRect(QRectF(0,0,size.width(),size.height()),dBkgRadius,dBkgRadius);
          }

        //绘制边框
        if(this->tCtrlsStyleData.uBarBorderStyle!=0)
          DrawBarCodeBorder(painter,QSize(size.width(),size.height()));

        painter->setPen(Qt::NoPen);

        //绘制条码
        if(CheckStringValide()){
            DrawBarCodesLines(painter,size);
            if(! (pBarcodeItemObj->flags & BARCODE_NO_ASCII) )
              DrawBarCodesTexts(painter,size);
          }
        else{
            DrawBarCodesError(painter,size);
          }

        pBarcodeItemObj->width = nBcWidths; // 恢复原状
        pBarcodeItemObj->height = nBcHeight;
        pBarcodeItemObj->scalef = nBcScalef;
      }
  }

  
  /// 绘制条码竖线
  /// \brief DrawBarCodesLines
  /// \param painter
  ///
  void Lncf_QtBarcodeProc::DrawBarCodesLines(QPainter *painter,QSize size)
  {
    double dLeftMargin =0;
    if(size.width()>pBarcodeItemObj->width+(int)tCtrlsStyleData.uBarCodePadding*2)
      dLeftMargin = (size.width()-pBarcodeItemObj->width)/2-(int)tCtrlsStyleData.uBarCodePadding*2;

    double dTopsMargin =0;
    if(size.height()>pBarcodeItemObj->width+(int)tCtrlsStyleData.uBarCodePadding*2)
      dTopsMargin = (size.height()-pBarcodeItemObj->height)/2-(int)tCtrlsStyleData.uBarCodePadding*2;

    int mode = '-';
    int i; /* text below bars */
    char * cBarcodePartial;
    double xpos = pBarcodeItemObj->margin + (pBarcodeItemObj->partial[0] - '0') * pBarcodeItemObj->scalef;

    int nLongScale = 10,nShortScale =0;
    if(tCtrlsStyleData.uBarCodeEncoder ==1||tCtrlsStyleData.uBarCodeEncoder ==2||tCtrlsStyleData.uBarCodeEncoder ==3||tCtrlsStyleData.uBarCodeEncoder ==6)
      nLongScale =5;

    QColor cBarColors=tCtrlsStyleData.cBarCodeLineClr;
    QColor cBarPrefix=tCtrlsStyleData.cPrefixBarColor;

    for (cBarcodePartial = pBarcodeItemObj->partial + 1, i = 1; *cBarcodePartial; cBarcodePartial++, i++)
      {
        /* special cases: '+' and '-' */
        if (*cBarcodePartial == '+' || *cBarcodePartial == '-'){
            mode = *cBarcodePartial; /* don't count it */
            i++;
            continue;
          }
        /* j is the width of this bar/space */
        int j = (isdigit (*cBarcodePartial))?*cBarcodePartial - '0'
                                           :*cBarcodePartial - 'a' + 1;

        if(this->tCtrlsStyleData.bRandomBarColor){
#if QT_DEPRECATED_SINCE(5, 15)
            cBarColors=QColor(QRandomGenerator::global()->bounded(193),QRandomGenerator::global()->bounded(193),QRandomGenerator::global()->bounded(193));
            cBarPrefix=QColor(QRandomGenerator::global()->bounded(193),QRandomGenerator::global()->bounded(193),QRandomGenerator::global()->bounded(193));
#else
            cBarColors=QColor(qrand()%193,qrand()%128,qrand()%193));
            cBarPrefix=QColor(qrand()%193,qrand()%128,qrand()%193));
#endif
          }

        double x0, y0, yr;
        if (i % 2)
          {
            x0 = pBarcodeItemObj->xoff + xpos;
            y0 = pBarcodeItemObj->yoff + pBarcodeItemObj->margin;
            yr = pBarcodeItemObj->height;
            if ( !(pBarcodeItemObj->flags & BARCODE_NO_ASCII) )
              {
                if (mode == '-'){
                    yr -= (isdigit(*cBarcodePartial) ? nLongScale : nShortScale) * pBarcodeItemObj->scalef;
                    painter->setBrush(isdigit(*cBarcodePartial)?cBarColors:cBarPrefix);
                  }
                else
                  {
                    y0 += (isdigit(*cBarcodePartial) ? 10 : 0) * pBarcodeItemObj->scalef;
                    yr -= (isdigit(*cBarcodePartial) ? 20 : 10) * pBarcodeItemObj->scalef;
                    painter->setBrush(isdigit(*cBarcodePartial)?cBarColors:cBarPrefix);
                  }
              }
            else{
                painter->setBrush(isdigit(*cBarcodePartial)?cBarColors:cBarPrefix);
              }

            QRectF rcLine = QRectF(x0+dLeftMargin, y0+dTopsMargin, (j * pBarcodeItemObj->scalef), yr);
            double dRadius = rcLine.width()*this->tCtrlsStyleData.dBarRadiusValue;
            painter->drawRoundedRect(rcLine, dRadius,dRadius);
          }
        xpos += j * pBarcodeItemObj->scalef;
      }

     //绘制下划线或上划线
  }

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值