HGSaneUI中实现选择设备和扫描对话框

This commit is contained in:
luoliangyi 2023-03-29 18:04:59 +08:00
parent f75c49dff4
commit 2e41e33a44
6 changed files with 255 additions and 60 deletions

View File

@ -7,8 +7,16 @@ int show_devlist_ui(SANEAPI* saneApi, HGWindow parent, SANE_Handle *handle, char
{
if (nullptr == saneApi || nullptr == handle)
return -1;
if (nullptr == qApp)
{
#ifdef HG_CMP_MSC
// 创建WIN32窗口
return -2;
#else
return -2;
#endif
}
QWidget *qParent = nullptr;
#ifdef HG_CMP_MSC
@ -40,8 +48,17 @@ int show_setting_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent)
{
if (nullptr == saneApi || nullptr == handle)
return -1;
if (nullptr == qApp)
{
#ifdef HG_CMP_MSC
// 创建WIN32窗口
return -2;
#else
return -2;
#endif
}
return 0;
}
@ -49,7 +66,27 @@ int show_scan_ui(SANEAPI* saneApi, SANE_Handle handle, HGWindow parent, show_sca
{
if (nullptr == saneApi || nullptr == handle)
return -1;
if (nullptr == qApp)
{
#ifdef HG_CMP_MSC
// 创建WIN32窗口
return -2;
#else
return -2;
#endif
}
QWidget *qParent = nullptr;
#ifdef HG_CMP_MSC
qParent = QWidget::find((WId)parent);
if (nullptr != parent && nullptr == qParent)
return -2;
#else
qParent = parent;
#endif
Dialog_Device_Scan dlg(saneApi, handle, callback, callbackParam, qParent);
dlg.exec();
return 0;
}

View File

@ -1,18 +1,28 @@
#include "dialog_device_scan.h"
#include "ui_dialog_device_scan.h"
Dialog_Device_Scan::Dialog_Device_Scan(SANE_Handle dev, QWidget *parent) :
Dialog_Device_Scan::Dialog_Device_Scan(SANEAPI* saneApi, SANE_Handle dev,
show_scan_ui_image_callback callback, void *callbackParam, QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog_Device_Scan)
{
ui->setupUi(this);
memcpy(&m_saneAPI, saneApi, sizeof(SANEAPI));
m_saneDev = dev;
m_callback = callback;
m_callbackParam = callbackParam;
m_buffer = NULL;
m_bufferSize = 0;
m_stopThread = HGFALSE;
m_thread = NULL;
connect(this, SIGNAL(eventFunc(unsigned int, QString)), this, SLOT(on_eventFunc(unsigned int, QString)), Qt::QueuedConnection);
connect(this, SIGNAL(eventFunc(QString)), this, SLOT(on_eventFunc(QString)), Qt::QueuedConnection);
connect(this, SIGNAL(newImage(void *, void *)), this, SLOT(on_newImage(void *, void *)), Qt::QueuedConnection);
ui->pushButton_Continue->setEnabled(false);
ui->pushButton_Continue->setEnabled(true);
ui->pushButton_Cancel->setEnabled(false);
ui->pushButton_Complete->setEnabled(false);
ui->pushButton_Complete->setEnabled(true);
on_pushButton_Continue_clicked();
}
@ -22,14 +32,39 @@ Dialog_Device_Scan::~Dialog_Device_Scan()
delete ui;
}
void Dialog_Device_Scan::on_eventFunc(HGUInt error, QString errInfo)
void Dialog_Device_Scan::on_eventFunc(QString errInfo)
{
ui->label->setText(errInfo);
m_stopThread = HGTRUE;
m_saneAPI.sane_cancel_api(m_saneDev);
HGBase_CloseThread(m_thread);
m_thread = NULL;
free(m_buffer);
m_buffer = NULL;
m_bufferSize = 0;
ui->pushButton_Continue->setEnabled(true);
ui->pushButton_Cancel->setEnabled(false);
ui->pushButton_Complete->setEnabled(true);
}
void Dialog_Device_Scan::on_newImage(void *format, void *data)
{
SANE_Parameters *format2 = (SANE_Parameters *)format;
SANE_Byte *data2 = (HGByte *)data;
if (NULL != m_callback)
m_callback(format2, data2, m_callbackParam);
delete [] data2;
delete format2;
}
void Dialog_Device_Scan::on_pushButton_Cancel_clicked()
{
m_saneAPI.sane_cancel_api(m_saneDev);
}
void Dialog_Device_Scan::on_pushButton_Complete_clicked()
@ -39,5 +74,92 @@ void Dialog_Device_Scan::on_pushButton_Complete_clicked()
void Dialog_Device_Scan::on_pushButton_Continue_clicked()
{
SANE_Parameters params;
memset(&params, 0, sizeof(SANE_Parameters));
SANE_Status stat = m_saneAPI.sane_get_parameters_api(m_saneDev, &params);
assert(SANE_STATUS_GOOD == stat);
m_bufferSize = 5000 * 4000;
m_buffer = (HGByte *)malloc(m_bufferSize);
if (NULL == m_buffer)
{
ui->label->setText(tr("out of memory"));
return;
}
m_stopThread = HGFALSE;
HGBase_OpenThread(ThreadFunc, this, &m_thread);
ui->pushButton_Continue->setEnabled(false);
ui->pushButton_Cancel->setEnabled(true);
ui->pushButton_Complete->setEnabled(false);
ui->label->setText(tr("正在扫描......"));
}
void HGAPI Dialog_Device_Scan::ThreadFunc(HGThread thread, HGPointer param)
{
Dialog_Device_Scan* p = (Dialog_Device_Scan*)param;
SANE_Status stat = p->m_saneAPI.sane_start_api(p->m_saneDev);
if (SANE_STATUS_GOOD != stat)
{
emit p->eventFunc(tr(p->m_saneAPI.sane_strstatus_api(stat)));
return;
}
while (!p->m_stopThread)
{
SANE_Parameters params;
memset(&params, 0, sizeof(SANE_Parameters));
SANE_Status stat1 = p->m_saneAPI.sane_get_parameters_api(p->m_saneDev, &params);
SANE_Int readSize = 0;
SANE_Status stat2 = SANE_STATUS_GOOD;
while (readSize < p->m_bufferSize)
{
SANE_Int len = 0;
stat2 = p->m_saneAPI.sane_read_api(p->m_saneDev, p->m_buffer + readSize, p->m_bufferSize - readSize, &len);
readSize += len;
if (SANE_STATUS_GOOD != stat2)
{
break;
}
}
if (SANE_STATUS_GOOD == stat2)
{
// m_bufferSize空间不够
emit p->eventFunc(tr(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_INVAL)));
break;
}
else if (SANE_STATUS_EOF == stat2)
{
if (0 == readSize)
{
emit p->eventFunc(tr("扫描完成"));
break;
}
else if (SANE_STATUS_GOOD != stat1 || readSize != params.bytes_per_line * params.lines)
{
emit p->eventFunc(tr(p->m_saneAPI.sane_strstatus_api(SANE_STATUS_INVAL)));
break;
}
}
else if (SANE_STATUS_CANCELLED == stat2)
{
break;
}
else
{
emit p->eventFunc(tr(p->m_saneAPI.sane_strstatus_api(stat2)));
break;
}
SANE_Parameters *format = new SANE_Parameters;
memcpy(format, &params, sizeof(SANE_Parameters));
SANE_Byte *data = new HGByte [readSize];
memcpy(data, p->m_buffer, readSize);
emit p->newImage(format, data);
}
}

View File

@ -2,7 +2,9 @@
#define DIALOG_DEVICE_SCAN_H
#include "base/HGDef.h"
#include "base/HGThread.h"
#include "sane/sane_ex.h"
#include "HGSaneUI.h"
#include <QDialog>
namespace Ui {
@ -14,25 +16,34 @@ class Dialog_Device_Scan : public QDialog
Q_OBJECT
public:
explicit Dialog_Device_Scan(SANE_Handle dev, QWidget *parent = nullptr);
Dialog_Device_Scan(SANEAPI* saneApi, SANE_Handle dev,
show_scan_ui_image_callback callback, void *callbackParam, QWidget *parent = nullptr);
~Dialog_Device_Scan();
signals:
void eventFunc(HGUInt error, QString errInfo);
void newImage(void *image);
void eventFunc(QString errInfo);
void newImage(void *format, void *data);
private slots:
void on_eventFunc(HGUInt error, QString errInfo);
void on_eventFunc(QString errInfo);
void on_newImage(void *format, void *data);
void on_pushButton_Cancel_clicked();
void on_pushButton_Complete_clicked();
void on_pushButton_Continue_clicked();
private:
static void HGAPI ThreadFunc(HGThread thread, HGPointer param);
private:
Ui::Dialog_Device_Scan *ui;
SANEAPI m_saneAPI;
SANE_Handle m_saneDev;
show_scan_ui_image_callback m_callback;
void *m_callbackParam;
HGByte* m_buffer;
HGInt m_bufferSize;
volatile HGBool m_stopThread;
HGThread m_thread;
};
#endif // DIALOG_DEVICE_SCAN_H

