Use of ResultDialog and ProcessingItem

This commit is contained in:
MSN 2013-11-26 10:44:00 +04:00
parent a4879c8f91
commit c7c9d72bd7
13 changed files with 331 additions and 91 deletions

View File

@ -16,44 +16,53 @@
#include "GlobalActionHelper.h" #include "GlobalActionHelper.h"
#include "Recognizer.h" #include "Recognizer.h"
#include "Translator.h" #include "Translator.h"
#include "ResultDialog.h"
Manager::Manager(QObject *parent) : Manager::Manager(QObject *parent) :
QObject(parent), QObject(parent),
trayIcon_ (new QSystemTrayIcon (QIcon (":/images/icon.png"), this)), trayIcon_ (new QSystemTrayIcon (QIcon (":/images/icon.png"), this)),
selection_ (new SelectionDialog), selection_ (new SelectionDialog),
resultDialog_ (new ResultDialog),
captureAction_ (NULL) captureAction_ (NULL)
{ {
GlobalActionHelper::init (); GlobalActionHelper::init ();
qRegisterMetaType<ProcessingItem>();
selection_->setWindowIcon (trayIcon_->icon ()); // Recognizer
connect (this, SIGNAL (showPixmap (QPixmap)),
selection_, SLOT (setPixmap (QPixmap)));
Recognizer* recognizer = new Recognizer; Recognizer* recognizer = new Recognizer;
connect (selection_, SIGNAL (selected (QPixmap)), connect (selection_, SIGNAL (selected (ProcessingItem)),
recognizer, SLOT (recognize (QPixmap))); recognizer, SLOT (recognize (ProcessingItem)));
connect (recognizer, SIGNAL (error (QString)), connect (recognizer, SIGNAL (error (QString)),
SLOT (showError (QString))); SLOT (showError (QString)));
connect (this, SIGNAL (settingsEdited ()),
recognizer, SLOT (applySettings ()));
QThread* recognizerThread = new QThread (this); QThread* recognizerThread = new QThread (this);
recognizer->moveToThread (recognizerThread); recognizer->moveToThread (recognizerThread);
recognizerThread->start (); recognizerThread->start ();
// Translator
Translator* translator = new Translator; Translator* translator = new Translator;
connect (recognizer, SIGNAL (recognized (QString)), connect (recognizer, SIGNAL (recognized (ProcessingItem)),
translator, SLOT (translate (QString))); translator, SLOT (translate (ProcessingItem)));
connect (translator, SIGNAL (error (QString)), connect (translator, SIGNAL (error (QString)),
SLOT (showError (QString))); SLOT (showError (QString)));
connect (this, SIGNAL (settingsEdited ()),
translator, SLOT (applySettings ()));
QThread* translatorThread = new QThread (this); QThread* translatorThread = new QThread (this);
translator->moveToThread (translatorThread); translator->moveToThread (translatorThread);
translatorThread->start (); translatorThread->start ();
connect (translator, SIGNAL (translated (QString, QString)), connect (translator, SIGNAL (translated (ProcessingItem)),
SLOT (showTranslation (QString, QString))); SLOT (showResult (ProcessingItem)));
connect (this, SIGNAL (showPixmap (QPixmap)),
selection_, SLOT (setPixmap (QPixmap)));
connect (this, SIGNAL (settingsEdited ()), this, SLOT (applySettings ())); connect (this, SIGNAL (settingsEdited ()), this, SLOT (applySettings ()));
connect (this, SIGNAL (settingsEdited ()), recognizer, SLOT (applySettings ())); selection_->setWindowIcon (trayIcon_->icon ());
connect (this, SIGNAL (settingsEdited ()), translator, SLOT (applySettings ())); resultDialog_->setWindowIcon (trayIcon_->icon ());
connect (trayIcon_, SIGNAL (activated (QSystemTrayIcon::ActivationReason)), connect (trayIcon_, SIGNAL (activated (QSystemTrayIcon::ActivationReason)),
SLOT (processTrayAction (QSystemTrayIcon::ActivationReason))); SLOT (processTrayAction (QSystemTrayIcon::ActivationReason)));
@ -151,11 +160,12 @@ void Manager::about()
message.exec (); message.exec ();
} }
void Manager::showTranslation(QString sourceText, QString translatedText) void Manager::showResult(ProcessingItem item)
{ {
lastMessage_ = sourceText + " - " + translatedText; resultDialog_->showResult (item);
qDebug () << sourceText << translatedText; // lastMessage_ = sourceText + " - " + translatedText;
trayIcon_->showMessage (tr ("Перевод"), lastMessage_, QSystemTrayIcon::Information); // qDebug () << sourceText << translatedText;
// trayIcon_->showMessage (tr ("Перевод"), lastMessage_, QSystemTrayIcon::Information);
} }
void Manager::showError(QString text) void Manager::showError(QString text)

