当前位置: 首页 > news >正文

QT 驱动条码打印机(没有验证过)

这里的打印机是条码打印机,因为第一次接触这种设备,所以买了斑马的GK888t型条码打印机,据说ZPL语言就是斑马的杰作想必支持会好点。实际是,除了ZPL本身外,没有SDK,也没有DDK,所以,一切就只能靠搜索引擎帮忙了,这里感谢百度和谷歌啦。

写在开头:有些在网上找的内容忘了留网址,写该文时搜索相关内容补的网址,请原相关作者见谅。

粗略总结了6种方法,个人比较推荐第6第3种方法。如下:

1、直接打印(最简单)。
条码打印机可以当做普通打印机使用。所以,你用记事本、word等等只要有打印功能的,都可以打印。所以该方法就是使用Qt绘制图片、path什么的,然后打印即可。

2、把USB打印机映射到LPT端口。
参照:http://blog.sina.com.cn/s/blog_6d4dcdba0100xowi.html

这里我在本机不需要安装“Microsoft Loopback Adapter”,而是使用如下的方法:(gk888t是我共享的打印机名)
net use LPT2 \\127.0.0.1\gk888t

3、使用转意字符(需要ZPL语言,建议)。
参照:http://stackoverflow.com/questions/4442122/send-raw-zpl-to-zebra-printer-via-usb

一定要按上文方法设置转意字符。代码如下,不再阐述。QPrinter printer(QPrinter::PrinterResolution);
QPrintDialog *dlg = new QPrintDialog(&printer, this);if (dlg->exec() == QDialog::Accepted)
{QPainter p(&printer);p.drawText(0,0,"${^XA^FO10,100^BY3^BCN,100,Y,N,N^FDDC123456^FS^XZ}$");

…………
}

4、使用CUPs API(未完成)。
参照:http://stackoverflow.com/questions/5558248/qt-print-raw-text

粗试文中的方法,当时链接库没搞好,所以放弃了。

5、使用libusb-win32(可以)。
参照:http://sourceforge.net/apps/trac/libusb-win32/wiki
http://www.4ucode.com/Study/Topic/617136

特别声明:如果你和我一样是菜鸟,请注意,最好在试验该方法时在虚拟机内进行,不然,系统USB设备可能会统统罢工的。
参照testlibusb.c例程,这里贴一下打印的代码:别忘了在.pro文件添加
LIBS += ./libusb.a
这里我把libusb.a和源代码放在了一起,还有lusb0_usb.h头文件不要忘了,……udev = usb_open(dev);
if (udev)
{
char *sb = "^XA^FO10,100^BY3^BCN,100,Y,N,N^FDDAe123456^FS^XZ";
int ok = usb_claim_interface(udev,0);
printf("%d\n",ok);
ok = usb_bulk_write(udev,0x01,sb,50,1000);
printf("%d\n",ok);
…………但这里有个问题,一直没有搞定使用libusb同时又使用系统的打印机驱动模式,也就是说,在该模式下,无法使用打印服务访问打印机,不再支持直接打印。
这个不知是我的设置问题还是什么。折腾的时候发现,使用一种方法可以一起使用,但一旦系统重启就不再可以,同时,打印服务以及rpc服务均不正常,需要使用斑马自带的打印机安装程序重新安装,系统才能回复正常,但一重启依旧。

6、使用Win32 API打印原始数据(强烈建议)。
这可是微软的方法啊,不用在系统添加任何文件,同时又能保证打印机的正常使用,所以强烈建议。
参照:http://support.microsoft.com/kb/138594

在.pro文件添加
LIBS += D:\Qt\qtcreator-2.4.1\mingw\lib\libwinspool.a
注:我的mingw安装路径 D:\Qt\qtcreator-2.4.1\mingw。贴一段我用来试验该方法的源代码:
注意事项:qt creater是UNICODE环境,所以使用OpenPrinter等函数时会自动转为OpenPrinterW,这样就需要进行char到wchar的转换或者使用宏定义,请参看winspool.h的内容,觉得比较烦,所以就直接给它改成OpenPrinterA了(其它同)。

#include “widget.h”
#include “ui_widget.h”

#include
#include
#include
#include
#include <windows.h>
#include <winspool.h>
#include

BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount);
bool RawDataToPrinter(QString printerName,QStringList *barcode);

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}

Widget::~Widget()
{
delete ui;
}

void Widget::on_pushButton_clicked()
{
QPrinter printer(QPrinter::PrinterResolution);
QPrintDialog *dlg = new QPrintDialog(&printer, this);

if (dlg->exec() == QDialog::Accepted)
{
QPainter p(&printer);
//p.drawText(0,0,“ X A F O 10 , 10 0 B Y 3 B C N , 100 , Y , N , N F D D C 12345 6 F S X Z {^XA^FO10,100^BY3^BCN,100,Y,N,N^FDDC123456^FS^XZ} XAFO10,100BY3BCN,100,Y,N,NFDDC123456FSXZ”);
//p.drawText(0,0,“ X A F O 10 , 10 0 B Y 3 B C N , 100 , Y , N , N F D C D 12345 6 F S X Z {^XA^FO10,100^BY3^BCN,100,Y,N,N^FDCD123456^FS^XZ} XAFO10,100BY3BCN,100,Y,N,NFDCD123456FSXZ”);

QString printerName = printer.printerName();
QString lpData = tr(“XAFO10,100BY3BCN,100,Y,N,NFDDD123456FS^XZ”);
long dwCount = lpData.length();

QStringList sl;
sl.append(tr(“XAFO10,100BY3BCN,100,Y,N,NFDAB123456FS^XZ”));
sl.append(tr(“XAFO10,100BY3BCN,100,Y,N,NFDCD123456FS^XZ”));
sl.append(tr(“XAFO10,100BY3BCN,100,Y,N,NFDEF123456FS^XZ”));
if(RawDataToPrinter(printerName,&sl)==true)
{
qDebug() << “OK”;
}else
{
qDebug() << “NO”;
}

/if(RawDataToPrinter((char)printerName.toLocal8Bit().data(),(unsigned char*)lpData.toLocal8Bit().data(),dwCount) == true)
{
qDebug() << “OK”;
}else
{
qDebug() << “NO”;
}*/
}
delete dlg;
}

BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount)
{
HANDLE hPrinter;
DOC_INFO_1A DocInfo;
DWORD dwJob;
DWORD dwBytesWritten;

// Need a handle to the printer.
if(!OpenPrinterA(szPrinterName,&hPrinter,NULL))
{
return FALSE;
}

// Fill in the structure with info about this “document.”
DocInfo.pDocName = “BarCode”;
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = “RAW”;

// Inform the spooler the document is beginning.
if((dwJob = StartDocPrinterA(hPrinter,1,(PBYTE)&DocInfo)) == 0)
{
ClosePrinter(hPrinter);
return FALSE;
}

// Start a page.
if(!StartPagePrinter(hPrinter))
{
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return FALSE;
}

// Send the data to the printer.
if(!WritePrinter(hPrinter,lpData,dwCount,&dwBytesWritten))
{
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return FALSE;
}

if(!WritePrinter(hPrinter,lpData,dwCount,&dwBytesWritten))
{
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return FALSE;
}

// End the page.
if(!EndPagePrinter(hPrinter))
{
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return FALSE;
}

// Inform the spooler that the document is ending.
if(!EndDocPrinter(hPrinter))
{
ClosePrinter(hPrinter);
return FALSE;
}

// Tidy up the printer handle.
ClosePrinter(hPrinter);

// Check to see if correct number of bytes were written.
if(dwBytesWritten != dwCount)
{
QMessageBox::warning(0,QObject::tr(“打印”),QObject::tr(“打印输出数据与输入数据大小不相符”),QObject::tr(“确定(&E)”));
return FALSE;
}else
{
return TRUE;
}
}

