diff --git a/.gitignore b/.gitignore index d0095d5..b71b875 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ **/Makefile **/*.cbp **/node-modules/ +**/CmakeLists.txt.user diff --git a/cpp/qt/CMakeLists.txt b/cpp/qt/CMakeLists.txt index 35a6d95..4d6c0d8 100644 --- a/cpp/qt/CMakeLists.txt +++ b/cpp/qt/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.15) project( #[[NAME]] Klips VERSION 1.0 - DESCRIPTION "A root project for several small cpp practice projects" + DESCRIPTION "A root project for several small Qt6 practice projects" LANGUAGES CXX ) @@ -19,4 +19,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_compile_options("-Wall") add_subdirectory(designer) +add_subdirectory(designer-plugin) +add_subdirectory(designer-plugin-collection) add_subdirectory(slots) diff --git a/cpp/qt/README.md b/cpp/qt/README.md new file mode 100644 index 0000000..4fa69bd --- /dev/null +++ b/cpp/qt/README.md @@ -0,0 +1,32 @@ +# Cpp + +```bash +shaunrd0/klips/cpp/qt/ +├── designer # Using Qt Designer to create application GUI +├── designer-plugin # Adding custom widgets as Qt Designer plugins +├── designer-plugin-collection # Adding a collection of widget plugins to Qt Designer +└── README.md +``` + +This directory contains a `CMakeLists.txt`, which can be selected to open as a +project within your preferred IDE. From there, all nested examples can be built, +debugged, and ran. + +The plugin examples will need to be installed for Qt Designer integration to work. +On Linux, Qt Designer looks under `/some/path/to/Qt/Tools/QtCreator/lib/Qt/plugins/designer/`. +On windows or Mac, this path may differ. Unfortunately I don't have these machines to test for myself. + +```bash +cd klips/cpp/qt/designer-plugin-collection +mkdir build && cd build +cmake .. && cmake --build . --target install +``` + +After installing the plugin collection example above, we can open Qt Creator and navigate to the Designer. +We should see the custom collection is available within the Designer, and the contents of the widgets render correctly in the application view. + + +![side-panel-view.png](side-panel-view.png) + + +![plugin-render-view.png](plugin-render-view.png) diff --git a/cpp/qt/designer-plugin-collection/CMakeLists.txt b/cpp/qt/designer-plugin-collection/CMakeLists.txt new file mode 100644 index 0000000..eb32921 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/CMakeLists.txt @@ -0,0 +1,110 @@ +################################################################################ +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Example of making a collection of widget plugins for Qt Designer ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ + +cmake_minimum_required(VERSION 3.15) + +project( + #[[NAME]] DesignerPluginCollection + VERSION 1.0 + DESCRIPTION "Example of a widget plugin collection for Qt Designer" + LANGUAGES CXX +) + +include(GenerateExportHeader) + +add_compile_options(-Wall) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_SHARED_MODULE_PREFIX "") + +set(QT_DIR "$ENV{HOME}/Code/Clones/Qt/" CACHE PATH "Path to Qt6") +# Qt Designer will look in different locations if WIN / Unix. +# These paths are for using Qt Designer integrated within Qt Creator. +# Standalone Qt Designer may use different paths. +if (WIN32) + set(QT_PLUGIN_INSTALL_DIR + "${QT_DIR}/Tools/QtCreator/bin/plugins/designer" + ) + # This path may be different on windows. I have not tested this. + set(QT_PLUGIN_LIBRARY_DIR + "${QT_DIR}/Tools/QtCreator/lib/Qt/lib" + ) +else() + set(QT_PLUGIN_INSTALL_DIR + "${QT_DIR}/Tools/QtCreator/lib/Qt/plugins/designer" + ) + set(QT_PLUGIN_LIBRARY_DIR + "${QT_DIR}/Tools/QtCreator/lib/Qt/lib" + ) +endif() +# This should be set to your Qt6 installation directory. +set(QT_INSTALL_DIR "${QT_DIR}/6.3.1/gcc_64/" CACHE PATH "Path to Qt6 install") +list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}") + +find_package(Qt6 REQUIRED COMPONENTS UiPlugin Core Gui Widgets) + +# Creating a library with two plugins for the collection. +qt_add_library(widget-plugin-library + textview.cpp textview.h + widgetplugin.cpp widgetplugin.h +) +target_sources(widget-plugin-library PRIVATE + textview.cpp textview.h + treeview.cpp treeview.h + widgetplugin.cpp widgetplugin.h +) +set_target_properties(widget-plugin-library PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(widget-plugin-library + PUBLIC Qt::UiPlugin Qt::Core Qt::Gui Qt::Widgets +) + +install(TARGETS widget-plugin-library + RUNTIME DESTINATION "${QT_PLUGIN_LIBRARY_DIR}" + BUNDLE DESTINATION "${QT_PLUGIN_LIBRARY_DIR}" + LIBRARY DESTINATION "${QT_PLUGIN_LIBRARY_DIR}" +) + +generate_export_header(widget-plugin-library) + +# Creating the collection + +qt_add_library(widget-plugin-collection + widgetplugincollection.cpp widgetplugincollection.h +) +target_link_libraries(widget-plugin-collection + Qt6::Widgets Qt6::UiPlugin widget-plugin-library +) +install(TARGETS widget-plugin-collection + RUNTIME DESTINATION "${QT_PLUGIN_INSTALL_DIR}" + BUNDLE DESTINATION "${QT_PLUGIN_INSTALL_DIR}" + LIBRARY DESTINATION "${QT_PLUGIN_INSTALL_DIR}" +) + +# Application that will use the widget plugin + +set(APP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/app-dir.h.in" + "${CMAKE_CURRENT_SOURCE_DIR}/app-dir.h" + @ONLY +) + +qt_add_executable(widget-app + widgetapp.cpp widgetapp.h widgetapp.ui + main.cpp +) +target_link_libraries(widget-app + PRIVATE Qt::Widgets widget-plugin-library +) diff --git a/cpp/qt/designer-plugin-collection/CMakeLists.txt.user b/cpp/qt/designer-plugin-collection/CMakeLists.txt.user new file mode 100644 index 0000000..e54475c --- /dev/null +++ b/cpp/qt/designer-plugin-collection/CMakeLists.txt.user @@ -0,0 +1,197 @@ + + + + + + EnvironmentId + {ce8a8d3d-318d-4c62-a573-71d1755252ce} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 4 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Qt 6.3.1 GCC 64bit + Qt 6.3.1 GCC 64bit + {70d5e2e6-ad48-44fa-b4dd-c54058c4b48b} + 0 + 0 + 0 + + Debug + false + + -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_BUILD_TYPE:STRING=Debug +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} + /home/kapper/Code/klips/cpp/qt/designer-plugin-collection + /home/kapper/Code/klips/cpp/qt/designer-plugin-collection/cmake-build-debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + widget-app + CMakeProjectManager.CMakeRunConfiguration.widget-app + widget-app + false + true + true + false + true + /home/kapper/Code/klips/cpp/qt/designer-plugin-collection/cmake-build-debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/cpp/qt/designer-plugin-collection/app-dir.h b/cpp/qt/designer-plugin-collection/app-dir.h new file mode 100644 index 0000000..5a37bb5 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/app-dir.h @@ -0,0 +1,6 @@ +#ifndef APPDIR_H_IN +#define APPDIR_H_IN + +#define APP_DIR "/home/kapper/Code/klips/cpp/qt/designer-plugin-collection" + +#endif // APPDIR_H_IN diff --git a/cpp/qt/designer-plugin-collection/app-dir.h.in b/cpp/qt/designer-plugin-collection/app-dir.h.in new file mode 100644 index 0000000..0d5dd20 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/app-dir.h.in @@ -0,0 +1,6 @@ +#ifndef APPDIR_H_IN +#define APPDIR_H_IN + +#define APP_DIR "@APP_DIR@" + +#endif // APPDIR_H_IN diff --git a/cpp/qt/designer-plugin-collection/main.cpp b/cpp/qt/designer-plugin-collection/main.cpp new file mode 100644 index 0000000..5d002db --- /dev/null +++ b/cpp/qt/designer-plugin-collection/main.cpp @@ -0,0 +1,18 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Main driver fprogram for practice using signals and slots in Qt ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widgetapp.h" +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + WidgetApp widgetApp; + widgetApp.show(); + return app.exec(); +} diff --git a/cpp/qt/designer-plugin-collection/textview.cpp b/cpp/qt/designer-plugin-collection/textview.cpp new file mode 100644 index 0000000..998796a --- /dev/null +++ b/cpp/qt/designer-plugin-collection/textview.cpp @@ -0,0 +1,10 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Text viewer for signals and slots examples ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "textview.h" diff --git a/cpp/qt/designer-plugin-collection/textview.h b/cpp/qt/designer-plugin-collection/textview.h new file mode 100644 index 0000000..a6111bc --- /dev/null +++ b/cpp/qt/designer-plugin-collection/textview.h @@ -0,0 +1,44 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Text viewer for signals and slots examples ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_TEXTVIEW_H +#define KLIPS_TEXTVIEW_H + +#include "widget-plugin-library_export.h" +#include + +class WIDGET_PLUGIN_LIBRARY_EXPORT TextView : public QPlainTextEdit { + Q_OBJECT + +public: + explicit TextView(QWidget *parent = nullptr) : QPlainTextEdit(parent) { + appendPlainText("This is an example of a custom QTextView widget."); + } + + ~TextView() = default; + + QString includeFile() const { return QStringLiteral("text-view.h"); }; +public: +signals: + void sendTest(); + +private: +signals: + void sentTestPrivate(); + +public slots: + void test() { appendPlainText("Test signal received by TextView."); } + + void testArgs(const QString &message) { appendPlainText(message); } + +private slots: + void testPrivate() {} +}; + +#endif // KLIPS_TEXTVIEW_H diff --git a/cpp/qt/designer-plugin-collection/treeview.cpp b/cpp/qt/designer-plugin-collection/treeview.cpp new file mode 100644 index 0000000..c39d86e --- /dev/null +++ b/cpp/qt/designer-plugin-collection/treeview.cpp @@ -0,0 +1,10 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Tree viewer ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "treeview.h" diff --git a/cpp/qt/designer-plugin-collection/treeview.h b/cpp/qt/designer-plugin-collection/treeview.h new file mode 100644 index 0000000..5848998 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/treeview.h @@ -0,0 +1,36 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Tree viewer ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_TREEVIEW_H +#define KLIPS_TREEVIEW_H + +#include "widget-plugin-library_export.h" +#include + +#include +#include +#include + +class WIDGET_PLUGIN_LIBRARY_EXPORT TreeView : public QTreeView { + Q_OBJECT + +public: + explicit TreeView(QWidget *parent = nullptr) : QTreeView(parent) { + QFileSystemModel *model = new QFileSystemModel; + QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this); + QModelIndex rootModelIndex = model->setRootPath(APP_DIR); + proxy->setSourceModel(model); + setModel(proxy); + setRootIndex(proxy->mapFromSource(rootModelIndex)); + } + + ~TreeView() = default; +}; + +#endif // KLIPS_TREEVIEW_H diff --git a/cpp/qt/designer-plugin-collection/widgetapp.cpp b/cpp/qt/designer-plugin-collection/widgetapp.cpp new file mode 100644 index 0000000..5fb58c1 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetapp.cpp @@ -0,0 +1,15 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Application that uses widget from the collection ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widgetapp.h" + +WidgetApp::WidgetApp(QWidget *parent) : QMainWindow(parent) { + m_widgetApp = new Ui::MainWindow; + m_widgetApp->setupUi(this); +} diff --git a/cpp/qt/designer-plugin-collection/widgetapp.h b/cpp/qt/designer-plugin-collection/widgetapp.h new file mode 100644 index 0000000..56e5b61 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetapp.h @@ -0,0 +1,37 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Application that uses a custom Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_WIDGETAPP_H +#define KLIPS_WIDGETAPP_H + +#include +#include +#include +#include +#include + +#include "ui_widgetapp.h" + +class WidgetApp : public QMainWindow { + Q_OBJECT + +public: + explicit WidgetApp(QWidget *parent = nullptr); + ~WidgetApp() = default; + + Ui::MainWindow * m_widgetApp; +public: +signals: + void sendTest(); + +public slots: + void test(){}; +}; + +#endif // KLIPS_WIDGETAPP_H diff --git a/cpp/qt/designer-plugin-collection/widgetapp.ui b/cpp/qt/designer-plugin-collection/widgetapp.ui new file mode 100644 index 0000000..c367f60 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetapp.ui @@ -0,0 +1,107 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + true + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + 800 + 22 + + + + + File + + + + + + + + + Edit + + + + + Help + + + + + + + + + + 1 + + + + + + + + + + + + Option1 + + + + + Option2 + + + + + Section 2 + + + + + + TreeView + QWidget +
treeview.h
+
+ + TextView + QWidget +
textview.h
+
+
+ + +
diff --git a/cpp/qt/designer-plugin-collection/widgetplugin.cpp b/cpp/qt/designer-plugin-collection/widgetplugin.cpp new file mode 100644 index 0000000..92389ca --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetplugin.cpp @@ -0,0 +1,52 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Example of a generic Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widgetplugin.h" +#include "textview.h" + +#include +#include + +WidgetPlugin::WidgetPlugin(QString group, QString name, + WidgetPlugin::Factory factory) + : m_group(std::move(group)), m_name(std::move(name)), + m_includeFile(name + ".h"), m_factory(std::move(factory)) {} + +WidgetPlugin::WidgetPlugin(QString group, QString name, QString include, + WidgetPlugin::Factory factory) + : m_group(std::move(group)), m_name(std::move(name)), + m_includeFile(std::move(include)), m_factory(std::move(factory)) {} + +QString WidgetPlugin::toolTip() const { return {}; } + +QString WidgetPlugin::whatsThis() const { return {}; } + +QIcon WidgetPlugin::icon() const { return {}; } + +bool WidgetPlugin::isContainer() const { return false; } + +QString WidgetPlugin::group() const { return m_group; } + +QString WidgetPlugin::name() const { return m_name; } + +// TODO: The generated UI headers do not use this member appropriately. +QString WidgetPlugin::includeFile() const { return m_includeFile; } + +QWidget *WidgetPlugin::createWidget(QWidget *parent) { + return m_factory(parent); +} + +bool WidgetPlugin::isInitialized() const { return m_initialized; } + +void WidgetPlugin::initialize(QDesignerFormEditorInterface *) { + if (m_initialized) + return; + + m_initialized = true; +} diff --git a/cpp/qt/designer-plugin-collection/widgetplugin.h b/cpp/qt/designer-plugin-collection/widgetplugin.h new file mode 100644 index 0000000..93c7757 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetplugin.h @@ -0,0 +1,52 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Example Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_WIDGETPLUGIN_H +#define KLIPS_WIDGETPLUGIN_H + +#include + +class WidgetPlugin : public QObject, public QDesignerCustomWidgetInterface { + Q_OBJECT + Q_PLUGIN_METADATA(IID "com.Klips.WidgetPlugin") + Q_INTERFACES(QDesignerCustomWidgetInterface) + + using Factory = std::function; + +public: + WidgetPlugin(QString group, QString name, Factory factory); + WidgetPlugin(QString group, QString name, QString include, Factory factory); + + explicit WidgetPlugin(QObject *parent = nullptr) : QObject(parent) {} + + ~WidgetPlugin() = default; + +public: + [[nodiscard]] QString group() const override; + [[nodiscard]] QString name() const override; + [[nodiscard]] QString includeFile() const override; + QWidget *createWidget(QWidget *parent) override; + + [[nodiscard]] QString toolTip() const override; + [[nodiscard]] QString whatsThis() const override; + [[nodiscard]] QIcon icon() const override; + [[nodiscard]] bool isContainer() const override; + [[nodiscard]] bool isInitialized() const override; + void initialize(QDesignerFormEditorInterface *core) override; + +private: + bool m_initialized = false; + + QString m_group; + QString m_name; + QString m_includeFile; + Factory m_factory; +}; + +#endif // KLIPS_WIDGETPLUGIN_H diff --git a/cpp/qt/designer-plugin-collection/widgetplugincollection.cpp b/cpp/qt/designer-plugin-collection/widgetplugincollection.cpp new file mode 100644 index 0000000..f144d7a --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetplugincollection.cpp @@ -0,0 +1,28 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Collection of widget plugins for Qt Designer ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widgetplugincollection.h" +#include "textview.h" +#include "treeview.h" +#include "widgetplugin.h" + +WidgetPluginCollection::WidgetPluginCollection(QObject *parent) + : QObject(parent), m_collectionName("Klips Widget Plugin Collection") { + m_collection = { + new WidgetPlugin(m_collectionName, "Text View Widget", "text-view.h", + [](QWidget *parent) { return new TextView(parent); }), + new WidgetPlugin(m_collectionName, "tree-view", + [](QWidget *parent) { return new TreeView(parent); }), + + }; +} +QList +WidgetPluginCollection::customWidgets() const { + return m_collection; +} diff --git a/cpp/qt/designer-plugin-collection/widgetplugincollection.h b/cpp/qt/designer-plugin-collection/widgetplugincollection.h new file mode 100644 index 0000000..89e3282 --- /dev/null +++ b/cpp/qt/designer-plugin-collection/widgetplugincollection.h @@ -0,0 +1,22 @@ + +#ifndef DESIGNERPLUGINCOLLECTION_WIDGETPLUGINCOLLECTION_H +#define DESIGNERPLUGINCOLLECTION_WIDGETPLUGINCOLLECTION_H + +#include + +class WidgetPluginCollection : public QObject, + public QDesignerCustomWidgetCollectionInterface { + Q_OBJECT + Q_PLUGIN_METADATA(IID "com.Klips.WidgetPluginCollection") + Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) + +public: + explicit WidgetPluginCollection(QObject *parent = nullptr); + [[nodiscard]] QList customWidgets() const; + +private: + QList m_collection; + QString m_collectionName; +}; + +#endif // DESIGNERPLUGINCOLLECTION_WIDGETPLUGINCOLLECTION_H diff --git a/cpp/qt/designer-plugin/CMakeLists.txt b/cpp/qt/designer-plugin/CMakeLists.txt new file mode 100644 index 0000000..df170ac --- /dev/null +++ b/cpp/qt/designer-plugin/CMakeLists.txt @@ -0,0 +1,76 @@ +################################################################################ +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Example of making widget plugins for Qt Designer ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ + +cmake_minimum_required(VERSION 3.15) + +project( + #[[NAME]] DesignerPlugin + VERSION 1.0 + DESCRIPTION "Example of a widget plugin for Qt Designer" + LANGUAGES CXX +) + +include(GenerateExportHeader) + +add_compile_options(-Wall) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_SHARED_MODULE_PREFIX "") + +set(QT_DIR "$ENV{HOME}/Code/Clones/Qt/" CACHE PATH "Path to Qt6") +# Qt Designer will look in different locations if WIN / Unix. +if (WIN32) + set(QT_PLUGIN_INSTALL_DIR + "${QT_DIR}/Tools/QtCreator/bin/plugins/designer" + ) +else() + set(QT_PLUGIN_INSTALL_DIR + "${QT_DIR}/Tools/QtCreator/lib/Qt/plugins/designer" + ) +endif() +# This should be set to your Qt6 installation directory. +set(QT_INSTALL_DIR "${QT_DIR}/6.3.1/gcc_64/" CACHE PATH "Path to Qt6 install") +list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}") + +find_package(Qt6 REQUIRED COMPONENTS UiPlugin Core Gui Widgets) + +# Creating the plugin + +qt_add_library(widget-plugin) +target_sources(widget-plugin PRIVATE + text-view.cpp text-view.h + widget-plugin.cpp widget-plugin.h +) +set_target_properties(widget-plugin PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) +target_link_libraries(widget-plugin PUBLIC + Qt::UiPlugin Qt::Core Qt::Gui Qt::Widgets +) + +install(TARGETS widget-plugin + RUNTIME DESTINATION "${QT_PLUGIN_INSTALL_DIR}" + BUNDLE DESTINATION "${QT_PLUGIN_INSTALL_DIR}" + LIBRARY DESTINATION "${QT_PLUGIN_INSTALL_DIR}" +) + +# Application that will use the widget plugin + +qt_add_executable(widget-app + widget-app.cpp widget-app.h widget-app.ui + main.cpp +) +target_link_libraries(widget-app PRIVATE + Qt::Widgets widget-plugin +) diff --git a/cpp/qt/designer-plugin/CMakeLists.txt.user b/cpp/qt/designer-plugin/CMakeLists.txt.user new file mode 100644 index 0000000..0d323a4 --- /dev/null +++ b/cpp/qt/designer-plugin/CMakeLists.txt.user @@ -0,0 +1,197 @@ + + + + + + EnvironmentId + {ce8a8d3d-318d-4c62-a573-71d1755252ce} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + false + true + false + 0 + true + true + 0 + 8 + true + false + 1 + true + true + true + *.md, *.MD, Makefile + false + true + true + + + + ProjectExplorer.Project.PluginSettings + + + true + false + true + true + true + true + + + 0 + true + + true + true + Builtin.DefaultTidyAndClazy + 4 + + + + true + + + + + ProjectExplorer.Project.Target.0 + + Desktop + Qt 6.3.1 GCC 64bit + Qt 6.3.1 GCC 64bit + {70d5e2e6-ad48-44fa-b4dd-c54058c4b48b} + 0 + 0 + 0 + + Debug + false + + -DCMAKE_GENERATOR:STRING=Ninja +-DCMAKE_BUILD_TYPE:STRING=Debug +-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} +-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} +-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} +-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} +-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} + /home/kapper/Code/klips/cpp/qt/designer-plugin + /home/kapper/Code/klips/cpp/qt/designer-plugin/cmake-build-debug + + + + + all + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + + + clean + + false + + true + Build + CMakeProjectManager.MakeStep + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + false + + Debug + CMakeProjectManager.CMakeBuildConfiguration + + 1 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + + false + ProjectExplorer.DefaultDeployConfiguration + + 1 + + true + true + true + + 2 + + widget-app + CMakeProjectManager.CMakeRunConfiguration.widget-app + widget-app + false + true + true + false + true + /home/kapper/Code/klips/cpp/qt/designer-plugin/cmake-build-debug + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/cpp/qt/designer-plugin/main.cpp b/cpp/qt/designer-plugin/main.cpp new file mode 100644 index 0000000..8b30883 --- /dev/null +++ b/cpp/qt/designer-plugin/main.cpp @@ -0,0 +1,18 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Main driver fprogram for practice using signals and slots in Qt ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widget-app.h" +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + WidgetApp widgetApp; + widgetApp.show(); + return app.exec(); +} diff --git a/cpp/qt/designer-plugin/text-view.cpp b/cpp/qt/designer-plugin/text-view.cpp new file mode 100644 index 0000000..226f195 --- /dev/null +++ b/cpp/qt/designer-plugin/text-view.cpp @@ -0,0 +1,10 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Text viewer for signals and slots examples ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "text-view.h" diff --git a/cpp/qt/designer-plugin/text-view.h b/cpp/qt/designer-plugin/text-view.h new file mode 100644 index 0000000..d68f2d1 --- /dev/null +++ b/cpp/qt/designer-plugin/text-view.h @@ -0,0 +1,40 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Text viewer for signals and slots examples ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_TEXTVIEW_H +#define KLIPS_TEXTVIEW_H + +#include + +class TextView : public QPlainTextEdit { + Q_OBJECT + +public: + explicit TextView(QWidget *parent = nullptr) : QPlainTextEdit(parent) { } + + ~TextView() = default; + +public: +signals: + void sendTest(); + +private: +signals: + void sentTestPrivate(); + +public slots: + void test() { appendPlainText("Test signal received by TextView."); } + + void testArgs(const QString &message) { appendPlainText(message); } + +private slots: + void testPrivate() {} +}; + +#endif // KLIPS_TEXTVIEW_H diff --git a/cpp/qt/designer-plugin/widget-app.cpp b/cpp/qt/designer-plugin/widget-app.cpp new file mode 100644 index 0000000..1ab4e2b --- /dev/null +++ b/cpp/qt/designer-plugin/widget-app.cpp @@ -0,0 +1,16 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Application that uses a custom Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widget-app.h" +#include "widget-plugin.h" + +WidgetApp::WidgetApp(QWidget *parent) : QMainWindow(parent) { + m_ui = new Ui::MainWindow; + m_ui->setupUi(this); +} diff --git a/cpp/qt/designer-plugin/widget-app.h b/cpp/qt/designer-plugin/widget-app.h new file mode 100644 index 0000000..32bff47 --- /dev/null +++ b/cpp/qt/designer-plugin/widget-app.h @@ -0,0 +1,38 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Application that uses a custom Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_WIDGETAPP_H +#define KLIPS_WIDGETAPP_H + +#include +#include +#include +#include +#include + +#include "ui_widget-app.h" + +class WidgetApp : public QMainWindow { + Q_OBJECT + +public: + WidgetApp(QWidget *parent = nullptr); + ~WidgetApp() = default; + + Ui::MainWindow *m_ui; + +public: +signals: + void sendTest(); + +public slots: + void test(){}; +}; + +#endif // KLIPS_WIDGETAPP_H diff --git a/cpp/qt/designer-plugin/widget-app.ui b/cpp/qt/designer-plugin/widget-app.ui new file mode 100644 index 0000000..5617c0d --- /dev/null +++ b/cpp/qt/designer-plugin/widget-app.ui @@ -0,0 +1,33 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + + + 0 + 0 + 800 + 22 + + + + + + + + diff --git a/cpp/qt/designer-plugin/widget-plugin.cpp b/cpp/qt/designer-plugin/widget-plugin.cpp new file mode 100644 index 0000000..4b38dd4 --- /dev/null +++ b/cpp/qt/designer-plugin/widget-plugin.cpp @@ -0,0 +1,67 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Example Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#include "widget-plugin.h" +#include "text-view.h" + +#include + +QString WidgetPlugin::toolTip() const +{ + return {}; +} + +QString WidgetPlugin::whatsThis() const +{ + return {}; +} + +QIcon WidgetPlugin::icon() const +{ + return {}; +} + +bool WidgetPlugin::isContainer() const +{ + return false; +} + +QString WidgetPlugin::group() const +{ + return m_group; +} + +QString WidgetPlugin::name() const +{ + return QStringLiteral("KlipsWidgetPlugin"); +} + +QString WidgetPlugin::includeFile() const +{ + return QStringLiteral("widget-plugin.h"); +} + +QWidget *WidgetPlugin::createWidget(QWidget *parent) +{ + return new TextView(parent); +} + +bool WidgetPlugin::isInitialized() const +{ + return m_initialized; +} + +void WidgetPlugin::initialize(QDesignerFormEditorInterface *) +{ + + if (m_initialized) + return; + + m_initialized = true; +} diff --git a/cpp/qt/designer-plugin/widget-plugin.h b/cpp/qt/designer-plugin/widget-plugin.h new file mode 100644 index 0000000..cac11ec --- /dev/null +++ b/cpp/qt/designer-plugin/widget-plugin.h @@ -0,0 +1,45 @@ +/*############################################################################## +## Author: Shaun Reed ## +## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ## +## About: Example Qt Designer widget plugin ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +################################################################################ +*/ + +#ifndef KLIPS_WIDGETPLUGIN_H +#define KLIPS_WIDGETPLUGIN_H + +#include + +class WidgetPlugin : public QObject, public QDesignerCustomWidgetInterface { +Q_OBJECT +Q_PLUGIN_METADATA(IID "com.Klips.WidgetPlugin") +Q_INTERFACES(QDesignerCustomWidgetInterface) + +public: + explicit WidgetPlugin(QObject *parent = nullptr) : QObject(parent) {} + + ~WidgetPlugin() = default; +public: + QString group() const override; + QString name() const override; + QString includeFile() const override; + QWidget *createWidget(QWidget *parent) override; + + QString toolTip() const override; + QString whatsThis() const override; + QIcon icon() const override; + bool isContainer() const override; + bool isInitialized() const override; + void initialize(QDesignerFormEditorInterface *core) override; + +private: + bool m_initialized = false; + + QString m_group; + QString m_name; + QString m_includeFile; +}; + +#endif // KLIPS_WIDGETPLUGIN_H diff --git a/cpp/qt/designer/CMakeLists.txt.user b/cpp/qt/designer/CMakeLists.txt.user index b4bdb9c..d9861d7 100644 --- a/cpp/qt/designer/CMakeLists.txt.user +++ b/cpp/qt/designer/CMakeLists.txt.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -161,12 +161,15 @@ 2 - ProjectExplorer.CustomExecutableRunConfiguration - + designer + CMakeProjectManager.CMakeRunConfiguration.designer + designer false true + true false true + /home/kapper/Code/klips/cpp/qt/designer/cmake-build-debug 1 diff --git a/cpp/qt/plugin-render-view.png b/cpp/qt/plugin-render-view.png new file mode 100644 index 0000000..5794502 Binary files /dev/null and b/cpp/qt/plugin-render-view.png differ diff --git a/cpp/qt/side-panel-view.png b/cpp/qt/side-panel-view.png new file mode 100644 index 0000000..bea8ead Binary files /dev/null and b/cpp/qt/side-panel-view.png differ diff --git a/cpp/qt/slots/text-view.h b/cpp/qt/slots/text-view.h index a325e9e..f9427ca 100644 --- a/cpp/qt/slots/text-view.h +++ b/cpp/qt/slots/text-view.h @@ -22,7 +22,7 @@ public: public: signals: - void sendTest(); + void sendTest()QWidget; private: signals: