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 驱动条码打印机(没有验证过)
这里的打印机是条码打印机,因为第一次接触这种设备,所以买了斑马的GK888t型条码打印机,据说ZPL语言就是斑马的杰作想必支持会好点。实际是,除了ZPL本身外,没有SDK,也没有DDK,所以,一…...

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

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

穷举深搜暴搜回溯剪枝(3)
一)字母大小写全排列 784. 字母大小写全排列 - 力扣(LeetCode) 1)从每一个字符开始进行枚举,如果枚举的是一个数字字符,直接忽视 如果是字母的话,进行选择是变还是不变 2)当进行遍历到叶子结点的时候,直接将…...
Bash 脚本的参数等
bash 的 $值 $0 : 表示当前脚本的名称${BASH_SOURCE[0]} : 表示当前 Bash 脚本文件的路径,可以理解为 $0 的安全版本,防止被修改。$1 : 表示第一个参数,以此类推$ : 表示所有传入脚本的参数$UID : 表示当前用户的 ID 号。如果当前用户是 roo…...

从哪些方面学HTML技术? - 易智编译EaseEditing
学习HTML技术是前端开发的基础,它用于定义网页的结构和内容。以下是学习HTML技术时可以关注的方面: HTML基本语法: 了解HTML标签的基本语法和用法,学习如何创建HTML文档和元素。 常用HTML标签: 学习常用的HTML标签&…...

非阻塞IO
非阻塞IO fcntl 一个文件描述符, 默认都是阻塞IO。fcntl可以将某个文件描述符设置为非阻塞IO,先看一下文档介绍。 传入的cmd的值不同,后面追加的参数也不相同。 fcntl函数有5种功能: 复制一个现有的描述符(cmd F_DUPFD)。获得…...
Debian如何让multilib和交叉编译工具链共存
Debian一个槽点是gcc/g/gfortran-multilib和交叉编译工具链如gcc/g/gfortran-riscv64-linux-gnu会互相卸载,解决办法如下: 1、安装build-essential(gcc/g/libc6-dev/make/dpkg-dev)和gfortran,记下被安装的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,但是在activity中使用lifecycleScope报错出现Unresolved reference找不到引用。 导包 import androidx.lifecycle.lifecycleScope使用 lifecycleScope.launch(Dispatchers.IO) {...}错误 方案 代码中的activity继承Activ…...
P5960 【模板】差分约束算法
【模板】差分约束算法 题目描述 给出一组包含 m m m 个不等式,有 n n n 个未知数的形如: { 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能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多…...

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

【LNMP】LNMP
LNMP:是目前成熟的企业网站的应用模式之一,指的是一套协同工作的系统和相关软件;能够提供静态页面服务,也可以提供动态web服务 L Linux系统,操作系统N Nginx网站服务,前端,提供前端的静态…...
uniapp自定义头部导航栏
有时我们需要一些特殊的头部导航栏页面,取消传统的导航栏,来增加页面的美观度。 下面我就教大家如何配置: 一、效果图 二、实现 首先在uniapp中打开pages.json配置文件,在单个路由配置style里面设置导航栏样式nav…...

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

dubbo-helloworld示例
1、工程架构 2、创建模块 (1)创建父工程,引入公共依赖 pom.xml依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></depende…...
电脑ADB连接手机的方式通过网络无法adb连接手机的问题(已解决)
首先电脑要下载adb工具,将压缩包解压到C盘:https://download.csdn.net/download/qq_43445867/87975072 1、使用USB线连接 打开手机USB调试;PC端安装手机USB驱动。 1.打开DOS命令窗口,进入adb文件夹,输入adb.exe devices回车列出设…...
79 | Python数据分析篇 —— Pandas中groupby聚合操作和透视表基础
Pandas是Python中最常用的数据处理库之一,它提供了高效的数据结构和数据分析工具。在进行数据分析和机器学习等领域的工作时,Pandas是必不可少的库之一。本文将介绍Pandas中的groupby聚合操作和透视表,包括groupby操作、透视表的基础知识、练习题和答案。 文章目录 Pandas中…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...