bool RawDataToPrinter(QString printerName, QStringList *barcode)
{
HANDLE hPrinter;
DOC_INFO_1A DocInfo;
DWORD dwJob;
DWORD dwBytesWritten;
LPSTR szPrinterName;
long dwCount;

if(!(barcode->length() >0))
{
return false;
}

szPrinterName = (char*)printerName.toLocal8Bit().data();

//获取打印机的handle
if(!OpenPrinterA(szPrinterName,&hPrinter,NULL))
{
return false;
}

//填充打印文档的DOC_INFO_1A
DocInfo.pDocName = “BarCode”;
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = “RAW”;

//通知打印服务,准备开始打印文档
if((dwJob = StartDocPrinterA(hPrinter,1,(PBYTE)&DocInfo)) == 0)
{
ClosePrinter(hPrinter);
return false;
}

//开始一页的打印
if(!StartPagePrinter(hPrinter))
{
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return false;
}

foreach(QString str,*barcode)
{
//发送数据到打印机
dwCount = str.toLocal8Bit().length();
if(!WritePrinter(hPrinter,(unsigned char *)str.toLocal8Bit().data(),dwCount,&dwBytesWritten))
{
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return false;
}
//检查实际写入数据是否与原始数据大小相符
if(dwBytesWritten != dwCount)
{
QMessageBox::warning(0,QObject::tr(“打印”),QObject::tr(“打印输出数据与输入数据大小不相符”),QObject::tr(“确定(&E)”));
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return false;
}
}

//结束一页的打印
if(!EndPagePrinter(hPrinter))
{
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
return FALSE;
}

//通知打印服务,文档打印结束
if(!EndDocPrinter(hPrinter))
{
ClosePrinter(hPrinter);
return FALSE;
}

//收回handle
ClosePrinter(hPrinter);
return true;
}

以上即我当前所能使用的方法,希望能给大家带来帮助,如有不到之处希望当家指正。

相关文章:

QT 驱动条码打印机(没有验证过)

这里的打印机是条码打印机&#xff0c;因为第一次接触这种设备&#xff0c;所以买了斑马的GK888t型条码打印机&#xff0c;据说ZPL语言就是斑马的杰作想必支持会好点。实际是&#xff0c;除了ZPL本身外&#xff0c;没有SDK&#xff0c;也没有DDK&#xff0c;所以&#xff0c;一…...

Kafka介绍

目录 1&#xff0c;kafka简单介绍 2&#xff0c;kafka使用场景 3&#xff0c;kafka基本概念 kafka集群 数据冗余 分区的写入 读取分区数据 顺序消费 顺序消费典型的应用场景&#xff1a; 批量消费 提交策略 kafka如何保证高并发 零拷贝技术&#xff08;netty&#…...

Django使用uwsgi+nginx部署,admin没有样式解决办法

Django使用uwsginginx部署,admin没有样式解决办法 如果使用了虚拟环境则修改nginx.conf文件中的/static/路径为你虚拟环境的路径&#xff0c;没有使用虚拟环境则改为你python安装路径下的static server {listen 8008;server_name location; #改为自己的域名&#xff0c;没域名…...

穷举深搜暴搜回溯剪枝(3)

一)字母大小写全排列 784. 字母大小写全排列 - 力扣&#xff08;LeetCode&#xff09; 1)从每一个字符开始进行枚举&#xff0c;如果枚举的是一个数字字符&#xff0c;直接忽视 如果是字母的话&#xff0c;进行选择是变还是不变 2)当进行遍历到叶子结点的时候&#xff0c;直接将…...

Bash 脚本的参数等

bash 的 $值 $0 : 表示当前脚本的名称${BASH_SOURCE[0]} : 表示当前 Bash 脚本文件的路径&#xff0c;可以理解为 $0 的安全版本&#xff0c;防止被修改。$1 : 表示第一个参数&#xff0c;以此类推$ : 表示所有传入脚本的参数$UID : 表示当前用户的 ID 号。如果当前用户是 roo…...

从哪些方面学HTML技术? - 易智编译EaseEditing

学习HTML技术是前端开发的基础&#xff0c;它用于定义网页的结构和内容。以下是学习HTML技术时可以关注的方面&#xff1a; HTML基本语法&#xff1a; 了解HTML标签的基本语法和用法&#xff0c;学习如何创建HTML文档和元素。 常用HTML标签&#xff1a; 学习常用的HTML标签&…...

非阻塞IO

非阻塞IO fcntl 一个文件描述符, 默认都是阻塞IO。fcntl可以将某个文件描述符设置为非阻塞IO&#xff0c;先看一下文档介绍。 传入的cmd的值不同&#xff0c;后面追加的参数也不相同。 fcntl函数有5种功能: 复制一个现有的描述符&#xff08;cmd F_DUPFD&#xff09;。获得…...

Debian如何让multilib和交叉编译工具链共存

Debian一个槽点是gcc/g/gfortran-multilib和交叉编译工具链如gcc/g/gfortran-riscv64-linux-gnu会互相卸载&#xff0c;解决办法如下&#xff1a; 1、安装build-essential&#xff08;gcc/g/libc6-dev/make/dpkg-dev&#xff09;和gfortran&#xff0c;记下被安装的gcc版本&am…...

