Commit 81d610f9 by NitefullWind

1. fm_mwrf32新增激活接口。 2. 使用单例重新实现reader。

parent 0b5a3989
......@@ -36,7 +36,8 @@ SOURCES += main.cpp\
backup/resend.cpp \
fmvipdispatcher.cpp \
fmnetwork.cpp \
windows/fmnumpad.cpp
windows/fmnumpad.cpp \
entityCard/reader.cpp
HEADERS += \
task/fmtask.h \
......@@ -64,7 +65,9 @@ HEADERS += \
fmnetwork.h \
readcfg.hpp \
reader.h \
windows/fmnumpad.h
windows/fmnumpad.h \
entityCard/readcfg.h \
entityCard/reader.h
FORMS += windows/forms/fmcouponwidget.ui \
windows/forms/fmloading.ui \
......@@ -75,7 +78,7 @@ FORMS += windows/forms/fmcouponwidget.ui \
windows/forms/fmvippanel.ui \
windows/forms/fmnumpad.ui
INCLUDEPATH += ../FMVipDC/ ./task ./windows ./backup
INCLUDEPATH += ../FMVipDC/ ./task ./windows ./backup ./entityCard
SUBDIRS += \
../FMVipDC/FMVipDC.pro
......
#include "reader.h"
Reader* Reader::instance()
{
static Reader reader;
return &reader;
}
Reader::Reader(QObject *parent) : QObject(parent)
{
s_end = true;
s_initsuc = false;
isDefaultPassword = false;
s_reader = NULL;
this->moveToThread(&m_thread);
m_thread.start();
QVariantMap map;
bool isOk = ReadCfg::readvalueforheadlist(CFG_FILENAME, CFG_SECTION_READER, map);
if(isOk) {
s_readerCfg.Port = map.value(CFG_READER_PORT).toInt();
s_readerCfg.Baud = map.value(CFG_READER_BAUD).toInt();
s_readerCfg.Section = map.value(CFG_READER_SECTION).toInt();
s_readerCfg.Password = map.value(CFG_READER_PWD).toString();
s_readerCfg.PasswordDefault = map.value(CFG_READER_PWD_DEFAULT).toString();
qDebug() << "Read values: " << s_readerCfg.Port << s_readerCfg.Baud << s_readerCfg.Section << s_readerCfg.Password << s_readerCfg.PasswordDefault;
} else {
qDebug() << "Read value for head list failed.";
}
}
Reader::~Reader()
{
disconnectReader();
}
bool Reader::readVipNO()
{
QString vipNo;
QString error;
while(s_end && !ReadCard(s_reader, s_readerCfg.Section, vipNo, error))
{
if(error == ReaderError.ConnectedError || error == ReaderError.PasswordError) {
qDebug() << "Readcard failed: " << error;
if(error == ReaderError.PasswordError) {
isDefaultPassword = !isDefaultPassword;
}
connectReader();
}
Sleep(500);
}
if(!s_end)
{
condition.wakeAll();
return false;
}
emit getVipNO(vipNo);
}
void Reader::connectReader()
{
qDebug() << "son:" <<QThread::currentThreadId() << "s_initsuc:" << s_initsuc << "s_reader: " << s_reader;
bool sign = true;
QString error;
if(s_end)
{
if(s_initsuc) {
DisConnectDevice(s_reader);
}
// do
// {
if(sign)
{
if(isDefaultPassword) {
sign = ConnectDevice(s_readerCfg.Port,
s_readerCfg.Baud,
s_readerCfg.Section,
s_readerCfg.Password,
s_reader,
error);
} else {
sign = ConnectDevice(s_readerCfg.Port,
s_readerCfg.Baud,
s_readerCfg.Section,
s_readerCfg.PasswordDefault,
s_reader,
error);
}
}
if(!sign) {
s_reader = NULL;
qDebug() << "Connect device failed: " << error;
}
else
s_initsuc = sign;
// Sleep(500);
// }while(s_end && !sign);
}
}
void Reader::disconnectReader()
{
s_end = false;
mutex.lock();
if(!condition.wait(&mutex, 2*1000))
{
m_thread.terminate();
m_thread.wait();
}
if(s_initsuc || s_reader > 0)
{
DisConnectDevice(s_reader);
s_reader = NULL;
s_initsuc = false;
}
mutex.unlock();
}
bool Reader::activateCard()
{
bool sign = false;
QString error;
if(s_initsuc) {
sign = ActivateCard(s_reader, s_readerCfg.Section, s_readerCfg.Password, error);
}
if(!sign) {
qDebug() << "Activate card failed: " << error;
}
return sign;
}
#ifndef READER_H
#define READER_H
#include "global.h"
#include "readcfg.h"
#include "../fmvip_card_reader/fm_mwrf32/fm_mwrf32.h"
#include <QMutex>
#include <QString>
#include <QObject>
#include <QThread>
#include <QWaitCondition>
#include <windows.h>
class Reader : public QObject
{
Q_OBJECT
public:
static Reader* instance();
void connectReader();
void resetEnd() {s_end = false;}
~Reader();
// 读卡器错误
struct {
QString ConnectedError = "open device failed";
QString PasswordError = "check password failure";
} ReaderError;
// 读卡器配置
struct ReaderCfg{
int Port;
int Baud;
int Section;
QString Password;
QString PasswordDefault;
};
private:
Reader(QObject *parent = 0);
private:
bool s_end;
bool s_initsuc;
bool isDefaultPassword;
QMutex mutex;
QWaitCondition condition;
HANDLE s_reader;
QThread m_thread;
ReaderCfg s_readerCfg;
signals:
void getVipNO(QString VipNO);
public slots:
void disconnectReader();
bool readVipNO();
bool activateCard();
};
#endif // READER_H
......@@ -80,6 +80,7 @@ struct{
const QString FM_Type = "FM_Type";
const QString TransId = "trans_id";
const QString Member_sign = "member_sign";
const QString IsActive = "is_active";
const QString Name = "name";
const QString Birthday = "birthday";
......@@ -218,5 +219,6 @@ extern bool g_init_reader_flg;
#define CFG_READER_SECTION "section"
#define CFG_READER_BAUD "baud"
#define CFG_READER_PWD "password"
#define CFG_READER_PWD_DEFAULT "password_default"
#endif // GLOBAL_H
......@@ -5,6 +5,7 @@
#include "reader.h"
#include "include/fmutils/fmutils.hpp"
#include <QWidget>
#include "reader.h"
//global.h 中声明 读卡器是否初始化||初始化是否成功标识
bool g_init_reader_flg = false;
......@@ -22,7 +23,10 @@ int main(int argc, char *argv[])
auto reSend = new ReSend();
reSend->start();
qInstallMessageHandler(customMessageHandler);
// qInstallMessageHandler(customMessageHandler);
// 连接读卡器
Reader::instance()->connectReader();
QWidget w;
w.show();
......
#ifndef READER_HPP
#define READER_HPP
#include "global.h"
#include "readcfg.hpp"
#include "../fmvip_card_reader/fm_mwrf32/fm_mwrf32.h"
#include <QString>
#include <QObject>
#include <QThread>
#include <windows.h>
class Reader : public QObject
{
Q_OBJECT
public:
Reader()
{
s_end = true;
r_end = false;
s_initsuc = false;
s_reader = NULL;
this->moveToThread(&m_thread);
m_thread.start();
}
public slots:
bool readVipNO()
{
QString vipNo;
QString error;
bool sign = false;
//HANDLE s_reader = NULL;
r_end = true;
qDebug() << "son:" <<QThread::currentThreadId() << "s_initsuc:" << s_initsuc;
if(s_end && !s_initsuc)
{
do
{
QVariantMap map;
sign = ReadCfg::readvalueforheadlist(CFG_FILENAME, CFG_SECTION_READER, map);
//qDebug() << map;
if(sign)
sign = ConnectDevice(map.value(CFG_READER_PORT).toInt(),
map.value(CFG_READER_BAUD).toInt(),
map.value(CFG_READER_SECTION).toInt(),
map.value(CFG_READER_PWD).toString(),
s_reader,
error);
if(!sign)
s_reader = NULL;
else
s_initsuc = sign;
Sleep(500);
}while(s_end && !sign);
}
qDebug() << "s_reader" << s_reader;
while(s_end && !ReadCard(s_reader, 1, vipNo, error))
Sleep(500);
if(!s_end)
{
r_end = false;
return false;
}
emit getVipNO(vipNo);
r_end = false;
}
void disconnectReader()
{
s_end = false;
while(r_end)
Sleep(500);
if(s_initsuc || s_reader > 0)
{
DisConnectDevice(s_reader);
s_reader = NULL;
s_initsuc = false;
}
}
signals:
void getVipNO(QString VipNO);
private:
bool s_end;
bool r_end;
bool s_initsuc;
HANDLE s_reader;
QThread m_thread;
};
#endif // READER_HPP
......@@ -39,7 +39,6 @@ void TaskLogin::onLogin()
// 认证失败
if(getServerJsonValue(PosProps.StatusCode).toInt() != FM_API_SUCCESS) {
FMMsgWnd::FailureWnd(serverRspJsonObj[ServerProps(PosProps.Msg)].toString());
qDebug() << "********************1111";
emit starReader();
}
// 认证成功但限制用支付码
......@@ -62,6 +61,7 @@ void TaskLogin::onLogin()
session()->addData(PosProps.Mobile, getServerJsonValue(PosProps.Mobile).toString());
session()->addData(PosProps.Fm_open_id, account);
session()->addData(PosProps.Score, getServerJsonValue(PosProps.Score).toInt());
session()->addData(PosProps.IsActive, getServerJsonValue(PosProps.IsActive).toInt());
// QMap<QString, QVariant> couponMap;
// for (auto value : getServerJsonValue(PosProps.CouponList).toArray())
......
......@@ -6,6 +6,7 @@
#include "fmmsgwnd.h"
#include <QJsonDocument>
#include <QJsonObject>
#include "reader.h"
TaskManage::TaskManage(QJsonObject &jsonObj, QObject *parent):
FMTask(jsonObj, FM_Manage, 0, parent),
......@@ -64,6 +65,11 @@ void TaskManage::onLock()
void TaskManage::onActivate()
{
bool isOk = Reader::instance()->activateCard();
if(!isOk) {
FMMsgWnd::FailureWnd("fmv: 激活卡时写卡失败!");
return;
}
childTask = new TaskCardActive(posReqJsonObj, this->session());
doChildTask();
}
......
#include "taskothers.h"
#include "reader.h"
/// 优惠券查询
TaskCoupon::TaskCoupon(QJsonObject &jsonObj, Session *session, QObject *parent)
......
#ifndef TASKPAY_H
#define TASKPAY_H
#include "fmtask.h"
#include "../reader.h"
#include <QThread>
#include "taskothers.h"
......
......@@ -5,6 +5,7 @@
#include <QMutex>
#include "fmloading.h"
#include "fmnumpad.h"
#include "reader.h"
FMVipLogin::FMVipLogin(QDialog *parent) :
FMVipWnd(parent),
......@@ -12,8 +13,8 @@ FMVipLogin::FMVipLogin(QDialog *parent) :
{
numpad = NULL;
ui->setupUi(this);
connect(this, &FMVipLogin::startreader, &m_reader, &Reader::readVipNO);
connect(&m_reader, &Reader::getVipNO, this, &FMVipLogin::readVipNO);
connect(this, &FMVipLogin::startreader, Reader::instance(), &Reader::readVipNO);
connect(Reader::instance(), &Reader::getVipNO, this, &FMVipLogin::readVipNO);
emit startreader();
ui->login_edit->setFocus();
qDebug() << "main:" <<QThread::currentThreadId();
......@@ -22,7 +23,6 @@ FMVipLogin::FMVipLogin(QDialog *parent) :
FMVipLogin::~FMVipLogin()
{
qDebug() << "des FMVipLogin";
m_reader.disconnectReader();
delete ui;
if(numpad != NULL)
{
......
......@@ -2,7 +2,6 @@
#define FMVIPLOGIN_H
#include "fmvipwnd.h"
#include "reader.h"
class QNetworkReply;
......@@ -41,7 +40,6 @@ private slots:
void on_clean_numpad();
private:
Ui::FMVipLogin *ui;
Reader m_reader;
FMNumPad *numpad;
};
......
......@@ -30,6 +30,12 @@ void FMVipPanel::initWnd(Session *session)
ui->bir_label->setText(session->data(PosProps.Birthday).toString());
ui->point_label->setText(QString::number(session->data(PosProps.Score).toInt()));
int isActived = session->data(PosProps.IsActive).toInt();
if(isActived == 0) {
ui->fund_btn->setStyleSheet("#fund_btn { background: rgb(166,166,166);}");
ui->fund_btn->setEnabled(false);
}
ui->fund_btn->setFocus();
}
......
No preview for this file type
#include "fm_mwrf32.h"
#include "mwdll/mwrf32.h"
#include <QCryptographicHash>
bool ConnectDevice(int port, int baud, int sector, const QString password, HANDLE &handle, QString &error)
{
......@@ -17,12 +18,14 @@ bool ConnectDevice(int port, int baud, int sector, const QString password, HANDL
error = "load key error";
return false;
}
rf_beep(handle,30);
return true;
}
bool ReadCard(const HANDLE handle, int sector, QString &vipNo, QString &error)
{
int st;
// 寻卡
unsigned long snr; //卡片序列号
st = rf_card(handle, 0, &snr);
if(st!=0)
......@@ -30,12 +33,14 @@ bool ReadCard(const HANDLE handle, int sector, QString &vipNo, QString &error)
error = "could not find the card";
return false;
}
// 鉴权
st = rf_authentication(handle, 0, sector);
if(st!=0)
{
error = "check password failure";
return false;
}
// 读卡号
unsigned char rdata[32];
ZeroMemory(rdata,32);
st = rf_read(handle, sector*4, rdata);
......@@ -45,6 +50,24 @@ bool ReadCard(const HANDLE handle, int sector, QString &vipNo, QString &error)
return false;
}
vipNo = QString::fromLatin1((char*)rdata);
// 读效验数据
QString keyData;
ZeroMemory(rdata,32);
st = rf_read(handle, sector*4+1, rdata);
if(st!=0)
{
error = "read key_data error";
return false;
}
keyData = QString::fromLatin1((char*)rdata);
// 对比数据
if(keyData.compare(QCryptographicHash::hash(QString("%1%2").arg(vipNo,MD5_KEY).toLatin1(), QCryptographicHash::Md5).toHex().mid(8, 16)))
{
error = "check key_data error";
return false;
}
rf_beep(handle,30);
return true;
}
......@@ -52,3 +75,57 @@ void DisConnectDevice(const HANDLE handle)
{
rf_exit(handle);
}
bool ActivateCard(const HANDLE handle, int sector, const QString newPassword, QString &error)
{
int st;
QString vipNo;
// 寻卡
unsigned long snr; //卡片序列号
st = rf_card(handle, 0, &snr);
if(st!=0)
{
error = "could not find the card";
return false;
}
// 鉴权
st = rf_authentication(handle, 0, sector);
if(st!=0)
{
error = "check password failure";
return false;
}
// 读卡号
unsigned char rdata[32];
ZeroMemory(rdata,32);
st = rf_read(handle, sector*4, rdata);
if(st!=0)
{
error = "read data error";
return false;
}
vipNo = QString::fromLatin1((char*)rdata);
// 写入效验数据
QByteArray keyData = QCryptographicHash::hash(QString("%1%2").arg(vipNo,MD5_KEY).toLatin1(), QCryptographicHash::Md5);
st = rf_write(handle, sector*4+1, (unsigned char*)keyData.toHex().mid(8, 16).data());
if(st!=0)
{
error = "write data error";
return false;
}
// 修改密码
QByteArray tmpData = newPassword.toLatin1();
char* key= tmpData.data();
unsigned char wkey[7];
ZeroMemory(wkey, 7);
a_hex(key, wkey, 12);
st= rf_changeb3(handle, sector, wkey, 0, 0, 0, 1, 0, wkey);
if(st!=0)
{
error = "change password error";
return false;
}
rf_beep(handle,30);
return true;
}
......@@ -5,6 +5,8 @@
#include <windows.h>
#include <QString>
#define MD5_KEY "HzdBhXmf"
/* 功能:连接读卡器设备
* 参数:[1]端口号[2]波特率[3]扇区[4]扇区密码[5_out]设备句柄[6_out]错误原因
* 返回:成功true
......@@ -17,6 +19,12 @@ FM_MWRF32SHARED_EXPORT bool ConnectDevice(int port, int baud, int sector, const
* */
FM_MWRF32SHARED_EXPORT void DisConnectDevice(const HANDLE handle);
/* 功能:激活卡片
* 参数:[1]设备句柄[2]新的读卡密码[3]错误信息[4]默认密码
* 返回:成功true
* */
FM_MWRF32SHARED_EXPORT bool ActivateCard(const HANDLE handle, int sector, const QString newPassword, QString& error);
/* 功能:读取会员号
* 参数:[1]设备句柄[2]要读取的扇区号[3_out]会员号[4_out]错误原因
* 返回:成功true
......
#include "activateworker.h"
#include <QDebug>
#include <QDateTime>
ActivateWorker::ActivateWorker()
{
}
void ActivateWorker::SetHandle(HANDLE handle)
{
m_handle = handle;
}
void ActivateWorker::Stop()
{
m_bStop = true;
}
void ActivateWorker::run()
{
m_bStop = false;
while(!m_bStop)
{
QString error;
bool result;
result = ActivateCard(m_handle, 1, "111111111111", error);
qDebug() << QDateTime::currentDateTime() << result << error;
emit activeted(result, error);
Sleep(300);
}
}
#ifndef ACTIVATEWORKER_H
#define ACTIVATEWORKER_H
#include <QThread>
#include "../fm_mwrf32/fm_mwrf32.h"
class ActivateWorker : public QThread
{
Q_OBJECT
public:
ActivateWorker();
void SetHandle(HANDLE handle);
void Stop();
protected:
void run();
private:
bool m_bStop;
HANDLE m_handle;
signals:
void activeted(bool,QString);
};
#endif // ACTIVATEWORKER_H
......@@ -2,6 +2,7 @@
#include "ui_mainwindow.h"
#include "../fm_mwrf32/fm_mwrf32.h"
#include <QDebug>
#include <QCryptographicHash>
HANDLE handle;
MainWindow::MainWindow(QWidget *parent) :
......@@ -9,6 +10,11 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pbt1->setEnabled(false);
ui->pbt1_2->setEnabled(false);
ui->pbt2->setEnabled(false);
connect(&m_worker, SIGNAL(activeted(bool, QString)), this, SLOT(onActivated(bool, QString)));
}
MainWindow::~MainWindow()
......@@ -16,15 +22,57 @@ MainWindow::~MainWindow()
delete ui;
}
void MainWindow::on_pushButton_clicked()
void MainWindow::on_pbt0_clicked()
{
QString error("NULL");
qDebug() << ConnectDevice(2, 9600, 1, "ffffffffffff", handle, error) << error;
QString error;
if(ConnectDevice(4, 9600, 1, "111111111111", handle, error))
{
ui->label->setText("连接设备成功!");
ui->pbt1->setEnabled(true);
ui->pbt2->setEnabled(true);
}else
{
ui->label->setText("连接设备失败!");
}
}
void MainWindow::on_pushButton_2_clicked()
void MainWindow::on_pbt1_clicked()
{
m_worker.SetHandle(handle);
m_worker.start();
ui->pbt1->setEnabled(false);
ui->pbt1_2->setEnabled(true);
ui->pbt2->setEnabled(false);
}
void MainWindow::on_pbt2_clicked()
{
QString error;
QString vipNo;
QString error("NULL");
qDebug() << ReadCard(handle, 1, vipNo, error) << vipNo << error;
if(ReadCard(handle, 1, vipNo, error))
{
ui->label_3->setText(vipNo);
}else
{
ui->label_3->setText(error);
}
}
void MainWindow::onActivated(bool result, QString error)
{
if(result)
{
ui->label_2->setText("激活成功!");
}else
{
ui->label_2->setText(error);
}
}
void MainWindow::on_pbt1_2_clicked()
{
m_worker.Stop();
ui->pbt1->setEnabled(true);
ui->pbt1_2->setEnabled(false);
ui->pbt2->setEnabled(true);
}
......@@ -2,6 +2,7 @@
#define MAINWINDOW_H
#include <QMainWindow>
#include "activateworker.h"
namespace Ui {
class MainWindow;
......@@ -16,12 +17,21 @@ public:
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pbt0_clicked();
void on_pushButton_2_clicked();
void on_pbt1_clicked();
void on_pbt2_clicked();
void on_pbt1_2_clicked();
private:
Ui::MainWindow *ui;
ActivateWorker m_worker;
public slots:
void onActivated(bool, QString);
};
#endif // MAINWINDOW_H
......@@ -6,60 +6,156 @@
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>347</height>
<width>528</width>
<height>540</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="pbt0">
<property name="geometry">
<rect>
<x>150</x>
<y>60</y>
<width>75</width>
<height>23</height>
<x>70</x>
<y>110</y>
<width>111</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string>连接</string>
<string>连接读卡器</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<widget class="QPushButton" name="pbt1">
<property name="geometry">
<rect>
<x>60</x>
<y>284</y>
<width>81</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>开始激活</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>270</x>
<y>30</y>
<width>131</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>未连接设备!</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="pbt2">
<property name="geometry">
<rect>
<x>150</x>
<y>130</y>
<width>75</width>
<height>23</height>
<y>420</y>
<width>81</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>读卡</string>
<string>读卡</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>120</x>
<y>260</y>
<width>141</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QMenuBar" name="menuBar">
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>23</height>
<x>80</x>
<y>374</y>
<width>231</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QPushButton" name="pbt1_2">
<property name="geometry">
<rect>
<x>240</x>
<y>284</y>
<width>81</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>停止激活</string>
</property>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>101</width>
<height>51</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>端口号:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget_2">
<property name="geometry">
<rect>
<x>130</x>
<y>30</y>
<width>101</width>
<height>51</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>波特率:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
</layout>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
......
......@@ -13,9 +13,11 @@ TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
mainwindow.cpp \
activateworker.cpp
HEADERS += mainwindow.h
HEADERS += mainwindow.h \
activateworker.h
FORMS += mainwindow.ui
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment