mirror of
https://github.com/FAUSheppy/speech-server-client-qt
synced 2025-12-06 00:41:35 +01:00
Implement basic functionality
This commit is contained in:
296
mainwindow.cpp
296
mainwindow.cpp
@@ -1,72 +1,330 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "notificationwidget.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QProcess>
|
||||||
#include <QtNetwork/QNetworkAccessManager>
|
#include <QtNetwork/QNetworkAccessManager>
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
#define FILENAME_COL 0
|
||||||
QMainWindow(parent),
|
#define TRACKING_ID_COL 1
|
||||||
ui(new Ui::MainWindow)
|
#define PG_BAR_COL 2
|
||||||
{
|
#define OPEN_DIR_COL 3
|
||||||
|
#define TRANSCRIPT_STATUS_COL 4
|
||||||
|
|
||||||
|
#define STATUS_REQUEST_URL "http://localhost:5000/dumpstate"
|
||||||
|
#define SUBMIT_URL "http://localhost:5000/submit-async"
|
||||||
|
#define REQUEST_TRANSCRIPT_URL "http://localhost:5000/transcript"
|
||||||
|
#define TRANSCRIPT_TARGET_DIR "."
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent), ui(new Ui::MainWindow){
|
||||||
|
|
||||||
|
/* setup ui */
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
|
||||||
|
setAuthHeader("user", "pass");
|
||||||
|
networkManager = new QNetworkAccessManager(this);
|
||||||
|
|
||||||
|
/* setup buttons */
|
||||||
button = ui->centralWidget->findChild<QPushButton*>("pushButton");
|
button = ui->centralWidget->findChild<QPushButton*>("pushButton");
|
||||||
connect(button, SIGNAL (released()), this, SLOT (importFile()));
|
connect(button, SIGNAL (released()), this, SLOT (importFile()));
|
||||||
|
|
||||||
|
/* table ui */
|
||||||
|
tw = ui->centralWidget->findChild<QTableWidget*>("tableWidget");
|
||||||
|
//QProgressBar *pgbar = new QProgressBar();
|
||||||
|
|
||||||
|
tw->verticalHeader()->setVisible(false);
|
||||||
|
tw->horizontalHeader()->setVisible(false);
|
||||||
|
tw->setRowCount(0);
|
||||||
|
/* FILE | trackingId | STATUS | open dir | download completed? true/false | */
|
||||||
|
tw->setColumnCount(5);
|
||||||
|
tw->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
|
tw->setColumnHidden(TRANSCRIPT_STATUS_COL, true);
|
||||||
|
|
||||||
|
/* table header */
|
||||||
|
tw->insertRow(0);
|
||||||
|
tw->setItem(0, FILENAME_COL, new QTableWidgetItem("Dateiname"));
|
||||||
|
tw->setItem(0, TRACKING_ID_COL, new QTableWidgetItem("Tracking-Id"));
|
||||||
|
tw->setItem(0, PG_BAR_COL, new QTableWidgetItem("Status"));
|
||||||
|
tw->setItem(0, OPEN_DIR_COL, new QTableWidgetItem("Ordner Öffnen"));
|
||||||
|
tw->setItem(0, OPEN_DIR_COL, new QTableWidgetItem("Ordner Öffnen"));
|
||||||
|
|
||||||
|
/* create status update timer */
|
||||||
|
QTimer *timer = new QTimer(this);
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(queryStatusAll()));
|
||||||
|
timer->start(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::importFile(){
|
||||||
void MainWindow::importFile()
|
|
||||||
{
|
|
||||||
QString filename = QFileDialog::getOpenFileName(
|
QString filename = QFileDialog::getOpenFileName(
|
||||||
this,
|
this,
|
||||||
"Open Document",
|
"Open Document",
|
||||||
QDir::currentPath(),
|
QDir::currentPath(),
|
||||||
"All files (*.*) ;; Document files (*.doc *.rtf);; PNG files (*.png)");
|
"All files (*.*) ;; Document files (*.doc *.rtf);; PNG files (*.png)");
|
||||||
if( !filename.isNull() ){
|
|
||||||
|
if(filename.isNull()){
|
||||||
return;
|
return;
|
||||||
|
}else{
|
||||||
|
submitFile(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::submitFile(QString filename)
|
void MainWindow::showNotification(QString str){
|
||||||
{
|
#ifdef Q_OS_LINUX
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
auto popUp = new NotificationWidget(this);
|
||||||
|
popUp->setPopupText(str);
|
||||||
|
popUp->setGeometry(0, 0, popUp->width(), popUp->height());
|
||||||
|
popUp->show();
|
||||||
|
auto *timer = new QTimer();
|
||||||
|
connect(timer, SIGNAL(timeout()), popUp, SLOT(fadeOut()));
|
||||||
|
timer->start(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setAuthHeader(const QString username, const QString password){
|
||||||
|
|
||||||
/* prepare auth */
|
/* prepare auth */
|
||||||
QString username = "lol";
|
|
||||||
QString password = "lol";
|
|
||||||
QString concatenated = username + ":" + password;
|
QString concatenated = username + ":" + password;
|
||||||
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
QByteArray data = concatenated.toLocal8Bit().toBase64();
|
||||||
QString authHeaderData = "Basic " + data;
|
QString authHeaderStr = "Basic " + data;
|
||||||
|
authHeaderData = authHeaderStr.toLocal8Bit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::submitFile(QString filename){
|
||||||
|
|
||||||
/* prepare request */
|
/* prepare request */
|
||||||
QUrl serviceUrl = QUrl("http://localhost:5000");
|
QUrl serviceUrl = QUrl(SUBMIT_URL);
|
||||||
QNetworkRequest request(serviceUrl);
|
QNetworkRequest request(serviceUrl);
|
||||||
request.setRawHeader("Authorization", authHeaderData.toLocal8Bit());
|
request.setRawHeader("Authorization", authHeaderData);
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
|
||||||
/* read audio as base64 */
|
/* read audio as base64 */
|
||||||
QFile sourceFile(filename);
|
QFile sourceFile(filename);
|
||||||
|
sourceFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
QByteArray base64Encoded = sourceFile.readAll().toBase64();
|
QByteArray base64Encoded = sourceFile.readAll().toBase64();
|
||||||
QString dataString = QString::fromUtf8(base64Encoded);
|
QString dataString = QString::fromUtf8(base64Encoded);
|
||||||
|
sourceFile.close();
|
||||||
|
|
||||||
/* prepare json */
|
/* prepare json */
|
||||||
QJsonObject json = QJsonObject();
|
QJsonObject json = QJsonObject();
|
||||||
QJsonValue dataFieldContent = QJsonValue(dataString);
|
QJsonValue dataFieldContent = QJsonValue(dataString);
|
||||||
|
|
||||||
QFileInfo info(filename);
|
QFileInfo info(filename);
|
||||||
QString basename(info.fileName());
|
QString basename(info.fileName());
|
||||||
json["filename"] = filename;
|
json["filename"] = filename;
|
||||||
json["data"] = dataFieldContent;
|
json["data"] = dataFieldContent;
|
||||||
|
|
||||||
/* make request */
|
/* make request */
|
||||||
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
|
|
||||||
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this,
|
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this,
|
||||||
SLOT(fileSubmissionFinished(QNetworkReply*)));
|
SLOT(requestFinished(QNetworkReply*)), Qt::UniqueConnection);
|
||||||
networkManager->post(request, QJsonDocument(json).toJson());
|
networkManager->post(request, QJsonDocument(json).toJson());
|
||||||
|
|
||||||
|
qDebug("Request submitted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::queryTransscript(QString trackingId){
|
||||||
|
QString url = QString("%1?id=%2").arg(REQUEST_TRANSCRIPT_URL, trackingId);
|
||||||
|
QUrl transcriptUrl = QUrl(url);
|
||||||
|
QNetworkRequest request(transcriptUrl);
|
||||||
|
request.setRawHeader("Authorization", authHeaderData);
|
||||||
|
networkManager->get(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::openContainingDir(){
|
||||||
|
qDebug("Called");
|
||||||
|
auto filePath = TRANSCRIPT_TARGET_DIR;
|
||||||
|
QStringList args;
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
args << QDir::toNativeSeparators(filePath);
|
||||||
|
QProcess::startDetached("/usr/bin/thunar", args);
|
||||||
|
#endif
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QStringList args;
|
||||||
|
args << "/select," << QDir::toNativeSeparators(filePath);
|
||||||
|
QProcess::startDetached("explorer", args);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateList(QNetworkReply* reply){
|
||||||
|
if(reply->error() != QNetworkReply::NoError){
|
||||||
|
showNotification("HTTP Error on status Request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get filename and tracking id from replay */
|
||||||
|
QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
|
||||||
|
for(int i = 0; i<tw->rowCount(); i++){
|
||||||
|
auto trackingId = tw->model()->data(tw->model()->index(i, TRACKING_ID_COL)).toString();
|
||||||
|
|
||||||
|
if(json.contains(trackingId)){
|
||||||
|
QJsonArray statusArray = json.value(trackingId).toArray();
|
||||||
|
if(statusArray.size() == 0){
|
||||||
|
qDebug("Status array empty wtf?");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto currentStatus = statusArray[statusArray.size()-1].toObject();
|
||||||
|
auto status = currentStatus["status"].toString();
|
||||||
|
auto percentage = currentStatus["percent"].toInt();
|
||||||
|
auto statusMsg = currentStatus["message"].toString();
|
||||||
|
|
||||||
|
auto pg = tw->cellWidget(i, PG_BAR_COL)->findChild<QProgressBar*>();
|
||||||
|
pg->setFormat(statusMsg);
|
||||||
|
pg->setValue(100);
|
||||||
|
|
||||||
|
if(percentage == -1){
|
||||||
|
pg->setValue(100);
|
||||||
|
pg->setStyleSheet("QProgressBar::chunk { background-color: red; }");
|
||||||
|
}else if(percentage == 100){
|
||||||
|
pg->setValue(percentage);
|
||||||
|
pg->setStyleSheet("QProgressBar::chunk { background-color: green; }");
|
||||||
|
auto status = tw->model()->data(tw->model()->index(i, TRANSCRIPT_STATUS_COL));
|
||||||
|
auto tStatus = status.toString().toInt();
|
||||||
|
if(tStatus == 0){
|
||||||
|
queryTransscript(trackingId);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pg->setValue(percentage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::saveTranscript(QNetworkReply* reply){
|
||||||
|
|
||||||
|
/* get return data */
|
||||||
|
QJsonDocument json = QJsonDocument::fromJson(reply->readAll());
|
||||||
|
auto transcript = json["transcript"].toString();
|
||||||
|
auto trackingId = json["id"].toString();
|
||||||
|
auto targetName = json["true-name"].toString();
|
||||||
|
if(QString::compare(trackingId, "") == 0){
|
||||||
|
qFatal("Empty TrackingId, file might have been request by it's name.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get filename for id */
|
||||||
|
QString filename;
|
||||||
|
int rowId = -1;
|
||||||
|
for(int i = 0; i<tw->rowCount(); i++){
|
||||||
|
auto curId = tw->model()->data(tw->model()->index(i, TRACKING_ID_COL)).toString();
|
||||||
|
auto curName = tw->model()->data(tw->model()->index(i, FILENAME_COL)).toString();
|
||||||
|
if(QString::compare(trackingId, curId) == 0){
|
||||||
|
filename = curName;
|
||||||
|
rowId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save return data */
|
||||||
|
QString fullpath = QDir(TRANSCRIPT_TARGET_DIR).filePath(targetName);
|
||||||
|
qDebug(qPrintable(fullpath));
|
||||||
|
QFile file(fullpath);
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
QMessageBox::information(this, tr("Unable to open file"), file.errorString());
|
||||||
|
qWarning("Error opening File");
|
||||||
|
}
|
||||||
|
QDataStream out(&file);
|
||||||
|
out.setVersion(QDataStream::Qt_4_5);
|
||||||
|
out << transcript;
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
/* mark as downloaded */
|
||||||
|
auto ts = new QTableWidgetItem();
|
||||||
|
ts->setData(Qt::DisplayRole, 1);
|
||||||
|
tw->setItem(rowId, TRANSCRIPT_STATUS_COL, ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::addTrackingToList(QNetworkReply* reply){
|
||||||
|
if(reply->error() != QNetworkReply::NoError){
|
||||||
|
showNotification("Fehler bei Dateiübertragung, keine Tracking-ID zugewiesen!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add new row */
|
||||||
|
tw->insertRow(tw->rowCount());
|
||||||
|
auto row = tw->rowCount() - 1;
|
||||||
|
|
||||||
|
/* get filename and tracking id from replay */
|
||||||
|
QJsonDocument json = QJsonDocument::fromJson(reply->readAll());
|
||||||
|
auto filename = json["filename"].toString();
|
||||||
|
auto trackingId = json["trackingId"].toString();
|
||||||
|
|
||||||
|
/* create cusomt widget for pg bar */
|
||||||
|
auto *pgBarLayout = new QGridLayout();
|
||||||
|
auto *pg = new QProgressBar();
|
||||||
|
auto *pgBarCellContent = new QWidget();
|
||||||
|
pg->setRange(0,100);
|
||||||
|
pg->setValue(0);
|
||||||
|
pg->setTextVisible(true);
|
||||||
|
pg->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
const QFont *font = new QFont("Times", 12, QFont::Weight::Bold, false);
|
||||||
|
pg->setFont(*font);
|
||||||
|
pg->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
pgBarLayout->addWidget(pg);
|
||||||
|
pgBarLayout->setContentsMargins(0,0,0,0);
|
||||||
|
pgBarCellContent->setLayout(pgBarLayout);
|
||||||
|
|
||||||
|
/* create cusomt widget for open-dir button */
|
||||||
|
auto *openDirLayout = new QGridLayout();
|
||||||
|
auto dirButton = new QPushButton("Ordner");
|
||||||
|
connect(dirButton, SIGNAL (released()), this, SLOT (openContainingDir()));
|
||||||
|
|
||||||
|
auto *openDirCellContent = new QWidget();
|
||||||
|
openDirLayout->addWidget(dirButton);
|
||||||
|
dirButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
openDirLayout->setContentsMargins(0,0,0,0);
|
||||||
|
openDirCellContent->setLayout(openDirLayout);
|
||||||
|
|
||||||
|
/* set values */
|
||||||
|
tw->setItem(row, FILENAME_COL, new QTableWidgetItem(filename));
|
||||||
|
tw->setItem(row, TRACKING_ID_COL, new QTableWidgetItem(trackingId));
|
||||||
|
tw->setCellWidget(row, PG_BAR_COL, pgBarCellContent);
|
||||||
|
tw->setCellWidget(row, OPEN_DIR_COL, openDirCellContent);
|
||||||
|
|
||||||
|
|
||||||
|
/* set transcript status */
|
||||||
|
auto ts = new QTableWidgetItem();
|
||||||
|
ts->setData(Qt::DisplayRole, 0);
|
||||||
|
tw->setItem(row, TRANSCRIPT_STATUS_COL, ts);
|
||||||
|
tw->setColumnHidden(TRACKING_ID_COL, true);
|
||||||
|
|
||||||
|
qDebug("Reply added to be tracked by list");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::requestFinished(QNetworkReply *reply){
|
||||||
|
qDebug(qPrintable(reply->url().toString()));
|
||||||
|
if(QString::compare(reply->url().toString(), SUBMIT_URL) == 0){
|
||||||
|
addTrackingToList(reply);
|
||||||
|
}else if (QString::compare(reply->url().toString(), STATUS_REQUEST_URL) == 0) {
|
||||||
|
updateList(reply);
|
||||||
|
}else if (reply->url().toString().startsWith(REQUEST_TRANSCRIPT_URL)) {
|
||||||
|
qDebug("Saving transcript");
|
||||||
|
saveTranscript(reply);
|
||||||
|
}else{
|
||||||
|
qDebug("URL-Response: %s", qUtf8Printable(reply->url().toString()));
|
||||||
|
qFatal("Unexpected responding URL");
|
||||||
|
}
|
||||||
|
//qDebug("Reply handling finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::queryStatusAll(){
|
||||||
|
QUrl trackingUrl = QUrl(STATUS_REQUEST_URL);
|
||||||
|
QNetworkRequest request(trackingUrl);
|
||||||
|
request.setRawHeader("Authorization", authHeaderData);
|
||||||
|
networkManager->get(request);
|
||||||
|
//qDebug("Status query sent");
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
|
|||||||
15
mainwindow.h
15
mainwindow.h
@@ -4,6 +4,7 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QTableWidget>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@@ -19,12 +20,22 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void importFile();
|
void importFile();
|
||||||
void fileSubmissionFinished(QNetworkReply*);
|
void requestFinished(QNetworkReply*);
|
||||||
|
void queryStatusAll();
|
||||||
|
void openContainingDir();
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
QTableWidget *tw;
|
||||||
QPushButton *button;
|
QPushButton *button;
|
||||||
|
QByteArray authHeaderData;
|
||||||
|
QNetworkAccessManager *networkManager;
|
||||||
void submitFile(QString filename);
|
void submitFile(QString filename);
|
||||||
|
void setAuthHeader(const QString username, const QString password);
|
||||||
|
void updateList(QNetworkReply *reply);
|
||||||
|
void addTrackingToList(QNetworkReply *reply);
|
||||||
|
void showNotification(QString str);
|
||||||
|
void queryTransscript(QString trackingId);
|
||||||
|
void saveTranscript(QNetworkReply *reply);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@@ -22,15 +22,8 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QProgressBar" name="progressBar">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QTableView" name="tableView"/>
|
<widget class="QTableWidget" name="tableWidget"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -43,15 +36,33 @@
|
|||||||
<height>20</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menuKonfiguration">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Konfiguration</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionServer"/>
|
||||||
|
<addaction name="actionStandards"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuKonfiguration"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QToolBar" name="mainToolBar">
|
<widget class="QToolBar" name="mainToolBar">
|
||||||
<attribute name="toolBarArea">
|
<attribute name="toolBarArea">
|
||||||
<enum>TopToolBarArea</enum>
|
<enum>TopToolBarArea</enum>
|
||||||
</attribute>
|
</attribute>
|
||||||
<attribute name="toolBarBreak">
|
<attribute name="toolBarBreak">
|
||||||
<bool>true</bool>
|
<bool>false</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
|
<action name="actionServer">
|
||||||
|
<property name="text">
|
||||||
|
<string>Server</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionStandards">
|
||||||
|
<property name="text">
|
||||||
|
<string>Standards</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|||||||
97
notificationwidget.cpp
Normal file
97
notificationwidget.cpp
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#include <QGraphicsOpacityEffect>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "notificationwidget.h"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
NotificationWidget::NotificationWidget(QWidget *parent) :
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
resize(200, 50);
|
||||||
|
|
||||||
|
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
|
||||||
|
setAttribute(Qt::WA_TranslucentBackground);
|
||||||
|
setAttribute(Qt::WA_ShowWithoutActivating);
|
||||||
|
|
||||||
|
animation.setTargetObject(this);
|
||||||
|
animation.setPropertyName("popupOpacity");
|
||||||
|
animation.setDuration(150);
|
||||||
|
|
||||||
|
label.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||||
|
|
||||||
|
layout.addWidget(&label, 0, 0);
|
||||||
|
setLayout(&layout);
|
||||||
|
setAttribute(Qt::WA_X11NetWmWindowTypeSplash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationWidget::paintEvent(QPaintEvent *e)
|
||||||
|
{
|
||||||
|
Q_UNUSED(e)
|
||||||
|
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
// Prepare the popup dimensions
|
||||||
|
QRect roundedRectDimensions;
|
||||||
|
roundedRectDimensions.setX(rect().x() + 5);
|
||||||
|
roundedRectDimensions.setY(rect().y() + 5);
|
||||||
|
roundedRectDimensions.setWidth(rect().width() - 10);
|
||||||
|
roundedRectDimensions.setHeight(rect().height() - 10);
|
||||||
|
|
||||||
|
painter.setBrush(QBrush(Qt::lightGray));
|
||||||
|
|
||||||
|
QPen pen;
|
||||||
|
pen.setColor(Qt::gray);
|
||||||
|
pen.setWidth(3);
|
||||||
|
painter.setPen(pen);
|
||||||
|
|
||||||
|
// Draw the popup body
|
||||||
|
painter.drawRoundedRect(roundedRectDimensions, 15, 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationWidget::setPopupText(const QString &text)
|
||||||
|
{
|
||||||
|
label.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationWidget::show()
|
||||||
|
{
|
||||||
|
setWindowOpacity(0.0);
|
||||||
|
|
||||||
|
animation.setStartValue(0.0);
|
||||||
|
animation.setEndValue(1.0);
|
||||||
|
|
||||||
|
QWidget::show();
|
||||||
|
|
||||||
|
animation.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationWidget::setPopupOpacity(float opacity)
|
||||||
|
{
|
||||||
|
popupOpacity = opacity;
|
||||||
|
setWindowOpacity(static_cast<double>(opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
float NotificationWidget::getPopupOpacity() const
|
||||||
|
{
|
||||||
|
return popupOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationWidget::fadeOut(){
|
||||||
|
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect();
|
||||||
|
setGraphicsEffect(effect);
|
||||||
|
QPropertyAnimation *a = new QPropertyAnimation(effect,"opacity");
|
||||||
|
a->setDuration(1000); // it will took 1000ms to face out
|
||||||
|
a->setStartValue(1);
|
||||||
|
a->setEndValue(0);
|
||||||
|
a->setEasingCurve(QEasingCurve::OutBack);
|
||||||
|
a->start(QPropertyAnimation::DeleteWhenStopped);
|
||||||
|
connect(a, SIGNAL(finished()), this, SLOT(hideAndDestroy()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationWidget::hideAndDestroy(){
|
||||||
|
this->hide();
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
38
notificationwidget.h
Normal file
38
notificationwidget.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#ifndef NOTIFICATIONWIDGET_H
|
||||||
|
#define NOTIFICATIONWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
class NotificationWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(float popupOpacity READ getPopupOpacity WRITE setPopupOpacity)
|
||||||
|
|
||||||
|
void setPopupOpacity(float opacity);
|
||||||
|
float getPopupOpacity() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit NotificationWidget(QWidget *parent = nullptr);
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setPopupText(const QString& text);
|
||||||
|
void show();
|
||||||
|
void fadeOut();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void hideAndDestroy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel label;
|
||||||
|
QGridLayout layout;
|
||||||
|
QPropertyAnimation animation;
|
||||||
|
float popupOpacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NOTIFICATIONWIDGET_H
|
||||||
@@ -26,10 +26,12 @@ CONFIG += c++11
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp
|
mainwindow.cpp \
|
||||||
|
notificationwidget.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
mainwindow.h
|
mainwindow.h \
|
||||||
|
notificationwidget.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
|
|||||||
Reference in New Issue
Block a user