View File

@ -4,10 +4,13 @@
#include <QPixmap> #include <QPixmap>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include "ProcessingItem.h"
class QAction; class QAction;
class QMenu; class QMenu;
class SelectionDialog; class SelectionDialog;
class ResultDialog;
class Manager : public QObject class Manager : public QObject
{ {
@ -18,7 +21,6 @@ class Manager : public QObject
signals: signals:
void showPixmap (QPixmap pixmap); void showPixmap (QPixmap pixmap);
void recognize (QPixmap pixmap);
void settingsEdited (); void settingsEdited ();
private slots: private slots:
@ -31,7 +33,7 @@ class Manager : public QObject
void processTrayAction (QSystemTrayIcon::ActivationReason reason); void processTrayAction (QSystemTrayIcon::ActivationReason reason);
void showTranslation (QString sourceText, QString translatedText); void showResult (ProcessingItem item);
void showError (QString text); void showError (QString text);
private: private:
@ -40,6 +42,7 @@ class Manager : public QObject
private: private:
QSystemTrayIcon* trayIcon_; QSystemTrayIcon* trayIcon_;
SelectionDialog* selection_; SelectionDialog* selection_;
ResultDialog* resultDialog_;
QAction* captureAction_; QAction* captureAction_;
QString lastMessage_; QString lastMessage_;
}; };

15
ProcessingItem.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef PROCESSINGITEM_H
#define PROCESSINGITEM_H
#include <QPixmap>
struct ProcessingItem
{
QPoint screenPos;
QPixmap source;
QString recognized;
QString translated;
};
Q_DECLARE_METATYPE(ProcessingItem)
#endif // PROCESSINGITEM_H

View File

@ -1,6 +1,6 @@
#include "Recognizer.h" #include "Recognizer.h"
#include <tesseract/baseapi.h> //#include <tesseract/baseapi.h>
#include <QDebug> #include <QDebug>
#include <QSettings> #include <QSettings>
@ -35,63 +35,67 @@ void Recognizer::applySettings()
bool Recognizer::initEngine() bool Recognizer::initEngine()
{ {
if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ()) // if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ())
{ // {
emit error (tr ("Неверные параметры для OCR")); // emit error (tr ("Неверные параметры для OCR"));
return false; // return false;
} // }
if (engine_ != NULL) // if (engine_ != NULL)
{ // {
delete engine_; // delete engine_;
} // }
engine_ = new tesseract::TessBaseAPI(); // engine_ = new tesseract::TessBaseAPI();
int result = engine_->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_), // int result = engine_->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_),
tesseract::OEM_DEFAULT); // tesseract::OEM_DEFAULT);
if (result != 0) // if (result != 0)
{ // {
emit error (tr ("Ошибка инициализации OCR: %1").arg (result)); // emit error (tr ("Ошибка инициализации OCR: %1").arg (result));
delete engine_; // delete engine_;
engine_ = NULL; // engine_ = NULL;
return false; // return false;
} // }
return true; // return true;
} }
void Recognizer::recognize(QPixmap pixmap) void Recognizer::recognize(ProcessingItem item)
{ {
Q_ASSERT (!pixmap.isNull ()); Q_ASSERT (!item.source.isNull ());
if (engine_ == NULL) item.recognized = "test rec";
{ emit recognized (item);
if (!initEngine ())
{
return; return;
} // if (engine_ == NULL)
} // {
// if (!initEngine ())
// {
// return;
// }
// }
QPixmap scaled = pixmap; // QPixmap scaled = pixmap;
if (imageScale_ > 0) // if (imageScale_ > 0)
{ // {
scaled = pixmap.scaledToHeight (pixmap.height () * imageScale_, // scaled = pixmap.scaledToHeight (pixmap.height () * imageScale_,
Qt::SmoothTransformation); // Qt::SmoothTransformation);
} // }
QImage image = scaled.toImage (); // QImage image = scaled.toImage ();
const int bytesPerPixel = image.depth () / 8; // const int bytesPerPixel = image.depth () / 8;
engine_->SetImage (image.bits (), image.width (), image.height (), // engine_->SetImage (image.bits (), image.width (), image.height (),
bytesPerPixel, image.bytesPerLine ()); // bytesPerPixel, image.bytesPerLine ());
char* outText = engine_->GetUTF8Text(); // char* outText = engine_->GetUTF8Text();
engine_->Clear(); // engine_->Clear();
QString result (outText); // QString result (outText);
result = result.trimmed(); // result = result.trimmed();
if (!result.isEmpty ()) // if (!result.isEmpty ())
{ // {
emit recognized (result); // item.recognized = result;
emit recognized (pixmap, result); // emit recognized (result);
} // emit recognized (pixmap, result);
else // }
{ // else
emit error (tr ("Текст не распознан.")); // {
} // emit error (tr ("Текст не распознан."));
delete [] outText; // }
// delete [] outText;
} }

