From 47ce6a06898607833184d6e8e2ee81dcbe72917f Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Thu, 8 Mar 2018 18:24:56 +0100 Subject: [PATCH] fixed project template --- ProjectTemplate/App.qml | 8 ++-- ProjectTemplate/app.cpp | 48 +++++++++++------------ ProjectTemplate/app.h | 13 ++---- ProjectTemplate/control.cpp | 44 --------------------- ProjectTemplate/control.h | 34 ---------------- ProjectTemplate/core.pro | 20 +++++----- ProjectTemplate/guiapplication.png | Bin 831 -> 0 bytes ProjectTemplate/qpmx_core.json | 27 ------------- ProjectTemplate/qpmx_quick.json | 28 ------------- ProjectTemplate/qpmx_widgets.json | 28 ------------- ProjectTemplate/quick.pro | 22 ++++------- ProjectTemplate/quick.qrc | 4 +- ProjectTemplate/quick_main.cpp | 17 ++++---- ProjectTemplate/view.qml | 50 +++++++++++++----------- ProjectTemplate/viewmodel.cpp | 31 +++++++++++++++ ProjectTemplate/viewmodel.h | 31 +++++++++++++++ ProjectTemplate/widgets.pro | 7 +--- ProjectTemplate/widgets_main.cpp | 20 ++++------ ProjectTemplate/window.cpp | 24 +++++++----- ProjectTemplate/window.h | 11 +++--- ProjectTemplate/window.ui | 5 ++- ProjectTemplate/wizard.json | 50 +++++++++--------------- README.md | 2 +- deploy.json | 3 ++ examples/mvvmquick/SampleQuick/main.cpp | 1 - 25 files changed, 205 insertions(+), 323 deletions(-) delete mode 100644 ProjectTemplate/control.cpp delete mode 100644 ProjectTemplate/control.h delete mode 100644 ProjectTemplate/guiapplication.png delete mode 100644 ProjectTemplate/qpmx_core.json delete mode 100644 ProjectTemplate/qpmx_quick.json delete mode 100644 ProjectTemplate/qpmx_widgets.json create mode 100644 ProjectTemplate/viewmodel.cpp create mode 100644 ProjectTemplate/viewmodel.h diff --git a/ProjectTemplate/App.qml b/ProjectTemplate/App.qml index 11b615f..26be7b7 100644 --- a/ProjectTemplate/App.qml +++ b/ProjectTemplate/App.qml @@ -1,6 +1,6 @@ -import QtQuick 2.8 -import de.skycoder42.qtmvvm.quick 1.0 - -App { +import QtQuick 2.10 +import de.skycoder42.QtMvvm.Quick 1.0 +QtMvvmApp { + title: qsTr("%{ProjectName}") } diff --git a/ProjectTemplate/app.cpp b/ProjectTemplate/app.cpp index 1aa3938..84c1bfa 100644 --- a/ProjectTemplate/app.cpp +++ b/ProjectTemplate/app.cpp @@ -1,11 +1,18 @@ #include "%{AppHdrName}" +#include "%{VmHdrName}" + +#include %{AppCn}::%{AppCn}(QObject *parent) : - CoreApp(parent), - mainControl(nullptr) + CoreApp(parent) { - //register metatypes etc here, just like you would do in your main before call QCoreApplication::exec + QCoreApplication::setApplicationName(QStringLiteral("%{ProjectName}")); + QCoreApplication::setApplicationVersion(QStringLiteral("1.0.0")); + QCoreApplication::setOrganizationName(QStringLiteral("Example Organization")); +} +void %{AppCn}::performRegistrations() +{ //if you are using a qt resource (e.g. "%{AppQrcFile}"), initialize it here @if '%{UseSettings}' Q_INIT_RESOURCE(%{AppQrcName}); @@ -14,28 +21,19 @@ @endif } -void %{AppCn}::setupParser(QCommandLineParser &parser, bool &allowInvalid) const -{ - CoreApp::setupParser(parser, allowInvalid); - //add additional command line arguments etc here -} - -bool %{AppCn}::startApp(const QCommandLineParser &parser) +int %{AppCn}::startApp(const QStringList &arguments) { + QCommandLineParser parser; + parser.addVersionOption(); + parser.addHelpOption(); + + //add more options + //shows help or version automatically - if(autoShowHelpOrVersion(parser)) - return true; - - //use this method to create services, controls, etc - - //create and show the inital control - mainControl = new %{ControlCn}(this); - showControl(mainControl); - - return true; -} - -void %{AppCn}::aboutToQuit() -{ - //if you need to perform any cleanups, do it here + if(!autoParse(parser, arguments)) + return EXIT_SUCCESS; + + //show a viewmodel to complete the startup + show<%{VmCn}>(); + return EXIT_SUCCESS; } diff --git a/ProjectTemplate/app.h b/ProjectTemplate/app.h index e9a234f..a6ffb35 100644 --- a/ProjectTemplate/app.h +++ b/ProjectTemplate/app.h @@ -1,11 +1,9 @@ #ifndef %{AppGuard} #define %{AppGuard} -#include +#include -#include "%{ControlHdrName}" - -class %{AppCn} : public CoreApp +class %{AppCn} : public QtMvvm::CoreApp { Q_OBJECT @@ -13,14 +11,11 @@ public: explicit %{AppCn}(QObject *parent = nullptr); protected: - void setupParser(QCommandLineParser &parser, bool &allowInvalid) const override; - bool startApp(const QCommandLineParser &parser) override; + void performRegistrations() override; + int startApp(const QStringList &arguments) override; protected slots: void aboutToQuit() override; - -private: - %{ControlCn} *mainControl; }; #undef coreApp diff --git a/ProjectTemplate/control.cpp b/ProjectTemplate/control.cpp deleted file mode 100644 index d022543..0000000 --- a/ProjectTemplate/control.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "%{ControlHdrName}" -@if '%{UseSettings}' -#include -@endif - -%{ControlCn}::%{ControlCn}(QObject *parent) : - Control(parent), - _text(QStringLiteral("hello world")) -{} - -QString %{ControlCn}::text() const -{ - return _text; -} - -@if '%{UseSettings}' -void %{ControlCn}::showSettings() -{ - auto settings = new SettingsControl(this); - settings->setDeleteOnClose(true); - settings->show(); -} - -@endif -void %{ControlCn}::setText(QString text) -{ - if (_text == text) - return; - - _text = text; - emit textChanged(_text); -} - -void %{ControlCn}::onShow() -{ - qDebug("%{ControlName} gui is now visible"); - //logic to execute when the gui is shown -} - -void %{ControlCn}::onClose() -{ - qDebug("%{ControlName} gui is now closed"); - //logic to execute when the gui was closed -} diff --git a/ProjectTemplate/control.h b/ProjectTemplate/control.h deleted file mode 100644 index 614c724..0000000 --- a/ProjectTemplate/control.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef %{ControlGuard} -#define %{ControlGuard} - -#include - -class %{ControlCn} : public Control -{ - Q_OBJECT - - Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) - -public: - explicit %{ControlCn}(QObject *parent = nullptr); - - void onShow() override; - void onClose() override; - - QString text() const; - -public slots: -@if '%{UseSettings}' - void showSettings(); - -@endif - void setText(QString text); - -signals: - void textChanged(QString text); - -private: - QString _text; -}; - -#endif // %{ControlGuard} diff --git a/ProjectTemplate/core.pro b/ProjectTemplate/core.pro index 3e98f55..e44ece6 100644 --- a/ProjectTemplate/core.pro +++ b/ProjectTemplate/core.pro @@ -1,7 +1,8 @@ TEMPLATE = lib -QT += core gui -CONFIG += c++11 staticlib #important because dlls are problematic +QT += mvvmcore +# Creating a static library is typically more efficient. You can still create a shared library if you want to +CONFIG += c++14 static TARGET = %{CoreName} @@ -9,11 +10,11 @@ DEFINES += QT_DEPRECATED_WARNINGS HEADERS += \\ %{AppHdrName} \\ - %{ControlHdrName} + %{VmHdrName} SOURCES += \\ %{AppSrcName} \\ - %{ControlSrcName} + %{VmSrcName} @if '%{UseSettings}' RESOURCES += \\ @@ -23,11 +24,10 @@ RESOURCES += \\ TRANSLATIONS += %{ProjectLowerName}_core_de.ts \\ %{ProjectLowerName}_core_template.ts +DISTFILES += $$TRANSLATIONS @if '%{UseSettings}' -QTMVVM_SETTINGS_FILES = settings.xml -never_true_lupdate_only: SOURCES += .qtmvvm_settings_xml_ts.cppdummy -CONFIG += no_settings_ts_warn - +QTMVVM_TS_SETTINGS = settings.xml +_never_true_condition: SOURCES += $$files($$PWD/.ts-dummy/*) +# Uncomment the following line to automatically generated and update settings translations when building +#PRE_TARGETDEPS += qtmvvm-tsgen @endif -!ReleaseBuild:!DebugBuild:!system(qpmx -d $$shell_quote($$_PRO_FILE_PWD_) --qmake-run init $$QPMX_EXTRA_OPTIONS $$shell_quote($$QMAKE_QMAKE) $$shell_quote($$OUT_PWD)): error(qpmx initialization failed. Check the compilation log for details.) -else: include($$OUT_PWD/qpmx_generated.pri) diff --git a/ProjectTemplate/guiapplication.png b/ProjectTemplate/guiapplication.png deleted file mode 100644 index c121959d9e29dbf2929114018cbff49ebf23955e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 831 zcmV-F1Hk-=P)f03CEi zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9@00N^)L_t(|+U=J;OjA)5 z$A7P&RcuRaQi(>?XdPU{#7lySNfW0xyjeFUM>Z1HlCY7~m4z^LVPo-@m@X_XHV;XR z1DYm8#6;SnU`tgVZ5=p|JZkw6`muPDm;3I!x##@vIrp9OKSnJcr<3BN!_sj8-QJ1P zx-CX+%W4b&sI}PeJ>Y|QzS0N)V`Dez>$~4n!|Utsn4J6sP>@4b5Ay(vi*xk!%rzB2 zxeV|S;P;6yVLX2NXt;YD=;%H%0K+g&4Zz)7ry~yp#HMj9fbsFuyWHJdry~MfkUQWz z)Fl9GYtIP;0!@j3sZ=5yo_0O34V*hNCIF^s5{*Wi0w9~slF3ZF(<=hRI1)fK8f9Q$ zplN?WCbJ)c9r+XlHad}tcO?h>Y-ufU9EVgYh2uE&OF!fi)>;Z6nM{(;=Se1$^-Gt5 z^T5TH0!XLR3=a>pxw(lxSl|kh4XZ5$P_0(+`FxCwjF8LaSYF;=x+XTAw(tSJ-_OLv z1m*H=wzjqaKFjGVZ6hS1P>7kCG`+pO0Cy!3?X;B<_4nUlYHA9l^-JK!iE2T!WpHqi zL?RJUTE79Vc7zkgVlhTXN5e|%w}+h3O>EoVkg)3chv2wt5rS)r|Vq2D}w0^a)un-9bgD9l{^0s9?0p2$P;HzWC?z`a`-KWb_ z+x;?kbNwyg7f@7MZ+N|67zVX?JOmUQ0SHQ}^aGdVhC#-!*`UOa12l<^DjOrE1VBX7s@zd3D}`~lsP*^-Eifa(AM002ov JPDHLkV1ki)a=!oo diff --git a/ProjectTemplate/qpmx_core.json b/ProjectTemplate/qpmx_core.json deleted file mode 100644 index c7a0630..0000000 --- a/ProjectTemplate/qpmx_core.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "dependencies": [ -@if '%{UseSettings}' - { - "package": "de.skycoder42.qtmvvm.settings.core", - "provider": "qpm", - "version": "1.1.2" - }, -@endif - { - "package": "de.skycoder42.qtmvvm.core", - "provider": "qpm", - "version": "1.1.1" - } - ], - "license": { - "file": "", - "name": "" - }, - "prcFile": "", - "priFile": "", - "priIncludes": [ - ], - "publishers": { - }, - "source": false -} diff --git a/ProjectTemplate/qpmx_quick.json b/ProjectTemplate/qpmx_quick.json deleted file mode 100644 index 87805b2..0000000 --- a/ProjectTemplate/qpmx_quick.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "dependencies": [ -@if '%{UseSettings}' - { - "package": "de.skycoder42.qtmvvm.settings.quick", - "provider": "qpm", - "version": "1.1.2" - }, -@endif - { - "package": "de.skycoder42.qtmvvm.quick", - "provider": "qpm", - "version": "1.1.2" - } - ], - "license": { - "file": "", - "name": "" - }, - "prcFile": "", - "priFile": "", - "priIncludes": [ - "../%{CoreName}" - ], - "publishers": { - }, - "source": false -} diff --git a/ProjectTemplate/qpmx_widgets.json b/ProjectTemplate/qpmx_widgets.json deleted file mode 100644 index 1c7c823..0000000 --- a/ProjectTemplate/qpmx_widgets.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "dependencies": [ -@if '%{UseSettings}' - { - "package": "de.skycoder42.qtmvvm.settings.widgets", - "provider": "qpm", - "version": "1.1.3" - }, -@endif - { - "package": "de.skycoder42.qtmvvm.widgets", - "provider": "qpm", - "version": "1.1.2" - } - ], - "license": { - "file": "", - "name": "" - }, - "prcFile": "", - "priFile": "", - "priIncludes": [ - "../%{CoreName}" - ], - "publishers": { - }, - "source": false -} diff --git a/ProjectTemplate/quick.pro b/ProjectTemplate/quick.pro index 24674d0..91972ed 100644 --- a/ProjectTemplate/quick.pro +++ b/ProjectTemplate/quick.pro @@ -1,16 +1,10 @@ TEMPLATE = app -QT += core gui qml quick quickcontrols2 -CONFIG += c++11 +QT += quick mvvmquick +CONFIG += c++14 TARGET = %{QuickName} -# Additional import path used to resolve QML modules in Qt Creator's code model -QML_IMPORT_PATH = - -# Additional import path used to resolve QML modules just for Qt Quick Designer -QML_DESIGNER_IMPORT_PATH = - DEFINES += QT_DEPRECATED_WARNINGS SOURCES += main.cpp @@ -21,11 +15,6 @@ RESOURCES += \\ TRANSLATIONS += %{ProjectLowerName}_quick_de.ts \\ %{ProjectLowerName}_quick_template.ts -# Default rules for deployment. -qnx: target.path = /tmp/$${TARGET}/bin -else: unix:!android: target.path = /opt/$${TARGET}/bin -!isEmpty(target.path): INSTALLS += target - # Link with core project win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../%{CoreName}/release/ -l%{CoreName} else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../%{CoreName}/debug/ -l%{CoreName} @@ -40,5 +29,8 @@ else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PW else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../%{CoreName}/debug/%{CoreName}.lib else:unix: PRE_TARGETDEPS += $$OUT_PWD/../%{CoreName}/lib%{CoreName}.a -!ReleaseBuild:!DebugBuild:!system(qpmx -d $$shell_quote($$_PRO_FILE_PWD_) --qmake-run init $$QPMX_EXTRA_OPTIONS $$shell_quote($$QMAKE_QMAKE) $$shell_quote($$OUT_PWD)): error(qpmx initialization failed. Check the compilation log for details.) -else: include($$OUT_PWD/qpmx_generated.pri) +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = diff --git a/ProjectTemplate/quick.qrc b/ProjectTemplate/quick.qrc index 6688d20..91e9370 100644 --- a/ProjectTemplate/quick.qrc +++ b/ProjectTemplate/quick.qrc @@ -1,8 +1,8 @@ - + App.qml - + %{QuickQmlName} diff --git a/ProjectTemplate/quick_main.cpp b/ProjectTemplate/quick_main.cpp index d3646db..0d14a3e 100644 --- a/ProjectTemplate/quick_main.cpp +++ b/ProjectTemplate/quick_main.cpp @@ -1,18 +1,21 @@ -#include -#include -#include +#include +#include #include <%{AppHdrName}> -REGISTER_CORE_APP(%{AppCn}) +QTMVVM_REGISTER_CORE_APP(%{AppCn}) int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + // If you want to support file dialogs on platforms other then android, use a QApplication instead (and add QT += widgets to the pro file) QGuiApplication app(argc, argv); - qmlRegisterUncreatableType<%{ControlCn}>("com.example.%{ProjectLowerName}", 1, 0, "%{ControlCn}", "Controls cannot be created!"); - - QuickPresenter::createAppEngine(QUrl(QLatin1String("qrc:/qml/App.qml"))); + qmlRegisterUncreatableType<%{VmCn}>("com.example.%{ProjectLowerName}", 1, 0, "%{VmCn}", "ViewModels cannot be created!"); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/App.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; return app.exec(); } diff --git a/ProjectTemplate/view.qml b/ProjectTemplate/view.qml index a6bf8d4..d006906 100644 --- a/ProjectTemplate/view.qml +++ b/ProjectTemplate/view.qml @@ -1,28 +1,34 @@ -import QtQuick 2.8 -import QtQuick.Controls 2.1 +import QtQuick 2.10 +import QtQuick.Vms 2.3 import QtQuick.Layouts 1.3 -import de.skycoder42.quickextras 2.0 -import de.skycoder42.qtmvvm.quick 1.0 +import de.skycoder42.QtMvvm.Core 1.0 +import de.skycoder42.QtMvvm.Quick 1.0 import com.example.%{ProjectLowerName} 1.0 Page { id: mainView - property %{ControlCn} control: null + property %{VmCn} viewModel: null - header: ActionBar { - id: toolbar - title: qsTr("%{ControlClassName}") - showMenuButton: false + header: ContrastToolBar { + RowLayout { + anchors.fill: parent + spacing: 0 + + ToolBarLabel { + text: qsTr("%{VmClassName}") + Layout.fillWidth: true + } @if '%{UseSettings}' - moreMenu: Menu { - MenuItem { - id: settings - text: qsTr("Settings") - onClicked: control.showSettings() + MenuButton { + MenuItem { + id: settings + text: qsTr("Settings") + onClicked: viewModel.showSettings() + } } - } @endif + } } PresenterProgress {} @@ -37,9 +43,9 @@ Page { id: textEdit Layout.fillWidth: true - QtMvvmBinding { - control: mainView.control - controlProperty: "text" + MvvmBinding { + viewModel: mainView.viewModel + viewModelProperty: "text" view: textEdit viewProperty: "text" } @@ -49,12 +55,12 @@ Page { id: textLabel Layout.fillWidth: true - QtMvvmBinding { - control: mainView.control - controlProperty: "text" + MvvmBinding { + viewModel: mainView.viewModel + viewModelProperty: "text" view: textLabel viewProperty: "text" - type: QtMvvmBinding.OneWayFromControl + type: MvvmBinding.OneWayToView } } diff --git a/ProjectTemplate/viewmodel.cpp b/ProjectTemplate/viewmodel.cpp new file mode 100644 index 0000000..25af6b2 --- /dev/null +++ b/ProjectTemplate/viewmodel.cpp @@ -0,0 +1,31 @@ +#include "%{VmHdrName}" +@if '%{UseSettings}' + +#include +@endif + +%{VmCn}::%{VmCn}(QObject *parent) : + ViewModel(parent), + _text(QStringLiteral("hello world")) +{} + +QString %{VmCn}::text() const +{ + return _text; +} + +@if '%{UseSettings}' +void %{VmCn}::showSettings() +{ + show(); +} + +@endif +void %{VmCn}::setText(const QString &text) +{ + if (_text == text) + return; + + _text = text; + emit textChanged(_text); +} diff --git a/ProjectTemplate/viewmodel.h b/ProjectTemplate/viewmodel.h new file mode 100644 index 0000000..e98004c --- /dev/null +++ b/ProjectTemplate/viewmodel.h @@ -0,0 +1,31 @@ +#ifndef %{VmGuard} +#define %{VmGuard} + +#include + +class %{VmCn} : public QtMvvm::ViewModel +{ + Q_OBJECT + + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + +public: + Q_INVOKABLE explicit %{VmCn}(QObject *parent = nullptr); + + QString text() const; + +public Q_SLOTS: +@if '%{UseSettings}' + void showSettings(); + +@endif + void setText(const QString &text); + +Q_SIGNALS: + void textChanged(const QString &text); + +private: + QString _text; +}; + +#endif // %{VmGuard} diff --git a/ProjectTemplate/widgets.pro b/ProjectTemplate/widgets.pro index 283ef1b..a77f40f 100644 --- a/ProjectTemplate/widgets.pro +++ b/ProjectTemplate/widgets.pro @@ -1,7 +1,7 @@ TEMPLATE = app -QT += core gui widgets -CONFIG += c++11 +QT += widgets mvvmwidgets +CONFIG += c++14 TARGET = %{WidgetsName} @@ -30,6 +30,3 @@ else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../%{Co else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../%{CoreName}/release/%{CoreName}.lib else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../%{CoreName}/debug/%{CoreName}.lib else:unix: PRE_TARGETDEPS += $$OUT_PWD/../%{CoreName}/lib%{CoreName}.a - -!ReleaseBuild:!DebugBuild:!system(qpmx -d $$shell_quote($$_PRO_FILE_PWD_) --qmake-run init $$QPMX_EXTRA_OPTIONS $$shell_quote($$QMAKE_QMAKE) $$shell_quote($$OUT_PWD)): error(qpmx initialization failed. Check the compilation log for details.) -else: include($$OUT_PWD/qpmx_generated.pri) diff --git a/ProjectTemplate/widgets_main.cpp b/ProjectTemplate/widgets_main.cpp index 801c97e..8051bd3 100644 --- a/ProjectTemplate/widgets_main.cpp +++ b/ProjectTemplate/widgets_main.cpp @@ -1,25 +1,19 @@ -#include -#include +#include +#include #include <%{AppHdrName}> -@if '%{UseSettings}' -#include -@endif #include "%{WindowHdrName}" -//register the core app to be used -REGISTER_CORE_APP(%{AppCn}) +// Register the core app +QTMVVM_REGISTER_CORE_APP(%{AppCn}) int main(int argc, char *argv[]) { QApplication a(argc, argv); - // automatically sets "WidgetPresenter" as presenter and registers the %{WindowName} class as a widget - // the control this widget belongs to is detected automatically via naming conventions - WidgetPresenter::registerWidget<%{WindowCn}>(); -@if '%{UseSettings}' - WidgetPresenter::registerWidget(); -@endif + // Automatically sets "WidgetPresenter" as presenter and registers the %{WindowName} class as a widget + // The viewmodel this widget belongs to is detected automatically via naming conventions + QtMvvm::WidgetsPresenter::registerView<%{WindowCn}>(); return a.exec(); } diff --git a/ProjectTemplate/window.cpp b/ProjectTemplate/window.cpp index f191184..aa1562e 100644 --- a/ProjectTemplate/window.cpp +++ b/ProjectTemplate/window.cpp @@ -1,24 +1,28 @@ #include "%{WindowHdrName}" #include "ui_%{WindowHdrName}" -#include -%{WindowCn}::%{WindowCn}(Control *mControl, QWidget *parent) : +#include + +%{WindowCn}::%{WindowCn}(QtMvvm::ViewModel *viewModel, QWidget *parent) : QMainWindow(parent), - control(static_cast<%{ControlCn}*>(mControl)), - ui(new Ui::%{WindowCn}) + _viewModel(static_cast<%{VmCn}*>(viewModel)), + _ui(new Ui::%{WindowCn}) { - ui->setupUi(this); + _ui->setupUi(this); @if '%{UseSettings}' - connect(ui->actionSettings, &QAction::triggered, - control, &%{ControlCn}::showSettings); + connect(_ui->actionSettings, &QAction::triggered, + _viewModel, &%{VmCn}::showSettings); @endif - QtMvvmBinding::bind(control, "text", ui->lineEdit, "text"); - QtMvvmBinding::bind(control, "text", ui->label, "text", QtMvvmBinding::OneWayFromControl); + QtMvvm::bind(_viewModel, "text", + _ui->lineEdit, "text"); + QtMvvm::bind(_viewModel, "text", + _ui->label, "text", + QtMvvm::Binding::OneWayToView); } %{WindowCn}::~%{WindowCn}() { - delete ui; + delete _ui; } diff --git a/ProjectTemplate/window.h b/ProjectTemplate/window.h index c5b3964..3630ffb 100644 --- a/ProjectTemplate/window.h +++ b/ProjectTemplate/window.h @@ -1,8 +1,9 @@ #ifndef %{WindowGuard} #define %{WindowGuard} -#include -#include <%{ControlHdrName}> +#include + +#include <%{VmHdrName}> namespace Ui { class %{WindowCn}; @@ -13,12 +14,12 @@ class %{WindowCn} : public QMainWindow Q_OBJECT public: - Q_INVOKABLE %{WindowCn}(Control *mControl, QWidget *parent = nullptr); + Q_INVOKABLE %{WindowCn}(QtMvvm::ViewModel *viewModel, QWidget *parent = nullptr); ~%{WindowCn}(); private: - %{ControlCn} *control; - Ui::%{WindowCn} *ui; + %{VmCn} *_viewModel; + Ui::%{WindowCn} *_ui; }; #endif // %{WindowGuard} diff --git a/ProjectTemplate/window.ui b/ProjectTemplate/window.ui index 10104b5..62141fd 100644 --- a/ProjectTemplate/window.ui +++ b/ProjectTemplate/window.ui @@ -10,6 +10,9 @@ 300 + + %{ProjectName} + @@ -66,7 +69,7 @@ - :/qtmvvm/icons/settings.ico:/qtmvvm/icons/settings.ico + :/de/skycoder42/qtmvvm/icons/settings.ico:/de/skycoder42/qtmvvm/icons/settings.ico Settings diff --git a/ProjectTemplate/wizard.json b/ProjectTemplate/wizard.json index 5f92001..cb359ce 100644 --- a/ProjectTemplate/wizard.json +++ b/ProjectTemplate/wizard.json @@ -6,7 +6,7 @@ "trDescription": "Creates a QtMvvm project skeleton, for easy creation of new QtMvvm projects.", "trDisplayName": "QtMvvm Application Project", "trDisplayCategory": "Application", - "icon": "guiapplication.png", + "icon": "../../global/guiapplication.png", "featuresRequired": [ "QtSupport.Wizards.FeatureQt" ], "enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}", "options": @@ -32,10 +32,10 @@ { "key": "AppCn", "value": "%{JS: Cpp.className('%{AppName}')}" }, { "key": "AppGuard", "value": "%{JS: Cpp.headerGuard('%{AppHdrName}')}" }, - { "key": "ControlHdrName", "value": "%{JS: Cpp.classToFileName('%{ControlClassName}', '%{JS: Util.preferredSuffix('text/x-c++hdr')}')}" }, - { "key": "ControlSrcName", "value": "%{JS: Cpp.classToFileName('%{ControlClassName}', '%{JS: Util.preferredSuffix('text/x-c++src')}')}" }, - { "key": "ControlCn", "value": "%{JS: Cpp.className('%{ControlClassName}')}" }, - { "key": "ControlGuard", "value": "%{JS: Cpp.headerGuard('%{ControlHdrName}')}" }, + { "key": "VmHdrName", "value": "%{JS: Cpp.classToFileName('%{VmClassName}', '%{JS: Util.preferredSuffix('text/x-c++hdr')}')}" }, + { "key": "VmSrcName", "value": "%{JS: Cpp.classToFileName('%{VmClassName}', '%{JS: Util.preferredSuffix('text/x-c++src')}')}" }, + { "key": "VmCn", "value": "%{JS: Cpp.className('%{VmClassName}')}" }, + { "key": "VmGuard", "value": "%{JS: Cpp.headerGuard('%{VmHdrName}')}" }, { "key": "AppQrcName", "value": "%{JS: '%{CoreName}'.toLowerCase()}" }, { "key": "AppQrcFile", "value": "%{JS: Util.fileName('%{AppQrcName}', 'qrc')}" }, @@ -100,14 +100,14 @@ ] }, { - "trDisplayName": "Define Initial Control", - "trShortTitle": "Control", + "trDisplayName": "Define Initial ViewModel", + "trShortTitle": "ViewModel", "typeId": "Fields", "data" : [ { - "name": "ControlName", - "trDisplayName": "Control base name:", + "name": "VmName", + "trDisplayName": "ViewModel base name:", "mandatory": true, "type": "LineEdit", "data": @@ -122,13 +122,13 @@ "data": { "factor": 2 } }, { - "name": "ControlClassName", + "name": "VmClassName", "type": "LineEdit", - "trDisplayName": "Control class name:", + "trDisplayName": "ViewModel class name:", "mandatory": true, "data": { - "trText": "%{ControlName}Control", + "trText": "%{VmName}ViewModel", "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*|)" } }, @@ -139,7 +139,7 @@ "mandatory": true, "data": { - "trText": "%{ControlName}Window", + "trText": "%{VmName}Window", "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*|)" } }, @@ -150,7 +150,7 @@ "mandatory": true, "data": { - "trText": "%{ControlName}View", + "trText": "%{VmName}View", "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*|)" } } @@ -184,10 +184,6 @@ "source": "core.pro", "target": "%{CoreProName}" }, - { - "source": "qpmx_core.json", - "target": "%{CoreDirectory}/qpmx.json" - }, { "source": "app.h", "target": "%{CoreDirectory}/%{AppHdrName}" @@ -197,12 +193,12 @@ "target": "%{CoreDirectory}/%{AppSrcName}" }, { - "source": "control.h", - "target": "%{CoreDirectory}/%{ControlHdrName}" + "source": "viewmodel.h", + "target": "%{CoreDirectory}/%{VmHdrName}" }, { - "source": "control.cpp", - "target": "%{CoreDirectory}/%{ControlSrcName}" + "source": "viewmodel.cpp", + "target": "%{CoreDirectory}/%{VmSrcName}" }, { "source": "core.qrc", @@ -219,11 +215,6 @@ "target": "%{WidgetsProName}", "condition": "%{JS: '%{CreateWidgets}' !== ''}" }, - { - "source": "qpmx_widgets.json", - "target": "%{WidgetsDirectory}/qpmx.json", - "condition": "%{JS: '%{CreateWidgets}' !== ''}" - }, { "source": "widgets_main.cpp", "target": "%{WidgetsDirectory}/main.cpp", @@ -249,11 +240,6 @@ "target": "%{QuickProName}", "condition": "%{JS: '%{CreateQuick}' !== ''}" }, - { - "source": "qpmx_quick.json", - "target": "%{QuickDirectory}/qpmx.json", - "condition": "%{JS: '%{CreateQuick}' !== ''}" - }, { "source": "quick_main.cpp", "target": "%{QuickDirectory}/main.cpp", diff --git a/README.md b/README.md index f9df130..68cabbc 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ If you don't know the Mvvm pattern already, you can read up on the links below. of logic (the models), presentation logic (the viewmodels) and the actual GUI (the views) that is very useful when creating applications that need to support different uis for the same data. -![[The MVVM Pattern](https://msdn.microsoft.com/en-us/library/hh848246.aspx)](https://i-msdn.sec.s-msft.com/dynimg/IC564167.png) +[![The MVVM Pattern](https://i-msdn.sec.s-msft.com/dynimg/IC564167.png)](https://msdn.microsoft.com/en-us/library/hh848246.aspx) Good links to get started: diff --git a/deploy.json b/deploy.json index 9bab12c..e7430bf 100644 --- a/deploy.json +++ b/deploy.json @@ -16,5 +16,8 @@ "license": { "name": "BSD-3-Clause", "path": "LICENSE" + }, + "installs": { + "ProjectTemplate": "Tools/QtCreator/share/qtcreator/templates/wizards/projects/qtmvvm" } } diff --git a/examples/mvvmquick/SampleQuick/main.cpp b/examples/mvvmquick/SampleQuick/main.cpp index 157fbdf..eb19b75 100644 --- a/examples/mvvmquick/SampleQuick/main.cpp +++ b/examples/mvvmquick/SampleQuick/main.cpp @@ -23,7 +23,6 @@ int main(int argc, char *argv[]) qputenv("QML2_IMPORT_PATH", QML_PATH); #endif - QIcon::setThemeSearchPaths({}); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); qDebug() << QQuickStyle::availableStyles() << QQuickStyle::name();