View File

@ -8,18 +8,26 @@ Dialog_Device_Select::Dialog_Device_Select(SANEAPI* saneApi, QWidget *parent) :
{
ui->setupUi(this);
memcpy(&m_saneAPI, saneApi, sizeof(SANEAPI));
m_devHandle = nullptr;
m_devName.clear();
m_vDevName.clear();
const SANE_Device** device_list;
if (SANE_STATUS_GOOD == saneApi->sane_get_devices_api(&device_list, SANE_TRUE))
{
const SANE_Device** p;
for (p = device_list; *p != nullptr; ++p)
{
m_vDevName.push_back((*p)->name);
ui->listWidget->addItem((*p)->name);
}
}
m_devHandle = nullptr;
m_devName.clear();
if (!m_vDevName.empty())
{
ui->listWidget->setCurrentRow(0);
}
}
Dialog_Device_Select::~Dialog_Device_Select()
@ -37,7 +45,28 @@ std::string Dialog_Device_Select::GetDevName()
return m_devName;
}
void Dialog_Device_Select::on_buttonBox_accepted()
void Dialog_Device_Select::on_pushButton_OK_clicked()
{
int index = ui->listWidget->currentRow();
if (index < 0)
{
return;
}
SANE_Handle dev = nullptr;
SANE_Status ret = m_saneAPI.sane_open_api(m_vDevName[index].c_str(), &dev);
if (SANE_STATUS_GOOD != ret)
{
QMessageBox::information(this, tr("tips"), tr(m_saneAPI.sane_strstatus_api(ret)));
return;
}
m_devHandle = dev;
m_devName = m_vDevName[index];
accept();
}
void Dialog_Device_Select::on_pushButton_Cancel_clicked()
{
reject();
}

View File

@ -5,6 +5,7 @@
#include "sane/sane_ex.h"
#include <QDialog>
#include <string>
#include <vector>
namespace Ui {
class Dialog_Device_Select;
@ -22,13 +23,16 @@ public:
std::string GetDevName();
private slots:
void on_buttonBox_accepted();
void on_pushButton_OK_clicked();
void on_pushButton_Cancel_clicked();
private:
Ui::Dialog_Device_Select *ui;
SANEAPI m_saneAPI;
SANE_Handle m_devHandle;
std::string m_devName;
std::vector<std::string> m_vDevName;
};
#endif // DIALOG_DEVICE_SELECT_H

View File

@ -14,54 +14,46 @@
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_OK">
<property name="text">
<string>确定</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_Cancel">
<property name="text">
<string>取消</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog_Device_Select</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog_Device_Select</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>