View File

@ -4,6 +4,7 @@
#include <QObject> #include <QObject>
#include "QPixmap" #include "QPixmap"
#include "ProcessingItem.h"
namespace tesseract namespace tesseract
{ {
@ -17,12 +18,11 @@ class Recognizer : public QObject
explicit Recognizer(QObject *parent = 0); explicit Recognizer(QObject *parent = 0);
signals: signals:
void recognized (QString text); void recognized (ProcessingItem item);
void recognized (QPixmap pixmap, QString text);
void error (QString text); void error (QString text);
public slots: public slots:
void recognize (QPixmap pixmap); void recognize (ProcessingItem item);
void applySettings (); void applySettings ();
private: private:

62
ResultDialog.cpp Normal file
View File

@ -0,0 +1,62 @@
#include "ResultDialog.h"
#include "ui_ResultDialog.h"
#include <QDesktopWidget>
ResultDialog::ResultDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ResultDialog),
isShowAtCapturePos_ (true)
{
ui->setupUi(this);
setWindowFlags (Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
Qt::WindowStaysOnTopHint);
installEventFilter (this);
}
ResultDialog::~ResultDialog()
{
delete ui;
}
bool ResultDialog::eventFilter(QObject* object, QEvent* event)
{
Q_UNUSED (object);
if (event->type () == QEvent::MouseButtonRelease)
{
hide ();
}
return QDialog::eventFilter (object, event);
}
void ResultDialog::showResult(ProcessingItem item)
{
Q_ASSERT (!item.source.isNull ());
Q_ASSERT (!item.recognized.isEmpty ());
Q_ASSERT (!item.translated.isEmpty ());
Q_ASSERT (!item.screenPos.isNull ());
ui->sourceLabel->setPixmap (item.source);
ui->recognizeLabel->setText (item.recognized);
ui->translateLabel->setText (item.translated);
adjustSize ();
if (isShowAtCapturePos_)
{
QPoint correction = QPoint (ui->frame->lineWidth (), ui->frame->lineWidth ());
move (item.screenPos - correction);
}
else
{
QDesktopWidget* desktop = QApplication::desktop ();
Q_CHECK_PTR (desktop);
QRect screenRect = desktop->availableGeometry (this);
Q_ASSERT (screenRect.isValid ());
QPoint newPos (screenRect.width () - width (), screenRect.height () - height ());
move (newPos);
}
show ();
}

31
ResultDialog.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef RESULTDIALOG_H
#define RESULTDIALOG_H
#include <QDialog>
#include "ProcessingItem.h"
namespace Ui {
class ResultDialog;
}
class ResultDialog : public QDialog
{
Q_OBJECT
public:
explicit ResultDialog(QWidget *parent = 0);
~ResultDialog();
public:
bool eventFilter (QObject *object, QEvent *event);
public slots:
void showResult (ProcessingItem item);
private:
Ui::ResultDialog *ui;
bool isShowAtCapturePos_;
};
#endif // RESULTDIALOG_H

98
ResultDialog.ui Normal file
View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ResultDialog</class>
<widget class="QDialog" name="ResultDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>260</width>
<height>222</height>
</rect>
</property>
<property name="windowTitle">
<string>Результат</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="sourceLabel">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="recognizeLabel">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="translateLabel">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -11,9 +11,9 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ScreenTranslator TARGET = ScreenTranslator
TEMPLATE = app TEMPLATE = app
INCLUDEPATH += C:/build/include #INCLUDEPATH += C:/build/include
LIBS += -LC:/build/bin -ltesseract #LIBS += -LC:/build/bin -ltesseract
SOURCES += main.cpp\ SOURCES += main.cpp\
Manager.cpp \ Manager.cpp \
@ -21,7 +21,8 @@ SOURCES += main.cpp\
SelectionDialog.cpp \ SelectionDialog.cpp \
GlobalActionHelper.cpp \ GlobalActionHelper.cpp \
Recognizer.cpp \ Recognizer.cpp \
Translator.cpp Translator.cpp \
ResultDialog.cpp
HEADERS += \ HEADERS += \
Manager.h \ Manager.h \
@ -30,11 +31,14 @@ HEADERS += \
GlobalActionHelper.h \ GlobalActionHelper.h \
Recognizer.h \ Recognizer.h \
Translator.h \ Translator.h \
Settings.h Settings.h \
ProcessingItem.h \
ResultDialog.h
FORMS += \ FORMS += \
SettingsEditor.ui \ SettingsEditor.ui \
SelectionDialog.ui SelectionDialog.ui \
ResultDialog.ui
RESOURCES += \ RESOURCES += \
Recources.qrc Recources.qrc

View File

@ -52,7 +52,10 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
QPixmap selectedPixmap = currentPixmap_.copy (selection); QPixmap selectedPixmap = currentPixmap_.copy (selection);
if (!selectedPixmap.isNull ()) if (!selectedPixmap.isNull ())
{ {
emit selected (selectedPixmap); ProcessingItem item;
item.source = selectedPixmap;
item.screenPos = selection.topLeft ();
emit selected (item);
accept (); accept ();
} }
} }

