From 415dcb4e2348edf996ed7b25d92b3b37f38b0adf Mon Sep 17 00:00:00 2001 From: Vladislav Budin Date: Mon, 22 May 2023 18:42:01 +0300 Subject: [PATCH] widgets added --- .gitignore | 1 + qt/AudioPlayer.cpp | 138 +++++++++++++++++++++++++++++++++++++ qt/AudioPlayer.hpp | 55 +++++++++++++++ qt/AudioPlayer.ui | 21 ++++++ qt/AudioWidget.cpp | 114 ++++++++++++++++++++++++++++++ qt/AudioWidget.hpp | 45 ++++++++++++ qt/AudioWidget.ui | 46 +++++++++++++ qt/CMakeLists.txt | 52 ++++++++++++++ qt/Deck.cpp | 49 +++++++++++++ qt/Deck.hpp | 30 ++++++++ qt/ExamplesWidget.cpp | 157 ++++++++++++++++++++++++++++++++++++++++++ qt/ExamplesWidget.hpp | 42 +++++++++++ qt/ExamplesWidget.ui | 89 ++++++++++++++++++++++++ qt/ImagesWidget.cpp | 119 ++++++++++++++++++++++++++++++++ qt/ImagesWidget.hpp | 43 ++++++++++++ qt/ImagesWidget.ui | 46 +++++++++++++ 16 files changed, 1047 insertions(+) create mode 100644 qt/AudioPlayer.cpp create mode 100644 qt/AudioPlayer.hpp create mode 100644 qt/AudioPlayer.ui create mode 100644 qt/AudioWidget.cpp create mode 100644 qt/AudioWidget.hpp create mode 100644 qt/AudioWidget.ui create mode 100644 qt/CMakeLists.txt create mode 100644 qt/Deck.cpp create mode 100644 qt/Deck.hpp create mode 100644 qt/ExamplesWidget.cpp create mode 100644 qt/ExamplesWidget.hpp create mode 100644 qt/ExamplesWidget.ui create mode 100644 qt/ImagesWidget.cpp create mode 100644 qt/ImagesWidget.hpp create mode 100644 qt/ImagesWidget.ui diff --git a/.gitignore b/.gitignore index 366ecf8..be5f7a6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,6 @@ build/ !./README.md !/img/** !/server/** +!/qt/** !/test_client/** !/plugins/**/*.py \ No newline at end of file diff --git a/qt/AudioPlayer.cpp b/qt/AudioPlayer.cpp new file mode 100644 index 0000000..9f0e7db --- /dev/null +++ b/qt/AudioPlayer.cpp @@ -0,0 +1,138 @@ +#include "AudioPlayer.hpp" +#include "ui_AudioPlayer.h" +#include +#include +#include +#include +#include +#include + +AudioPlayer::AudioPlayer(QWidget *parent): + QWidget(parent), + ui(new Ui::AudioPlayer) +{ + m_infoEdit = new QTextEdit; + m_infoEdit->setPlaceholderText("Audio additional info"); + m_infoEdit->setEnabled(false); + + m_pcmdPlay = new QPushButton; + m_pcmdStop = new QPushButton; + m_psldPosition = new QSlider; + m_plblCurrent = new QLabel(msecsToString(0)); + m_plblRemain = new QLabel(msecsToString(0)); + m_pmp = new QMediaPlayer; + + m_pcmdPlay->setEnabled(false); + m_pcmdPlay->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + + m_pcmdStop->setEnabled(false); + m_pcmdStop->setIcon(style()->standardIcon(QStyle::SP_MediaStop)); + + m_psldPosition->setRange(0, 0); + m_psldPosition->setOrientation(Qt::Horizontal); + + connect(m_pcmdPlay, SIGNAL(clicked()), SLOT(slotPlay())); + connect(m_pcmdStop, SIGNAL(clicked()), m_pmp, SLOT(stop())); + connect(m_pmp, SIGNAL(positionChanged(qint64)), SLOT(slotSetSliderPosition(qint64))); + connect(m_pmp, SIGNAL(durationChanged(qint64)), SLOT(slotSetDuration(qint64))); + connect(m_pmp, SIGNAL(stateChanged(QMediaPlayer::State)), + SLOT(slotStatusChanged(QMediaPlayer::State))); + + QHBoxLayout* phbxPlayControls = new QHBoxLayout; + phbxPlayControls->addWidget(m_pcmdPlay); + phbxPlayControls->addWidget(m_infoEdit); + + QHBoxLayout* phbxTimeControls = new QHBoxLayout; + phbxTimeControls->addWidget(m_plblCurrent); + phbxTimeControls->addWidget(m_psldPosition); + phbxTimeControls->addWidget(m_plblRemain); + + m_pvbxMainLayout = new QVBoxLayout; + m_pvbxMainLayout->addLayout(phbxPlayControls); + m_pvbxMainLayout->addLayout(phbxTimeControls); + + setLayout(m_pvbxMainLayout); +} + +AudioPlayer::~AudioPlayer() +{ + delete ui; +} + +void AudioPlayer::set(SourceWithAdditionalInfo audio, bool isLocal) +{ + m_audio = audio; + m_isLocal = isLocal; + m_infoEdit->setText(QString::fromStdString(audio.info)); + slotOpen(); +} + +void AudioPlayer::slotOpen() +{ + QUrl url; + if (m_isLocal) { + url = QUrl::fromLocalFile(QString::fromStdString(m_audio.src)); + } + else { + url = QUrl(QString::fromStdString(m_audio.src)); + } + if (url.isValid()) { + m_pmp->setMedia(url); + m_pcmdPlay->setEnabled(true); + m_pcmdStop->setEnabled(true); + } +} + +void AudioPlayer::slotPlay() +{ + switch (m_pmp->state()) { + case QMediaPlayer::PlayingState: + m_pmp->pause(); + break; + default: + m_pmp->play(); + break; + } +} + +void AudioPlayer::slotStatusChanged(QMediaPlayer::State state) +{ + switch (state) { + case QMediaPlayer::PlayingState: + m_pcmdPlay->setIcon(style()->standardIcon(QStyle::SP_MediaPause)); + break; + default: + m_pcmdPlay->setIcon(style()->standardIcon(QStyle::SP_MediaPlay)); + break; + } +} + +void AudioPlayer::slotSetMediaPosition(int n) +{ + m_pmp->setPosition(n); +} + +QString AudioPlayer::msecsToString(qint64 n) +{ + int nHours = (n / (60 * 60 * 1000)); + int nMinutes = ((n % (60 * 60 * 1000)) / (60 * 1000)); + int nSeconds = ((n % (60 * 1000)) / 1000); + + return QTime(nHours, nMinutes, nSeconds).toString("hh:mm::ss"); +} + +void AudioPlayer::slotSetDuration(qint64 n) +{ + m_psldPosition->setRange(0, n); + m_plblCurrent->setText(msecsToString(0)); + m_plblRemain->setText(msecsToString(n)); +} + +void AudioPlayer::slotSetSliderPosition(qint64 n) +{ + m_psldPosition->setValue(n); + + m_plblCurrent->setText(msecsToString(n)); + int nDuration = m_psldPosition->maximum(); + m_plblRemain->setText(msecsToString(nDuration - n)); +} diff --git a/qt/AudioPlayer.hpp b/qt/AudioPlayer.hpp new file mode 100644 index 0000000..02202fd --- /dev/null +++ b/qt/AudioPlayer.hpp @@ -0,0 +1,55 @@ +#ifndef AUDIOPLAYER_HPP +#define AUDIOPLAYER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Media.hpp" + +namespace Ui { +class AudioPlayer; +} + +class AudioPlayer : public QWidget +{ + Q_OBJECT + +public: + explicit AudioPlayer(QWidget *parent = nullptr); + ~AudioPlayer(); + +public slots: + void set(SourceWithAdditionalInfo audio, bool isLocal); + +private: + Ui::AudioPlayer *ui; + SourceWithAdditionalInfo m_audio; + bool m_isLocal; + QPushButton* m_pcmdPlay; + QPushButton* m_pcmdStop; + QSlider* m_psldPosition; + QLabel* m_plblCurrent; + QLabel* m_plblRemain; + QTextEdit* m_infoEdit; + + QString msecsToString(qint64 n); + +protected: + QMediaPlayer* m_pmp; + QVBoxLayout* m_pvbxMainLayout; + +private slots: + void slotOpen(); + void slotPlay(); + void slotSetSliderPosition(qint64); + void slotSetMediaPosition(int); + void slotSetDuration(qint64); + void slotStatusChanged(QMediaPlayer::State); +}; + +#endif // AUDIOPLAYER_HPP diff --git a/qt/AudioPlayer.ui b/qt/AudioPlayer.ui new file mode 100644 index 0000000..11e4ef3 --- /dev/null +++ b/qt/AudioPlayer.ui @@ -0,0 +1,21 @@ + + + + + AudioPlayer + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + diff --git a/qt/AudioWidget.cpp b/qt/AudioWidget.cpp new file mode 100644 index 0000000..167bd7e --- /dev/null +++ b/qt/AudioWidget.cpp @@ -0,0 +1,114 @@ +#include "AudioWidget.hpp" +#include "ui_AudioWidget.h" +#include +#include +#include "AudioPlayer.hpp" + +AudioWidget::AudioWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::AudioWidget), + pageNumber(0) +{ + ui->setupUi(this); + formLayout = new QFormLayout; + for (size_t i = 0; i < audioInPage; ++i) { + QPushButton* button = new QPushButton; + button->setStyleSheet("background-color: white"); + button->setCheckable(true); + button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + connect(button, &QPushButton::clicked, [=](bool toggled) { + updateChosen(i, toggled, button); + }); + AudioPlayer* audioPlayer = new AudioPlayer; + formLayout->addRow(button, audioPlayer); + } + ui->groupBox->setLayout(formLayout); +} + +AudioWidget::~AudioWidget() +{ + delete ui; +} + +void AudioWidget::setButtonEnabled(QPushButton* button, bool enabled) { + if (enabled) { + button->setEnabled(true); + button->setChecked(false); + button->setStyleSheet("background-color: white"); + } + else { + button->setStyleSheet("background-color: gray"); + button->setChecked(false); + button->setEnabled(false); + } +} +void AudioWidget::setButtonChosen(QPushButton* button) { + button->setStyleSheet("background-color: green"); +} + +void AudioWidget::set(Media audio) +{ + m_audio = audio; + clear(); + chosen.resize(m_audio.web.size()); + std::fill(chosen.begin(), chosen.end(), false); + for (size_t i = 0; i < audioInPage; ++i) { + QLayoutItem* button_item = formLayout->itemAt(i, QFormLayout::LabelRole); + QPushButton* button = qobject_cast(button_item->widget()); + QLayoutItem* player_item = formLayout->itemAt(i, QFormLayout::FieldRole); + AudioPlayer* player = qobject_cast(player_item->widget()); + if (i >= audio.web.size()) { + return; + } + else { + setButtonEnabled(button, true); + player->set(audio.web.at(i), false); + } + } +} + +void AudioWidget::next() +{ + +} + +void AudioWidget::prev() +{ + +} + +Media AudioWidget::extract() +{ + Media media; + for (size_t i = 0; i < chosen.size(); ++i) { + if (chosen[i]) { + media.web.push_back(m_audio.web.at(i)); + } + } + return media; +} + +void AudioWidget::updateChosen(size_t index, bool choice, QPushButton *button) +{ + if (chosen.size() <= index) { + return; + } + chosen.at(index) = choice; + if (choice) { + setButtonChosen(button); + } + else { + setButtonEnabled(button, true); + } + qDebug() << extract().web.size(); +} + +void AudioWidget::clear() { + for (size_t i = 0; i < audioInPage; ++i) { + QLayoutItem* button_item = formLayout->itemAt(i, QFormLayout::LabelRole); + QPushButton* button = qobject_cast(button_item->widget()); + setButtonEnabled(button, false); + // QLayoutItem* player_item = formLayout->itemAt(i, QFormLayout::FieldRole); + // AudioPlayer* player = qobject_cast(player_item->widget()); + } +} \ No newline at end of file diff --git a/qt/AudioWidget.hpp b/qt/AudioWidget.hpp new file mode 100644 index 0000000..eeb0e0a --- /dev/null +++ b/qt/AudioWidget.hpp @@ -0,0 +1,45 @@ +#ifndef AUDIOWIDGET_HPP +#define AUDIOWIDGET_HPP + +#include +#include +#include +#include +#include +#include "Media.hpp" +// #include "DefinitionsProviderWrapper.h" + +namespace Ui { +class AudioWidget; +} + +class AudioWidget : public QWidget +{ + Q_OBJECT + +public: + explicit AudioWidget(QWidget *parent = nullptr); + ~AudioWidget(); + +public slots: + void set(Media audio); + void next(); + void prev(); + Media extract(); + +private slots: + void clear(); + void setButtonEnabled(QPushButton* button, bool enabled); + void setButtonChosen(QPushButton* button); + void updateChosen(size_t index, bool choice, QPushButton* button); + +private: + Ui::AudioWidget *ui; + Media m_audio; + std::vector chosen; + QFormLayout* formLayout; + const size_t audioInPage = 3; + size_t pageNumber; +}; + +#endif // AUDIOWIDGET_HPP diff --git a/qt/AudioWidget.ui b/qt/AudioWidget.ui new file mode 100644 index 0000000..99a31df --- /dev/null +++ b/qt/AudioWidget.ui @@ -0,0 +1,46 @@ + + + AudioWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + + + + + + + + + < + + + + + + + > + + + + + + + + + + diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt new file mode 100644 index 0000000..3485640 --- /dev/null +++ b/qt/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.5) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +# set(CMAKE_AUTOMOC_MOC_OPTIONS "moc=/usr/lib/x86_64-linux-gnu/qt5/bin") + +find_package(QT NAMES Qt5 COMPONENTS Widgets REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) +# find_package(Qt5Network REQUIRED) +find_package(Qt5Multimedia REQUIRED) +FIND_PACKAGE( Qt5MultimediaWidgets REQUIRED ) + +SET(QT_USE_QTMULTIMEDIA TRUE) +SET(QT_USE_QTMULTIMEDIAWIDGETS TRUE) + +add_executable(qt +main.cpp +AudioPlayer.cpp +AudioWidget.cpp +deck_model.cpp +ExamplesWidget.cpp +ImagesWidget.cpp +mainwindow.cpp +word_cards.cpp +main.cpp +AudioPlayer.ui +AudioWidget.ui +ExamplesWidget.ui +ImagesWidget.ui +mainwindow.ui +Deck.cpp +) +target_include_directories(qt PUBLIC ./) + +target_link_libraries(qt +Qt${QT_VERSION_MAJOR}::Widgets +Qt5::Multimedia +Qt5::Network +media +connection +definitions_provider_wrapper +definitions_provider_interface +format_processor_plugin_wrapper +card +word_plugin_wrapper +) + +QT5_USE_MODULES (qt Multimedia MultimediaWidgets) \ No newline at end of file diff --git a/qt/Deck.cpp b/qt/Deck.cpp new file mode 100644 index 0000000..65321b9 --- /dev/null +++ b/qt/Deck.cpp @@ -0,0 +1,49 @@ +#include "Deck.hpp" +#include "word_cards.h" +#include + +Deck::Deck(std::unique_ptr wordPlugin) { + wordPlugin_ = std::move(wordPlugin); +} + +size_t Deck::size() const { + return cards_.size(); +} +std::string Deck::getWord(size_t index) const { + return cards_.at(index).get_word(); +} +const Card* Deck::getCard(size_t index) const { + return cards_.at(index).get_card(); +} + +void Deck::next(size_t index) { + cards_.at(index).next(); +} + +void Deck::prev(size_t index) { + cards_.at(index).prev(); +} + +void Deck::load(std::string word, std::string query) { + std::cout << "in deck load" << std::endl; + std::vector wordCards; + std::string error; + tie(wordCards, error) = wordPlugin_->get(word, query, batch_size, false); + std::cout << "got: " << wordCards.size() << " cards" << std::endl; + int i = indexOfWord(word); + if (i == -1) { + cards_.push_back(WordCards(word, wordCards)); + } + else { + cards_.at(i).addCards(wordCards); + } +} + +int Deck::indexOfWord(const std::string &word) const { + for (int i = 0; i < cards_.size(); ++i) { + if (cards_.at(i).get_word() == word) { + return i; + } + } + return -1; +} diff --git a/qt/Deck.hpp b/qt/Deck.hpp new file mode 100644 index 0000000..e924a00 --- /dev/null +++ b/qt/Deck.hpp @@ -0,0 +1,30 @@ +#ifndef DECK_H +#define DECK_H + +#include "word_cards.h" +#include "IDeck.h" +#include "IWordPluginWrapper.h" +#include +#include +#include + +class Deck: public IDeck { +public: + Deck(std::unique_ptr wordPlugin); + ~Deck() {std::cout << "Destructor of deck" << std::endl;} + size_t size() const; + std::string getWord(size_t index) const; + const Card* getCard(size_t index) const; + void next(size_t index); + void prev(size_t index); + void load(std::string word, std::string query); + + virtual int indexOfWord(const std::string &word) const; + +private: + const size_t batch_size = 10; + std::vector cards_; + std::unique_ptr wordPlugin_; +}; + +#endif // DECK_H \ No newline at end of file diff --git a/qt/ExamplesWidget.cpp b/qt/ExamplesWidget.cpp new file mode 100644 index 0000000..2d2dad8 --- /dev/null +++ b/qt/ExamplesWidget.cpp @@ -0,0 +1,157 @@ +#include "ExamplesWidget.hpp" +#include "ui_ExamplesWidget.h" +#include +#include +#include +#include +#include +#include +#include + +ExamplesWidget::ExamplesWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::ExamplesWidget), + examples(nullptr), + page_number(0) +{ + ui->setupUi(this); + form_layout = new QFormLayout; + for (size_t i = 0; i < edits_in_page; ++i) { + QTextEdit* edit = new QTextEdit; + edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + QPushButton* button = new QPushButton; + button->setStyleSheet("background-color: white"); + button->setCheckable(true); + button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + connect(button, &QPushButton::toggled, [=](bool toggled) { + updateChosen(i, toggled, button); + }); + form_layout->addRow(edit, button); + } + ui->groupBox->setLayout(form_layout); +} + +ExamplesWidget::~ExamplesWidget() +{ + delete ui; +} + +void ExamplesWidget::setButtonEnabled(QPushButton* button, bool enabled) { + if (enabled) { + button->setEnabled(true); + button->setChecked(false); + button->setStyleSheet("background-color: white"); + } + else { + button->setStyleSheet("background-color: gray"); + button->setChecked(false); + button->setEnabled(false); + } +} + +void ExamplesWidget::setButtonChosen(QPushButton* button) { + button->setStyleSheet("background-color: green"); +} + +void ExamplesWidget::set(const std::vector *new_examples) +{ + examples = new_examples; + if (!examples) { + return; + } + clear(); + chosen.resize(examples->size()); + for (size_t i = 0; i < edits_in_page; ++i) { + QLayoutItem* edit_item = form_layout->itemAt(i, QFormLayout::LabelRole); + QTextEdit* edit = qobject_cast(edit_item->widget()); + QLayoutItem* button_item = form_layout->itemAt(i, QFormLayout::FieldRole); + QPushButton* button = qobject_cast(button_item->widget()); + if (i < examples->size()) { + edit->setText(QString::fromStdString(examples->at(i))); + edit->setEnabled(true); + setButtonEnabled(button, true); + } + else { + } + } +} + +void ExamplesWidget::next() +{ + size_t start_index = (page_number + 1) * edits_in_page; + if (start_index >= examples->size()) { + return; + } + clear(); + for (size_t i = 0; i < edits_in_page; ++i) { + QLayoutItem* edit_item = form_layout->itemAt(i, QFormLayout::LabelRole); + QTextEdit* edit = qobject_cast(edit_item->widget()); + QLayoutItem* button_item = form_layout->itemAt(i, QFormLayout::FieldRole); + QPushButton* button = qobject_cast(button_item->widget()); + if (start_index + i < examples->size()) { + edit->setText(QString::fromStdString(examples->at(start_index + i))); + edit->setEnabled(true); + setButtonEnabled(button, true); + } + else { + } + } + ++page_number; +} + +void ExamplesWidget::prev() +{ + if (page_number == 0) { + return; + } + clear(); + if (page_number == 1) { + set(examples); + --page_number; + return; + } + page_number -= 2; + next(); +} + +std::vector ExamplesWidget::extract() +{ + std::vector extracted; + if (!examples) { + return extracted; + } + for (size_t i = 0; i < chosen.size(); ++i) { + if (chosen[i]) { + extracted.push_back(examples->at(i)); + } + } + return extracted; +} + +void ExamplesWidget::clear() +{ + for (size_t i = 0; i < edits_in_page; ++i) { + QLayoutItem* item = form_layout->itemAt(i, QFormLayout::LabelRole); + if (QTextEdit* edit = qobject_cast(item->widget())) { + edit->clear(); + } + QLayoutItem* button_item = form_layout->itemAt(i, QFormLayout::FieldRole); + QPushButton* button = qobject_cast(button_item->widget()); + setButtonEnabled(button, false); + } +} + +void ExamplesWidget::updateChosen(size_t index, bool choice, QPushButton *button) +{ + if (chosen.size() <= index) { + return; + } + chosen.at(index) = choice; + if (choice) { + setButtonChosen(button); + } + else { + setButtonEnabled(button, true); + } +} + diff --git a/qt/ExamplesWidget.hpp b/qt/ExamplesWidget.hpp new file mode 100644 index 0000000..9679172 --- /dev/null +++ b/qt/ExamplesWidget.hpp @@ -0,0 +1,42 @@ +#ifndef EXAMPLESWIDGET_H +#define EXAMPLESWIDGET_H + +#include +#include +#include +#include +#include + +namespace Ui { +class ExamplesWidget; +} + +class ExamplesWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ExamplesWidget(QWidget *parent = nullptr); + ~ExamplesWidget(); +public slots: + void set(const std::vector* new_examples); + void next(); + void prev(); + void setButtonEnabled(QPushButton* button, bool enabled); + void setButtonChosen(QPushButton* button); + std::vector extract(); + +private slots: + void clear(); + void updateChosen(size_t index, bool choice, QPushButton* button); + +private: + Ui::ExamplesWidget *ui; + const std::vector* examples; + std::vector chosen; + QFormLayout* form_layout; + const size_t edits_in_page = 3; + size_t page_number; +}; + +#endif // EXAMPLESWIDGET_H diff --git a/qt/ExamplesWidget.ui b/qt/ExamplesWidget.ui new file mode 100644 index 0000000..833e33b --- /dev/null +++ b/qt/ExamplesWidget.ui @@ -0,0 +1,89 @@ + + + ExamplesWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + 0 + 0 + + + + + + + + + + + + + < + + + + + + + > + + + + + + + + + + + pushButton_2 + clicked() + ExamplesWidget + next() + + + 272 + 216 + + + 391 + 337 + + + + + pushButton + clicked() + ExamplesWidget + prev() + + + 63 + 221 + + + 70 + 321 + + + + + + next() + prev() + + diff --git a/qt/ImagesWidget.cpp b/qt/ImagesWidget.cpp new file mode 100644 index 0000000..90e46e6 --- /dev/null +++ b/qt/ImagesWidget.cpp @@ -0,0 +1,119 @@ +#include "ImagesWidget.hpp" +#include "AudioWidget.hpp" +#include "ui_ImagesWidget.h" +#include +#include +#include +#include +#include +#include + +IMagesWidget::IMagesWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::IMagesWidget), + pageNumber(0) +{ + ui->setupUi(this); + manager = new QNetworkAccessManager(this); + gridLayout = new QGridLayout; + for (size_t row = 0; row < rows; ++row) { + for (size_t col = 0; col < cols; ++col) { + QPushButton* button = new QPushButton; + button->setStyleSheet("background-color: white"); + connect(button, &QPushButton::clicked, [=](bool toggled) { + updateChosen(row * cols + col, toggled, button); + }); + button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + button->setCheckable(true); + gridLayout->addWidget(button, row, col); + } + } + ui->groupBox->setLayout(gridLayout); +} + +IMagesWidget::~IMagesWidget() +{ + delete ui; +} + +void IMagesWidget::setButtonEnabled(QPushButton* button, bool enabled) { + if (enabled) { + button->setEnabled(true); + button->setChecked(false); + button->setStyleSheet("background-color: white"); + } + else { + button->setStyleSheet("background-color: gray"); + button->setChecked(false); + button->setEnabled(false); + } +} +void IMagesWidget::setButtonChosen(QPushButton* button) { + button->setStyleSheet("background-color: green"); +} + +void IMagesWidget::set(Media images) +{ + m_images = images; + clear(); + chosen.resize(m_images.web.size()); + std::fill(chosen.begin(), chosen.end(), false); + for (size_t i = 0; i < rows * cols; ++i) { + if (i >= images.web.size()) { + return; + } + else { + QUrl imageUrl(QString::fromStdString(m_images.web.at(i).src)); + QNetworkReply *reply = manager->get(QNetworkRequest(imageUrl)); + QLayoutItem* item = gridLayout->itemAtPosition(i / cols, i % cols); + QPushButton* button = qobject_cast(item->widget()); + setButtonEnabled(button, true); + connect(reply, &QNetworkReply::finished, [=]() { + if (reply->error() == QNetworkReply::NoError) { + QImage image; + image.loadFromData(reply->readAll()); + button->setIcon(QIcon(QPixmap::fromImage(image))); + button->setIconSize(QSize(150, 150)); + } + reply->deleteLater(); + }); + } + } +} + +Media IMagesWidget::extract() +{ + Media media; + for (size_t i = 0; i < chosen.size(); ++i) { + if (chosen[i]) { + media.web.push_back(m_images.web.at(i)); + } + } + return media; +} + +void IMagesWidget::updateChosen(size_t index, bool choice, QPushButton* button) +{ + if (chosen.size() <= index) { + return; + } + chosen.at(index) = choice; + if (choice) { + button->setStyleSheet("background-color: green"); + } + else { + button->setStyleSheet("background-color: white"); + } + qDebug() << extract().web.size(); +} + +void IMagesWidget::clear() { + for (size_t row = 0; row < rows; ++row) { + for (size_t col = 0; col < cols; ++col) { + QLayoutItem* item = gridLayout->itemAtPosition(row, col); + QPushButton* button = qobject_cast(item->widget()); + button->setIcon(QIcon()); + setButtonEnabled(button, false); + } + } +} \ No newline at end of file diff --git a/qt/ImagesWidget.hpp b/qt/ImagesWidget.hpp new file mode 100644 index 0000000..2b98d15 --- /dev/null +++ b/qt/ImagesWidget.hpp @@ -0,0 +1,43 @@ +#ifndef IMAGESWIDGET_H +#define IMAGESWIDGET_H + +#include +#include +#include +#include +#include "Media.hpp" + +namespace Ui { +class IMagesWidget; +} + +class IMagesWidget : public QWidget +{ + Q_OBJECT + +public: + explicit IMagesWidget(QWidget *parent = nullptr); + ~IMagesWidget(); + +public slots: + void set(Media images); + Media extract(); + +private slots: + void clear(); + void setButtonEnabled(QPushButton* button, bool enabled); + void setButtonChosen(QPushButton* button); + void updateChosen(size_t index, bool choice, QPushButton* button); + +private: + Ui::IMagesWidget *ui; + Media m_images; + std::vector chosen; + size_t rows = 2; + size_t cols = 3; + size_t pageNumber; + QGridLayout* gridLayout; + QNetworkAccessManager* manager; +}; + +#endif // IMAGESWIDGET_H diff --git a/qt/ImagesWidget.ui b/qt/ImagesWidget.ui new file mode 100644 index 0000000..fba05c6 --- /dev/null +++ b/qt/ImagesWidget.ui @@ -0,0 +1,46 @@ + + + IMagesWidget + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + + + + + + + + + < + + + + + + + > + + + + + + + + + + -- GitLab