Flink之JDBC Sink

这里介绍一下Flink Sink中jdbc sink的使用方法,以mysql为例,这里代码分为两种,事务和非事务 非事务代码 import org.apache.flink.connector.jdbc.JdbcConnectionOptions; import org.apache.flink.connector.jdbc.JdbcExecutionOptions; import org.apache.flink.connector.…...

lifecycleScope Unresolved reference

描述 导入了lifecycle.lifecycleScope&#xff0c;但是在activity中使用lifecycleScope报错出现Unresolved reference找不到引用。 导包 import androidx.lifecycle.lifecycleScope使用 lifecycleScope.launch(Dispatchers.IO) {...}错误 方案 代码中的activity继承Activ…...

P5960 【模板】差分约束算法

【模板】差分约束算法 题目描述 给出一组包含 m m m 个不等式&#xff0c;有 n n n 个未知数的形如&#xff1a; { x c 1 − x c 1 ′ ≤ y 1 x c 2 − x c 2 ′ ≤ y 2 ⋯ x c m − x c m ′ ≤ y m \begin{cases} x_{c_1}-x_{c_1}\leq y_1 \\x_{c_2}-x_{c_2} \leq y_2 \\…...

VSCode---通过ctrl+鼠标滚动改变字体大小

打开设置然后在右边输editor.mouseWheelZoo勾选即可实现鼠标滚动改变字体大小 4.这种设置的字体大小是固定的...

视频监控汇聚平台EasyCVR视频分享页面WebRTC流地址播放不了是什么原因?

开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多…...

Libevent开源库的介绍与应用

libeventhttps://libevent.org/ 一、初识 1、libevent介绍 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库&#xff0c;主要有以下几个亮点&#xff1a;事件驱动&#xff08; event-driven&#xff09;&#xff0c;高性能;轻量级&#xff0c;专注于网络&#xff…...

【LNMP】LNMP

LNMP&#xff1a;是目前成熟的企业网站的应用模式之一&#xff0c;指的是一套协同工作的系统和相关软件&#xff1b;能够提供静态页面服务&#xff0c;也可以提供动态web服务 L Linux系统&#xff0c;操作系统N Nginx网站服务&#xff0c;前端&#xff0c;提供前端的静态…...

uniapp自定义头部导航栏

有时我们需要一些特殊的头部导航栏页面&#xff0c;取消传统的导航栏&#xff0c;来增加页面的美观度。 下面我就教大家如何配置&#xff1a; 一、效果图 二、实现 首先在uniapp中打开pages.json配置文件&#xff0c;在单个路由配置style里面设置导航栏样式​​​​​​nav…...

Django实现音乐网站 ⑹

使用Python Django框架制作一个音乐网站&#xff0c; 本篇主要是在添加编辑过程中对后台歌手功能优化及表模型名称修改、模型继承内容。 目录 表模型名称修改 模型继承 创建抽象基类 其他模型继承 更新表结构 歌手新增、编辑优化 表字段名称修改 隐藏单曲数和专辑数 姓…...

dubbo-helloworld示例

1、工程架构 2、创建模块 &#xff08;1&#xff09;创建父工程,引入公共依赖 pom.xml依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></depende…...

电脑ADB连接手机的方式通过网络无法adb连接手机的问题(已解决)

首先电脑要下载adb工具&#xff0c;将压缩包解压到C盘&#xff1a;https://download.csdn.net/download/qq_43445867/87975072 1、使用USB线连接 打开手机USB调试&#xff1b;PC端安装手机USB驱动。 1.打开DOS命令窗口&#xff0c;进入adb文件夹,输入adb.exe devices回车列出设…...

79 | Python数据分析篇 —— Pandas中groupby聚合操作和透视表基础

Pandas是Python中最常用的数据处理库之一,它提供了高效的数据结构和数据分析工具。在进行数据分析和机器学习等领域的工作时,Pandas是必不可少的库之一。本文将介绍Pandas中的groupby聚合操作和透视表,包括groupby操作、透视表的基础知识、练习题和答案。 文章目录 Pandas中…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)

小伙伴们&#xff0c;有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL&#xff0c; 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始&#xff0c;OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...