added simple example

This commit is contained in:
Andrei Yankovich 2022-01-16 19:51:07 +03:00
parent ff6c7ae397
commit 4dd75025f7
12 changed files with 197 additions and 21 deletions

View File

@ -1,10 +1,15 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.15
import DoctorPillModule 1.0
ApplicationWindow {
width: 800
height: 600
visible: true
DoctorView {
anchors.fill: parent
model: (doctorPillMpdel)? doctorPillMpdel: null
}
}

View File

@ -7,7 +7,32 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <doctorpill.h>
#include <thread>
class EmptyPill: public DP::iPill {
// iPill interface
public:
QString name() const override {
return "EmptyPill";
};
QString description() const override {
return "Pill For Test. This pill cant be fixed ";
};
protected:
bool diagnostic() const override {
std::this_thread::sleep_for(std::chrono::seconds(5));
return true;
};
bool fix() const override {
return false;
};
};
int main(int argc, char *argv[]) {
QCoreApplication::setOrganizationName("QuasarApp");
@ -20,9 +45,15 @@ int main(int argc, char *argv[]) {
return -1;
}
DP::DoctorModel model({QSharedPointer<EmptyPill>::create()});
engine.load("qrc:/Main.qml");
if (engine.rootObjects().isEmpty())
return -2;
QQmlContext* rootContext = engine.rootContext();
if (rootContext)
rootContext->setContextProperty("doctorPillMpdel", &model);
return app.exec();
}

View File

@ -35,8 +35,8 @@ add_library(${PROJECT_NAME} ${SOURCE_CPP} ${SOURCE_QRC} ${SOURCE_CPP_GUI})
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core )
if (DOCTOR_PILL_GUI)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Quick )
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick Concurrent REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Concurrent Qt${QT_VERSION_MAJOR}::Quick )
endif()
target_include_directories(${PROJECT_NAME} PUBLIC ${PUBLIC_INCUDE_DIR})
@ -56,5 +56,5 @@ set(LANGS ${CMAKE_CURRENT_SOURCE_DIR}/languages/en.ts
prepareQM(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/../ "${LANGS}")
set(QML_IMPORT_PATH ${QML_IMPORT_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/src" CACHE STRING "" FORCE)
set(QML_IMPORT_PATH ${QML_IMPORT_PATH} "${CMAKE_CURRENT_SOURCE_DIR}" CACHE STRING "" FORCE)

View File

@ -13,6 +13,8 @@ namespace DP {
Doctor::Doctor(const QList<QSharedPointer<iPill> > &base) {
_pillsData = base;
qRegisterMetaType<QList<QSharedPointer<iPill> >>();
}
void Doctor::diagnostic(bool fix) const {
@ -21,6 +23,10 @@ void Doctor::diagnostic(bool fix) const {
QList<QSharedPointer<iPill> > detected;
QList<QSharedPointer<iPill> > fixedSuccessful;
float progress = 0;
float progressStep = 1.0f / _pillsData.size();
emit sigDiagnosticProgressChanged(progress);
for (const auto &pill: _pillsData) {
if (pill->diagnostic()) {
if (fix) {
@ -33,15 +39,16 @@ void Doctor::diagnostic(bool fix) const {
detected.push_back(pill);
}
}
progress += progressStep;
emit sigDiagnosticProgressChanged(progress);
}
if (failed.size()) {
emit sigFixesFailed(failed);
}
if (detected.count()) {
emit sigTroubleDetected(detected);
}
emit sigDiagnosticFinished(detected);
if (fixedSuccessful.count()) {
emit sigFixesFinishedSuccessful(fixedSuccessful);

View File

@ -39,6 +39,7 @@ public:
* @see Doctor::addPill
* @see Doctor::sigFixesFailed
* @see Doctor::sigFixesFinishedSuccessful
* @see Doctor::sigDiagnosticFinished
*/
void diagnostic(bool fix = false) const;
@ -64,14 +65,14 @@ public:
void addPill(const QSharedPointer<iPill>& pill);
signals:
/**
* @brief sigTroubleDetected This signal will emited when The doctor object found issues in this application.
* @brief sigDiagnosticFinished This signal will emited when The doctor object found issues in this application.
* @param issues this is list of detected issues.
* @see Doctor::diagnostic
* @see Doctor::fix
* @see Doctor::sigFixesFailed
* @see Doctor::sigFixesFinishedSuccessful
*/
void sigTroubleDetected(QList<QSharedPointer<iPill>> issues) const;
void sigDiagnosticFinished(QList<QSharedPointer<iPill>> issues) const;
/**
* @brief sigFixesFailed This signal emited when the doctor can't fix foundet issues.
@ -85,6 +86,11 @@ signals:
*/
void sigFixesFinishedSuccessful(QList<QSharedPointer<iPill>> issues) const;
/**
* @brief sigDiagnosticProgressChanged This signal emitted when progress of diagnstic changed.
* @param progress This is ptogress of diagnostic process from 0 to 1
*/
void sigDiagnosticProgressChanged(float progress) const;
private:
QList<QSharedPointer<iPill>> _pillsData;
};

View File

@ -11,6 +11,8 @@
#include <QString>
#include "doctorpill_global.h"
#include <QMetaType>
#include <QSharedPointer>
namespace DP {
@ -70,5 +72,10 @@ protected:
friend class DoctorTest;
};
}
Q_DECLARE_METATYPE(QSharedPointer<DP::iPill>);
Q_DECLARE_METATYPE(QList<QSharedPointer<DP::iPill>>);
#endif // IPILL_H

View File

@ -7,13 +7,30 @@
#include "doctormodel.h"
#include <QHash>
#include <QtConcurrent>
namespace DP {
DoctorModel::DoctorModel(const QList<QSharedPointer<iPill>> &base):
_doctor(base)
{
connect(&_doctor, &Doctor::sigDiagnosticFinished,
this, &DoctorModel::handleDiagnostcFinished,
Qt::QueuedConnection);
connect(&_doctor, &Doctor::sigDiagnosticProgressChanged,
this, &DoctorModel::handleDiagnosticProgressChanged,
Qt::QueuedConnection);
connect(&_doctor, &Doctor::sigFixesFailed,
this, &DoctorModel::handleFixFailed,
Qt::QueuedConnection);
connect(&_doctor, &Doctor::sigFixesFinishedSuccessful,
this, &DoctorModel::handleFixSuccessful,
Qt::QueuedConnection);
setState(ViewState::BeginDiagnostic);
}
int DoctorModel::rowCount(const QModelIndex &) const {
@ -67,7 +84,16 @@ void DoctorModel::usePill(QString pillName) {
}
void DoctorModel::diagnostic() {
_doctor.diagnostic();
auto work = [this](){
_doctor.diagnostic();
};
setState(ViewState::SearchBugs);
auto val = QtConcurrent::run(work);
}
void DoctorModel::handleFixFailed(QList<QSharedPointer<iPill>> failed) {
@ -84,15 +110,46 @@ void DoctorModel::handleFixSuccessful(QList<QSharedPointer<iPill>> successful) {
}
}
void DoctorModel::handleBugDetected(QList<QSharedPointer<iPill>> bugDetected) {
void DoctorModel::handleDiagnostcFinished(QList<QSharedPointer<iPill> > issues) {
beginResetModel();
_viewData.clear();
for (const auto &pill : qAsConst(bugDetected)) {
for (const auto &pill : qAsConst(issues)) {
_viewData[pill->name()] = Issue{0, pill};
}
endResetModel();
if (_viewData.size())
setState(ViewState::BugFound);
else
setState(ViewState::AllIsFine);
}
void DoctorModel::handleDiagnosticProgressChanged(float progress) {
setProgress(progress);
}
double DoctorModel::progress() const {
return _progress;
}
void DoctorModel::setProgress(double newProgress) {
if (qFuzzyCompare(_progress, newProgress))
return;
_progress = newProgress;
emit progressChanged();
}
int DoctorModel::state() const {
return _state;
}
void DoctorModel::setState(int newState) {
if (_state == newState)
return;
_state = newState;
emit stateChanged();
}
}

View File

@ -9,23 +9,27 @@
#define PILLSMODEL_H
#include <QAbstractListModel>
#include <QFuture>
#include <DoctorPillCore/doctor.h>
namespace DP {
struct Issue {
int _status = 0;
QSharedPointer<iPill> _pill = nullptr;
};
/**
* @brief The PillsModel class This is gui model of available pills.
*/
class DoctorModel: public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(double progress READ progress WRITE setProgress NOTIFY progressChanged)
Q_PROPERTY(int state READ state WRITE setState NOTIFY stateChanged)
struct Issue {
int _status = 0;
QSharedPointer<iPill> _pill = nullptr;
};
enum Roles {
Name = Qt::UserRole,
Description,
Status
@ -37,7 +41,15 @@ class DoctorModel: public QAbstractListModel
Failed
};
enum ViewState {
BeginDiagnostic,
SearchBugs,
BugFound,
AllIsFine,
};
public:
DoctorModel(const QList<QSharedPointer<iPill>> &base);
void addPill(const QSharedPointer<iPill>& pill);
@ -48,14 +60,29 @@ public:
Q_INVOKABLE void usePill(QString pillName);
Q_INVOKABLE void diagnostic();
double progress() const;
int state() const;
signals:
void progressChanged();
void stateChanged();
private slots:
void handleFixFailed(QList<QSharedPointer<iPill>>);
void handleFixSuccessful(QList<QSharedPointer<iPill>>);
void handleBugDetected(QList<QSharedPointer<iPill>>);
void handleDiagnostcFinished(QList<QSharedPointer<iPill>>);
void handleDiagnosticProgressChanged(float);
private:
void setProgress(double newProgress);
void setState(int newState);
int _state;
Doctor _doctor;
QHash<QString, Issue> _viewData;
double _progress;
QFuture<void> _diagnosticWork;
};
}

View File

@ -10,26 +10,42 @@ Page {
signal contactWithDevsPressed();
ColumnLayout {
contentItem: ColumnLayout {
Label {
id: atansionMsg
text: qsTr("Attention: Please use this page only if you knows what you do. If your application works correctly then please - do nothing.");
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
wrapMode: Label.WordWrap
Layout.fillWidth: true
}
Label {
id: descriptionMsg
text: qsTr("This is your personal application doctor room! The doctor automatically check your application to exits errors. If the Doctor found any errors he suggest solution of your issue");
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
wrapMode: Label.WordWrap
Layout.fillWidth: true
}
Label {
id: allIsFineMsg
text: qsTr("The Doctor not found any issues. If you sure that application is works wrong then you can contact with developers.");
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
wrapMode: Label.WordWrap
Layout.fillWidth: true
}
Button {
id: contactButton
text: qsTr("Contact with Developers");
Layout.alignment: Qt.AlignHCenter
onClicked: {
contactWithDevsPressed();
}
@ -43,6 +59,7 @@ Page {
Button {
id: diagnosticButton
text: qsTr("Diagnostic");
Layout.alignment: Qt.AlignHCenter
onClicked: {
if (root.model) {
@ -102,7 +119,8 @@ Page {
}
}
state: "beginDiagnostic"
state: (root.model)? privateRoot.getState(root.model.state): "beginDiagnostic"
//beginDiagnostic
//searchBugs
@ -261,4 +279,17 @@ Page {
}
}
]
Item {
id: privateRoot
function getState(state) {
switch(state) {
case 0: return "beginDiagnostic";
case 1: return "searchBugs";
case 2: return "bugFound";
case 3: return "allIsFine";
}
}
}
}

View File

@ -1,3 +1,3 @@
module QuasarAppCreditsModule
module DoctorPillModule
DoctorView 1.0 DoctorView.qml

View File

@ -26,5 +26,4 @@ bool init(QQmlApplicationEngine *engine) {
return true;
}
}

View File

@ -10,11 +10,14 @@
#include "DoctorPillCore/ipill.h"
#include "DoctorPillCore/doctortest.h"
#include "DoctorPillGui/doctormodel.h"
inline void initDoctorPillResources() {
Q_INIT_RESOURCE(DoctorPill);
}
class QQmlApplicationEngine;
class DoctorModel;
/**
* @brief DP This is base name space of the DoctorPill(DP) library. Please if you use the gui application and gui models then invoke the DP::init method before use this library.
@ -25,7 +28,10 @@ namespace DP {
* @brief init This function initialize the qml gui classes of the DoctorPill library.
* @note if you do not use GUI then this function do nothing.
* @param engine This is qml engine pointer if this pointer is invalid then finction return false.
* @param customModel This is a custom c++ nodel of qml view. IF this option sets to nullptr then doctorpill will use default model.
* @return return true if the library initialized successful else false.
*
* @see DoctorModel
*/
bool DOCTOR_PILL_EXPORT init(QQmlApplicationEngine *engine);