新建一个Qt Widgets Application项目,这里我起名为IdCardReader。然后在该项目路径下新建一个名为SDK的文件夹,将二代征SDK开发包/DLL下的这些文件复制到该路径中。(路径根据自己的修改)
在 .pro 中添加如下内容。(路径根据自己的修改)
INCLUDEPATH += SDK
HEADERS += SDK/SynPublic.h
LIBS += -L$$PWD/SDK -lSynIDCardAPI
代码时是参考C#中的示例,大体思路是开启两个定时器,一个定时器用于检测设备是否已连接到PC,另一个用于读取身份证信息。若有报错信息或读取成功都会以信号的形式发送,使用时连接IdCardReader实例的的信号即可。
IdCardReader.h
#ifndef IDCARDREADER_H
#define IDCARDREADER_H
#include
#include
#include
#include
#include
#include "SynPublic.h"
struct IdCard{
QString Name; //姓名
QString Sex; //性别
QString Nation; //名族
QString Born; //出生日期
QString Address; //住址
QString IDCardNo; //身份证号
QString GrantDept; //发证机关
QString UserLifeBegin; // 有效开始日期
QString UserLifeEnd; // 有效截止日期
QImage Photo; // 照片
IdCard(){}
IdCard(IDCardData idcard_data){
Name = QString::fromLocal8Bit(idcard_data.Name).trimmed();
Sex = QString::fromLocal8Bit(idcard_data.Sex).trimmed();
Nation = QString::fromLocal8Bit(idcard_data.Nation).trimmed();
Born = QString::fromLocal8Bit(idcard_data.Born).trimmed();
Address = QString::fromLocal8Bit(idcard_data.Address).trimmed();
IDCardNo = QString::fromLocal8Bit(idcard_data.IDCardNo).trimmed();
GrantDept = QString::fromLocal8Bit(idcard_data.GrantDept).trimmed();
UserLifeBegin = QString::fromLocal8Bit(idcard_data.UserLifeBegin).trimmed();
UserLifeEnd = QString::fromLocal8Bit(idcard_data.UserLifeEnd).trimmed();
Photo = QImage(idcard_data.PhotoFileName);
}
};
class IdCardReader : public QObject
{
Q_OBJECT
int m_iPort = -1, ilfOpen = 0;
int nRet;
bool bRet;
char cPath[256];
uchar pucIIN[4];
uchar pucSN[8];
char ucPath[256];
IDCardData data;
QTimer timer_check;
QTimer timer_read;
QTime prev_read_time;
public:
explicit IdCardReader(QObject *parent = nullptr);
~IdCardReader();
private slots:
void check();
void read();
signals:
void newIdCard(IdCard);
void detectedDevice();
void undetectedDevice();
void error(QString);
void warn(QString);
void msg(QString);
};
#endif // IDCARDREADER_H
IdCardReader.cpp
#include "IdCardReader.h"
#include
#include
//读取身份证成功后,距下一次读取的时间间隔
const int interval_s = 5;
IdCardReader::IdCardReader(QObject *parent) : QObject(parent)
{
connect(&timer_check, &QTimer::timeout, this, &IdCardReader::check);
connect(&timer_read, &QTimer::timeout, this, &IdCardReader::read);
timer_check.start(1000);
timer_read.start(100);
prev_read_time = QTime::currentTime().addSecs(-interval_s);
}
IdCardReader::~IdCardReader()
{
timer_read.stop();
timer_check.stop();
}
void IdCardReader::check()
{
m_iPort = Syn_FindUSBReader();
if (m_iPort > 0) {
Syn_SetPhotoPath(1, cPath); //设置照片路径 iOption 路径选项 0=C: 1=当前路径 2=指定路径
//cPhotoPath 绝对路径,仅在iOption=2时有效
Syn_SetPhotoType(0); //0 = bmp ,1 = jpg , 2 = base64 , 3 = WLT ,4 = 不生成
Syn_SetPhotoName(2); // 生成照片文件名 0=tmp 1=姓名 2=身份证号 3=姓名_身份证号
Syn_SetSexType(1); // 0=卡中存储的数据 1=解释之后的数据,男、女、未知
Syn_SetNationType(1); // 0=卡中存储的数据 1=解释之后的数据 2=解释之后加"族"
Syn_SetBornType(1); // 0=YYYYMMDD,1=YYYY年MM月DD日,2=YYYY.MM.DD,3=YYYY-MM-DD,4=YYYY/MM/DD
Syn_SetUserLifeBType(1); // 0=YYYYMMDD,1=YYYY年MM月DD日,2=YYYY.MM.DD,3=YYYY-MM-DD,4=YYYY/MM/DD
Syn_SetUserLifeEType(1, 1); // 0=YYYYMMDD(不转换),1=YYYY年MM月DD日,2=YYYY.MM.DD,3=YYYY-MM-DD,4=YYYY/MM/DD,
// 0=长期 不转换, 1=长期转换为 有效期开始+50年
Syn_ResetSAM(m_iPort, ilfOpen);
emit detectedDevice();
}
else {
emit undetectedDevice();
}
}
void IdCardReader::read()
{
if (m_iPort < 0)
return;
//距离上次读卡成功时间差大于5s,才继续检测
if (prev_read_time.secsTo(QTime::currentTime()) < interval_s)
return;
nRet = Syn_OpenPort(m_iPort);
if (nRet != 0) {
emit error("打开设备端口失败");
return;
}
nRet = Syn_SetMaxRFByte(m_iPort, 80, ilfOpen);
if (nRet != 0) {
emit error("设置射频适配器失败");
goto end;
return;
}
nRet = Syn_StartFindIDCard(m_iPort, pucIIN, ilfOpen);
if (nRet != 0) {
emit warn("未读取到卡片");
goto end;
return;
}
nRet = Syn_SelectIDCard(m_iPort, pucSN, ilfOpen);
if (nRet != 0) {
emit error("选卡出错");
goto end;
return;
}
nRet = Syn_ReadMsg(m_iPort, ilfOpen, &data);
if (nRet == 0 || nRet == 1) {
emit newIdCard(IdCard(data));
QFile::remove(data.PhotoFileName); //删除本地文件
emit msg("读卡成功");
prev_read_time = QTime::currentTime();
}
else {
emit error("读取身份证信息出错");
}
end:
Syn_ClosePort(m_iPort);
}
IdCardReaderDialog.ui
<ui version="4.0">
<class>IdCardReaderDialogclass>
<widget class="QDialog" name="IdCardReaderDialog">
<property name="geometry">
<rect>
<x>0x>
<y>0y>
<width>356width>
<height>382height>
rect>
property>
<property name="windowTitle">
<string>IdCardReaderDialogstring>
property>
<property name="styleSheet">
<string notr="true">QWidget#IdCardReaderDialog{
background: #ffffff;
}string>
property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QWidget" name="widget" native="true">
<property name="styleSheet">
<string notr="true">QWidget#widget{
border-radius: 10px;
background: #ffffff;
}
QLabel#label_photo{
border: 1px solid #000000;
}
QLabel{
color: #0000ee;
}string>
property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>4number>
property>
<property name="leftMargin">
<number>0number>
property>
<property name="topMargin">
<number>0number>
property>
<property name="rightMargin">
<number>0number>
property>
<property name="bottomMargin">
<number>0number>
property>
<item>
<widget class="QWidget" name="widget_info1" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>0number>
property>
<property name="leftMargin">
<number>0number>
property>
<property name="topMargin">
<number>0number>
property>
<property name="rightMargin">
<number>0number>
property>
<property name="bottomMargin">
<number>0number>
property>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0number>
property>
<property name="leftMargin">
<number>0number>
property>
<property name="topMargin">
<number>0number>
property>
<property name="rightMargin">
<number>0number>
property>
<property name="bottomMargin">
<number>0number>
property>
<item>
<widget class="QWidget" name="widget_4" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>姓名string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_name">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_5" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>性别string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_sex">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_6" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>民族string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_nation">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_7" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>出生string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_born">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QLabel" name="label_photo">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0horstretch>
<verstretch>0verstretch>
sizepolicy>
property>
<property name="minimumSize">
<size>
<width>102width>
<height>126height>
size>
property>
<property name="styleSheet">
<string notr="true"/>
property>
<property name="text">
<string>照片string>
property>
<property name="alignment">
<set>Qt::AlignCenterset>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_8" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>住址string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_address">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_9" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>公民身份证号码string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_idcard_No">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_10" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>签发机关string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_grant_dept">
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_11" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>有效期限string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_user_life_begin">
<property name="alignment">
<set>Qt::AlignCenterset>
property>
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>-string>
property>
widget>
item>
<item>
<widget class="QLineEdit" name="lineEdit_user_life_end">
<property name="alignment">
<set>Qt::AlignCenterset>
property>
<property name="readOnly">
<bool>truebool>
property>
widget>
item>
layout>
widget>
item>
layout>
widget>
item>
<item>
<widget class="QWidget" name="widget_status" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="spacing">
<number>20number>
property>
<item>
<widget class="QLabel" name="label_device_state">
<property name="text">
<string>-string>
property>
widget>
item>
<item>
<widget class="QLabel" name="label_work_state">
<property name="text">
<string>-string>
property>
widget>
item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontalenum>
property>
<property name="sizeHint" stdset="0">
<size>
<width>40width>
<height>20height>
size>
property>
spacer>
item>
layout>
widget>
item>
layout>
widget>
<resources/>
<connections/>
ui>
IdCardReaderDialog.h
#ifndef IDCARDREADERDIALOG_H
#define IDCARDREADERDIALOG_H
#include
#include "IdCardReader.h"
QT_BEGIN_NAMESPACE
namespace Ui { class IdCardReaderDialog; }
QT_END_NAMESPACE
class IdCardReaderDialog : public QDialog
{
Q_OBJECT
IdCardReader idcard_reader;
public:
IdCardReaderDialog(QWidget *parent = nullptr);
~IdCardReaderDialog();
private slots:
void recvIdCard(IdCard id_card);
private:
Ui::IdCardReaderDialog *ui;
};
#endif // IDCARDREADERDIALOG_H
IdCardReaderDialog.cpp
#include "IdCardReaderDialog.h"
#include "ui_IdCardReaderDialog.h"
#include
QString makeTextColor(QString text, QString color){
return "+color+">"+text+"";
}
IdCardReaderDialog::IdCardReaderDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::IdCardReaderDialog)
{
ui->setupUi(this);
this->setWindowTitle("身份证阅读器测试");
connect(&idcard_reader, &IdCardReader::detectedDevice, [=](){
ui->label_device_state->setText(makeTextColor("设备已连接", "green"));
});
connect(&idcard_reader, &IdCardReader::undetectedDevice, [=](){
ui->label_device_state->setText(makeTextColor("设备未连接", "red"));
});
connect(&idcard_reader, &IdCardReader::error, [=](QString text){
ui->label_work_state->setText(makeTextColor(text, "red"));
});
connect(&idcard_reader, &IdCardReader::warn, [=](QString text){
ui->label_work_state->setText(makeTextColor(text, "orange"));
});
connect(&idcard_reader, &IdCardReader::msg, [=](QString text){
ui->label_work_state->setText(makeTextColor(text, "green"));
});
connect(&idcard_reader, &IdCardReader::newIdCard, this, &IdCardReaderDialog::recvIdCard);
}
IdCardReaderDialog::~IdCardReaderDialog()
{
delete ui;
}
void IdCardReaderDialog::recvIdCard(IdCard id_card)
{
ui->lineEdit_name->setText(id_card.Name);
ui->lineEdit_sex->setText(id_card.Sex);
ui->lineEdit_nation->setText(id_card.Nation);
ui->lineEdit_born->setText(id_card.Born);
ui->lineEdit_address->setText(id_card.Address);
ui->lineEdit_idcard_No->setText(id_card.IDCardNo);
ui->lineEdit_grant_dept->setText(id_card.GrantDept);
ui->lineEdit_user_life_begin->setText(id_card.UserLifeBegin);
ui->lineEdit_user_life_end->setText(id_card.UserLifeEnd);
ui->label_photo->setPixmap(QPixmap::fromImage(id_card.Photo));
}