View File

@ -4,6 +4,8 @@
#include <QDialog> #include <QDialog>
#include <QPixmap> #include <QPixmap>
#include "ProcessingItem.h"
namespace Ui { namespace Ui {
class SelectionDialog; class SelectionDialog;
} }
@ -19,7 +21,7 @@ class SelectionDialog : public QDialog
bool eventFilter (QObject *object, QEvent *event); bool eventFilter (QObject *object, QEvent *event);
signals: signals:
void selected (QPixmap pixmap); void selected (ProcessingItem pixmap);
public slots: public slots:
void setPixmap (QPixmap pixmap); void setPixmap (QPixmap pixmap);

View File

@ -35,20 +35,26 @@ void Translator::applySettings()
toString (); toString ();
} }
void Translator::translate(QString text) void Translator::translate(ProcessingItem item)
{ {
Q_ASSERT (!text.isEmpty ()); Q_ASSERT (!item.recognized.isEmpty ());
item.translated = "проверка";
emit translated (item);
return;
if (translationLanguage_.isEmpty ()) if (translationLanguage_.isEmpty ())
{ {
emit error (tr ("Неверные парметры для перевода.")); emit error (tr ("Неверные парметры для перевода."));
return; return;
} }
QUrl url (translateBaseUrl.arg (text, translationLanguage_)); QUrl url (translateBaseUrl.arg (item.recognized, translationLanguage_));
network_.get (QNetworkRequest (url)); QNetworkReply* reply = network_.get (QNetworkRequest (url));
items_.insert (reply, item);
} }
void Translator::replyFinished(QNetworkReply* reply) void Translator::replyFinished(QNetworkReply* reply)
{ {
Q_ASSERT (items_.contains (reply));
ProcessingItem item = items_.take (reply);
Q_ASSERT (reply->isFinished ()); Q_ASSERT (reply->isFinished ());
if (reply->error () != QNetworkReply::NoError) if (reply->error () != QNetworkReply::NoError)
{ {
@ -73,7 +79,6 @@ void Translator::replyFinished(QNetworkReply* reply)
} }
QJsonArray answerArray = document.array (); QJsonArray answerArray = document.array ();
QJsonArray fullTranslation = answerArray.first ().toArray (); QJsonArray fullTranslation = answerArray.first ().toArray ();
QString source = "";
QString translation = ""; QString translation = "";
foreach (QJsonValue part, fullTranslation) foreach (QJsonValue part, fullTranslation)
{ {
@ -83,7 +88,7 @@ void Translator::replyFinished(QNetworkReply* reply)
continue; continue;
} }
translation += partTranslation.at (0).toString (); translation += partTranslation.at (0).toString ();
source += partTranslation.at (1).toString ();
} }
emit translated (source, translation); item.translated = translation;
emit translated (item);
} }

View File

@ -3,6 +3,8 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include "ProcessingItem.h"
class Translator : public QObject class Translator : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -10,11 +12,11 @@ class Translator : public QObject
explicit Translator(QObject *parent = 0); explicit Translator(QObject *parent = 0);
signals: signals:
void translated (QString sourceText, QString translatedText); void translated (ProcessingItem item);
void error (QString text); void error (QString text);
public slots: public slots:
void translate (QString text); void translate (ProcessingItem item);
void applySettings (); void applySettings ();
private slots: private slots:
@ -23,6 +25,7 @@ class Translator : public QObject
private: private:
QNetworkAccessManager network_; QNetworkAccessManager network_;
QString translationLanguage_; QString translationLanguage_;
QHash<QNetworkReply*, ProcessingItem> items_;
}; };