diff --git a/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/CMakeLists.txt b/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/CMakeLists.txt new file mode 100644 index 0000000..efb857b --- /dev/null +++ b/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(DemoApp VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app1-DemoApp + main.cpp +) + +qt_add_qml_module(app1-DemoApp + URI DemoApp + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app1-DemoApp PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app1-DemoApp + PRIVATE Qt6::Quick +) + +install(TARGETS app1-DemoApp + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/Main.qml b/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/Main.qml new file mode 100644 index 0000000..59eddb5 --- /dev/null +++ b/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/Main.qml @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Hello World") + + Text { + anchors.centerIn: parent + text : "Hello World"; + color: "red" + font.pointSize: 20 + } +} diff --git a/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/main.cpp b/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/main.cpp new file mode 100644 index 0000000..7f27924 --- /dev/null +++ b/Qt6QMLBeginnersCode/1.Introduction/1-DemoApp/main.cpp @@ -0,0 +1,40 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("DemoApp", "Main"); + + return app.exec(); + + + /* + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/1-DemoApp/main.qml"_qs); + + QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, + &app, [url](QObject *obj, const QUrl &objUrl) { + qDebug() << "url : " << url; + qDebug() << "objUrl : " << objUrl; + if (!obj && url == objUrl) + QCoreApplication::exit(-1); + }, Qt::QueuedConnection); + + engine.load(url); + + return app.exec(); + */ +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/CMakeLists.txt b/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/CMakeLists.txt new file mode 100644 index 0000000..5b14d09 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/src/main.cpp b/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/src/main.cpp new file mode 100644 index 0000000..29ac2e0 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/src/main.cpp @@ -0,0 +1,18 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/src/views/MainView.qml b/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/src/views/MainView.qml new file mode 100644 index 0000000..41424f8 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/01_todolist_starter/src/views/MainView.qml @@ -0,0 +1,8 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Hello World") +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/CMakeLists.txt b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/CMakeLists.txt new file mode 100644 index 0000000..6fc870a --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick + Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/components/AppHeader.qml new file mode 100644 index 0000000..fb7e5e9 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/components/AppHeader.qml @@ -0,0 +1,79 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + // Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/main.cpp b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/main.cpp new file mode 100644 index 0000000..2919679 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/views/MainView.qml b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/views/MainView.qml new file mode 100644 index 0000000..f3c013b --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/02_app_header/src/views/MainView.qml @@ -0,0 +1,66 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + //Placeholder for header (we'll add this next) + /* + Rectangle{ + Layout.fillWidth: true + Layout.preferredHeight: 80 + color: "transparent" + border.color: root.textColor + border.width: 1 + + Text{ + anchors.centerIn: parent + text: "Header will go here" + color: root.textColor + } + } + */ + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + //The actual AppHeader component to replace the place holder + + //Add a spacer to push things up. Will remove later + Item { + Layout.fillHeight: true + } + + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/CMakeLists.txt b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/CMakeLists.txt new file mode 100644 index 0000000..231b393 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml + src/components/AddTaskBar.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick + Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/components/AddTaskBar.qml b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/components/AddTaskBar.qml new file mode 100644 index 0000000..aa63652 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/components/AddTaskBar.qml @@ -0,0 +1,106 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 60 + + signal taskAdded(string taskText) + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color primaryColor: "#007aff" + property bool darkMode: false + + Rectangle { + id: background + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // Add icon + Rectangle { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + color: root.primaryColor + radius: 18 + + Text { + anchors.centerIn: parent + text: "+" + color: "#ffffff" + font.pixelSize: 20 + font.weight: Font.Bold + } + } + + // Text input + TextField { + id: taskInput + Layout.fillWidth: true + Layout.preferredHeight: 36 + placeholderText: qsTr("Add a new task...") + placeholderTextColor: root.darkMode ? "#888888" : "#999999" + color: root.textColor + font.pixelSize: 16 + selectByMouse: true + + background: Rectangle { + color: "transparent" + border.color: "transparent" + } + + Keys.onReturnPressed: root.addTask() + Keys.onEnterPressed: root.addTask() + + } + + // Add button + Button { + id: addButton + Layout.preferredWidth: 80 + Layout.preferredHeight: 36 + text: qsTr("Add") + enabled: taskInput.text.trim().length > 0 + + background: Rectangle { + color: addButton.enabled ? + (addButton.pressed ? Qt.darker(root.primaryColor, 1.2) : root.primaryColor) : + (root.darkMode ? "#404040" : "#e0e0e0") + radius: 8 + + } + + contentItem: Text { + text: addButton.text + color: addButton.enabled ? "#ffffff" : (root.darkMode ? "#888888" : "#cccccc") + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + } + + onClicked: root.addTask() + } + } + } + } + + function addTask() { + //TODO: Implement task addition logic + console.log("Task added.") + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/components/AppHeader.qml new file mode 100644 index 0000000..fb7e5e9 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/components/AppHeader.qml @@ -0,0 +1,79 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + // Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/main.cpp b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/main.cpp new file mode 100644 index 0000000..2919679 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/views/MainView.qml b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/views/MainView.qml new file mode 100644 index 0000000..4a69a23 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/03_task_bar/src/views/MainView.qml @@ -0,0 +1,77 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + //Placeholder for header (we'll add this next) + /* + Rectangle{ + Layout.fillWidth: true + Layout.preferredHeight: 80 + color: "transparent" + border.color: root.textColor + border.width: 1 + + Text{ + anchors.centerIn: parent + text: "Header will go here" + color: root.textColor + } + } + */ + //The actual AppHeader component to replace the place holder + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + // Add task bar + AddTaskBar { + id: addTaskBar + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + } + + + //Add a spacer to push things up. Will remove later + Item { + Layout.fillHeight: true + } + + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/CMakeLists.txt b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/CMakeLists.txt new file mode 100644 index 0000000..ec2c392 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml + src/components/AddTaskBar.qml + src/components/TaskItem.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick + Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/AddTaskBar.qml b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/AddTaskBar.qml new file mode 100644 index 0000000..aa63652 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/AddTaskBar.qml @@ -0,0 +1,106 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 60 + + signal taskAdded(string taskText) + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color primaryColor: "#007aff" + property bool darkMode: false + + Rectangle { + id: background + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // Add icon + Rectangle { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + color: root.primaryColor + radius: 18 + + Text { + anchors.centerIn: parent + text: "+" + color: "#ffffff" + font.pixelSize: 20 + font.weight: Font.Bold + } + } + + // Text input + TextField { + id: taskInput + Layout.fillWidth: true + Layout.preferredHeight: 36 + placeholderText: qsTr("Add a new task...") + placeholderTextColor: root.darkMode ? "#888888" : "#999999" + color: root.textColor + font.pixelSize: 16 + selectByMouse: true + + background: Rectangle { + color: "transparent" + border.color: "transparent" + } + + Keys.onReturnPressed: root.addTask() + Keys.onEnterPressed: root.addTask() + + } + + // Add button + Button { + id: addButton + Layout.preferredWidth: 80 + Layout.preferredHeight: 36 + text: qsTr("Add") + enabled: taskInput.text.trim().length > 0 + + background: Rectangle { + color: addButton.enabled ? + (addButton.pressed ? Qt.darker(root.primaryColor, 1.2) : root.primaryColor) : + (root.darkMode ? "#404040" : "#e0e0e0") + radius: 8 + + } + + contentItem: Text { + text: addButton.text + color: addButton.enabled ? "#ffffff" : (root.darkMode ? "#888888" : "#cccccc") + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + } + + onClicked: root.addTask() + } + } + } + } + + function addTask() { + //TODO: Implement task addition logic + console.log("Task added.") + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/AppHeader.qml new file mode 100644 index 0000000..fb7e5e9 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/AppHeader.qml @@ -0,0 +1,79 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + // Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/TaskItem.qml b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/TaskItem.qml new file mode 100644 index 0000000..686339f --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/components/TaskItem.qml @@ -0,0 +1,129 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 56 + + required property string taskTitle + required property bool taskDone + + signal toggleDone() + signal deleteTask() + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color completedColor: "#999999" + property color primaryColor: "#007aff" + property bool darkMode: false + + // Constants for this component + readonly property int itemHeight: 56 + readonly property int margins: 4 + readonly property int innerMargins: 12 + readonly property int checkboxSize: 24 + readonly property int deleteButtonSize: 32 + + Rectangle { + id: taskItemBackground + anchors.fill: parent + color: "transparent" + + Rectangle { + id: itemBackground + anchors.fill: parent + anchors.margins: root.margins + color: root.backgroundColor + radius: 8 + border.color: root.taskDone ? "transparent" : (root.darkMode ? "#404040" : "#f0f0f0") + border.width: 1 + opacity: root.taskDone ? 0.7 : 1.0 + + RowLayout { + anchors.fill: parent + anchors.margins: root.innerMargins + spacing: 12 + + // Checkbox + Rectangle { + id: checkbox + Layout.preferredWidth: root.checkboxSize + Layout.preferredHeight: root.checkboxSize + color: root.taskDone ? root.primaryColor : "transparent" + border.color: root.taskDone ? root.primaryColor : (root.darkMode ? "#666666" : "#cccccc") + border.width: 2 + radius: 4 + + // Checkmark + Text { + anchors.centerIn: parent + text: "✓" + color: "#ffffff" + font.pixelSize: 16 + font.weight: Font.Bold + opacity: root.taskDone ? 1.0 : 0.0 + + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.toggleDone() + } + cursorShape: Qt.PointingHandCursor + } + + } + + // Task text + Text { + id: taskText + Layout.fillWidth: true + text: root.taskTitle + color: root.taskDone ? root.completedColor : root.textColor + font.pixelSize: 16 + font.strikeout: root.taskDone + wrapMode: Text.WordWrap + + MouseArea { + anchors.fill: parent + onClicked: root.toggleDone() + cursorShape: Qt.PointingHandCursor + } + } + + // Delete button + Button { + id: deleteButton + Layout.preferredWidth: root.deleteButtonSize + Layout.preferredHeight: root.deleteButtonSize + opacity: itemBackground.hovered ? 1.0 : 0.3 + + background: Rectangle { + color: deleteButton.pressed ? "#ff3b30" : "transparent" + radius: 16 + } + + contentItem: Text { + text: "🗑" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: { + console.log("Delete task clicked") + } + } + } + + // Hover effect + property bool hovered: false + + HoverHandler { + onHoveredChanged: itemBackground.hovered = hovered + } + } + } +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/main.cpp b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/main.cpp new file mode 100644 index 0000000..2919679 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/views/MainView.qml b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/views/MainView.qml new file mode 100644 index 0000000..7fcb863 --- /dev/null +++ b/Qt6QMLBeginnersCode/10-TodoListApp/04_task_item/src/views/MainView.qml @@ -0,0 +1,98 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + //Placeholder for header (we'll add this next) + /* + Rectangle{ + Layout.fillWidth: true + Layout.preferredHeight: 80 + color: "transparent" + border.color: root.textColor + border.width: 1 + + Text{ + anchors.centerIn: parent + text: "Header will go here" + color: root.textColor + } + } + */ + //The actual AppHeader component to replace the place holder + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + // Add task bar + AddTaskBar { + id: addTaskBar + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + } + + // Test TaskItem + TaskItem { + id: testTaskItem + Layout.fillWidth: true + taskTitle: "Sample Task Item" + taskDone: false + backgroundColor: root.cardColor + textColor: root.textColor + completedColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onToggleDone: { + testTaskItem.taskDone = !testTaskItem.taskDone + } + + onDeleteTask: { + console.log("Delete task clicked") + } + } + + + //Add a spacer to push things up. Will remove later + Item { + Layout.fillHeight: true + } + + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/CMakeLists.txt new file mode 100644 index 0000000..7dec286 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(10-PathView VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app10-PathView + main.cpp +) + +qt_add_qml_module(app10-PathView + URI 10-PathView + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app10-PathView PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app10-PathView + PRIVATE Qt6::Quick +) + +install(TARGETS app10-PathView + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/Main.qml new file mode 100644 index 0000000..a1e938c --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/Main.qml @@ -0,0 +1,203 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + id: rootId + width: 340 + height: 480 + visible: true + title: qsTr("PathView") + + Rectangle { + width: parent.width + height: parent.height + color: "#EBEBEB" + + + ListModel { + id: modelId + ListElement { our_color: "red" } + ListElement { our_color: "green" } + ListElement { our_color: "blue" } + ListElement { our_color: "yellow" } + ListElement { our_color: "black" } + ListElement { our_color: "dodgerblue" } + ListElement { our_color: "purple" } + ListElement { our_color: "magenta" } + ListElement { our_color: "yellowgreen" } + ListElement { our_color: "skyblue" } + } + + + Component { + id: delegateId + Column { + //opacity: PathView.opacity + scale: PathView.scale + opacity: PathView.isCurrentItem ? 1 : 0.3 + readonly property bool is_current: PathView.isCurrentItem + + + /* + Rectangle{ + width: 5 + height: 5 + color: "black" + radius: 5 + } + */ + + + Rectangle { + anchors.horizontalCenter: textId.horizontalCenter + width: 64 + height: 64 + radius: 20 + color: model.our_color + MouseArea{ + anchors.fill: parent + onClicked: { + if(is_current){ + console.log("Clicked on "+ model.our_color) + }else{ + console.log("Not current item") + } + } + } + + } + + Text { + id: textId + text: model.our_color; font.pixelSize: 24 + } + } + } + + PathView { + anchors.fill: parent + model: modelId + //model: 100 + delegate: delegateId + focus: true + + path: Path { + + //Bottom : Starting Point + startX: rootId.width/2 + startY: rootId.height - 50 + + PathAttribute{ + name: "scale" + value: 1 + } + /* + PathAttribute{ + name: "opacity" + value: 1 + } + */ + + // Towards Left + PathCubic { + x: 50 + y: rootId.height/2 + + control1X: rootId.width/2 - rootId.width/8 + control1Y: rootId.height + control2X: 0 + control2Y: rootId.height/2 + rootId.height/8 + + } + + PathAttribute{ + name: "scale" + value: 0.5 + } + /* + PathAttribute{ + name: "opacity" + value: 0.5 + } + */ + + + //Towards Top: Q2 + PathCubic { + x: rootId.width/2 + y: 50 + control1X: 0 + control1Y: (rootId.height/2 - rootId.height/8) + control2X : (rootId.width/2 - rootId.width/8) + control2Y: 0 + } + + + PathAttribute{ + name: "scale" + value: 0.3 + } + + /* + PathAttribute{ + name: "opacity" + value: 0.5 + } + */ + + //Towards Right: Q3 + PathCubic { + x: rootId.width - 50 + y: rootId.height/2 + control1X: rootId.width/2 + rootId.width/8 + control1Y: 0 + control2X: rootId.width + control2Y: rootId.height/2 - rootId.height/8 + } + + + PathAttribute{ + name: "scale" + value: 0.5 + } + + /* + PathAttribute{ + name: "opacity" + value: 0.5 + } + */ + + + //Towards bottom: Q4 + PathCubic { + x: rootId.width/2 + y: rootId.height - 50 + control1X: rootId.width + control1Y: rootId.height/2 + rootId.height/8 + control2X: rootId.width/2 + rootId.width/8 + control2Y: rootId.height + } + + + PathAttribute{ + name: "scale";value: 1 + } + + /* + PathAttribute{ + name: "opacity";value: 0.5 + } + */ + + } + + Keys.onLeftPressed: decrementCurrentIndex() + Keys.onRightPressed: incrementCurrentIndex() + } + + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/main.cpp new file mode 100644 index 0000000..a81f338 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/10-PathView/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("10-PathView", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/CMakeLists.txt new file mode 100644 index 0000000..6a354f9 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(11-TableView VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app11-TableView + main.cpp +) + +qt_add_qml_module(app11-TableView + URI 11-TableView + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app11-TableView PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app11-TableView + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app11-TableView + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/Main.qml new file mode 100644 index 0000000..f08c143 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/Main.qml @@ -0,0 +1,128 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import Qt.labs.qmlmodels + +ApplicationWindow { + width: 680 + height: 400 + visible: true + + HorizontalHeaderView { + id: horizontalHeader + anchors.left: tableViewId.left + anchors.top: parent.top + syncView: tableViewId + + } + + VerticalHeaderView { + id: verticalHeader + anchors.top: tableViewId.top + anchors.left: parent.left + syncView: tableViewId + } + + + TableModel { + id: tableModelId + TableModelColumn { display: "checked" } + TableModelColumn { display: "amount" } + TableModelColumn { display: "fruitType" } + TableModelColumn { display: "fruitName" } + TableModelColumn { display: "fruitPrice" } + + // Each row is one type of fruit that can be ordered + rows: [ + { + // Each property is one cell/column. + checked: false, + amount: 1, + fruitType: "Apple", + fruitName: "Granny Smith", + fruitPrice: 1.50 + }, + { + checked: true, + amount: 4, + fruitType: "Orange", + fruitName: "Navel", + fruitPrice: 2.50 + }, + { + checked: false, + amount: 1, + fruitType: "Banana", + fruitName: "Cavendish", + fruitPrice: 3.50 + } + ] + } + + TableView { + id: tableViewId + anchors.left: verticalHeader.right + anchors.top: horizontalHeader.bottom + anchors.right: parent.right + anchors.bottom: parent.bottom + + columnSpacing: 1 + rowSpacing: 1 + + model: tableModelId + + /* + delegate: TextInput { + text: model.display + padding: 12 + selectByMouse: true + + onAccepted: model.display = text + + Rectangle { + anchors.fill: parent + color: "#efefef" + z: -1 + } + } + */ + + + delegate: DelegateChooser { + DelegateChoice { + column: 0 + delegate: CheckBox { + checked: model.display + onToggled: model.display = checked + } + } + DelegateChoice { + column: 1 + delegate: SpinBox { + value: model.display + onValueModified: model.display = value + } + } + DelegateChoice { + delegate: TextField { + text: model.display + selectByMouse: true + implicitWidth: 140 + onAccepted: model.display = text + } + } + } + } + + + Button{ + text: "See the data" + anchors.bottom: parent.bottom + onClicked: { + console.log(tableModelId.data(tableModelId.index(0,0),"display")) + } + } + +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/main.cpp new file mode 100644 index 0000000..af77218 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/11-TableView/main.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("11-TableView", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/CMakeLists.txt new file mode 100644 index 0000000..0e17caf --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(12-TableViewCppModel VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app12-TableViewCppModel + main.cpp tablemodel.h tablemodel.cpp +) + +qt_add_qml_module(app12-TableViewCppModel + URI 12-TableViewCppModel + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app12-TableViewCppModel PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app12-TableViewCppModel + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app12-TableViewCppModel + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/Main.qml new file mode 100644 index 0000000..3dd4177 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/Main.qml @@ -0,0 +1,68 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import TableModel // Import the custom model from C++ + +ApplicationWindow { + width: 680 + height: 400 + visible: true + + HorizontalHeaderView { + id: horizontalHeader + anchors.left: tableViewId.left + anchors.top: parent.top + syncView: tableViewId + clip: true + + } + + VerticalHeaderView { + id: verticalHeader + anchors.top: tableViewId.top + anchors.left: parent.left + syncView: tableViewId + clip: true + + } + + TableModel{ + id: tableModelId + } + + TableView { + id: tableViewId + anchors.left: verticalHeader.right + anchors.top: horizontalHeader.bottom + anchors.right: parent.right + anchors.bottom: parent.bottom + + columnSpacing: 1 + rowSpacing: 1 + boundsBehavior: Flickable.StopAtBounds + + model: tableModelId + + delegate: Label { + text: model.tabledata + width: 100 + padding: 12 + + Rectangle { + anchors.fill: parent + color: "#efefef" + z: -1 + } + } + } + + Button{ + text: "See the data" + anchors.bottom: parent.bottom + onClicked: { + console.log(tableModelId.get_display_data(tableModelId.index(0,1))) + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/main.cpp new file mode 100644 index 0000000..91cccf1 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/main.cpp @@ -0,0 +1,24 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include "tablemodel.h" + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType("TableModel", 0, 1, "TableModel"); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("12-TableViewCppModel", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/tablemodel.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/tablemodel.cpp new file mode 100644 index 0000000..cfa8e8b --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/tablemodel.cpp @@ -0,0 +1,92 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include "tablemodel.h" + +TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) +{ + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + table.append({"John","Doe","32","Farmer","Single","Gounduana","Mestkv"}); + table.append({"Mary","Jane","27","Teacher","Married","Verkso","Tukk"}); + +} + +int TableModel::rowCount(const QModelIndex &) const +{ + return table.size();//Number of rows +} + +int TableModel::columnCount(const QModelIndex &) const +{ + return table.at(0).size();//Columns +} + +QVariant TableModel::data(const QModelIndex &index, int role) const +{ + switch (role) { + case TableDataRole: + { + return table.at(index.row()).at(index.column()); + } + default: + break; + } + + return QVariant(); +} + +QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) { + return QVariant(); + } + if (orientation == Qt::Horizontal && section == 0) { + return "Name"; + } else if (orientation == Qt::Horizontal && section == 1) { + return "Name"; + } else if (orientation == Qt::Horizontal && section == 2) { + return "Age"; + } else if (orientation == Qt::Horizontal && section == 3) { + return "Job"; + } else if (orientation == Qt::Horizontal && section == 4) { + return "Status"; + } else if (orientation == Qt::Horizontal && section == 5) { + return "Country"; + } else if (orientation == Qt::Horizontal && section == 6) { + return "City"; + } + + if(orientation == Qt::Vertical){ + return QVariant::fromValue(section + 1) ; + } + return QVariant(); +} + +QHash TableModel::roleNames() const +{ + QHash roles; + roles[TableDataRole] = "tabledata"; + return roles; +} + +QVariant TableModel::get_display_data(const QModelIndex &index){ + return data(index,TableDataRole ); +} + + diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/tablemodel.h b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/tablemodel.h new file mode 100644 index 0000000..10937e4 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/12-TableViewCppModel/tablemodel.h @@ -0,0 +1,31 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#ifndef TABLEMODEL_H +#define TABLEMODEL_H + +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + enum TableRoles{ + TableDataRole = Qt::UserRole + 1, + }; +public: + explicit TableModel(QObject *parent = nullptr); + int rowCount(const QModelIndex & = QModelIndex()) const override; + int columnCount(const QModelIndex & = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + QHash roleNames() const override; + + Q_INVOKABLE + QVariant get_display_data(const QModelIndex& index); + +private: + QVector> table; +}; + +#endif // TABLEMODEL_H diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/.qmlls.ini b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/.qmlls.ini new file mode 100644 index 0000000..f5b09ae --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/.qmlls.ini @@ -0,0 +1,5 @@ +[General] +buildDir="D:/Sandbox/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/build" +no-cmake-calls=false +docDir=C:/Qt/Docs/Qt-6.9.0 +importPaths="C:/Qt/6.9.0/mingw_64/qml" diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/CMakeLists.txt new file mode 100644 index 0000000..bd05f5c --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml + src/components/AddTaskBar.qml + src/components/TaskItem.qml + src/components/TaskStats.qml + + # Models + src/models/TaskListModel.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/AddTaskBar.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/AddTaskBar.qml new file mode 100644 index 0000000..72719d0 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/AddTaskBar.qml @@ -0,0 +1,110 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 60 + + signal taskAdded(string taskText) + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color primaryColor: "#007aff" + property bool darkMode: false + + Rectangle { + id: background + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // Add icon + Rectangle { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + color: root.primaryColor + radius: 18 + + Text { + anchors.centerIn: parent + text: "+" + color: "#ffffff" + font.pixelSize: 20 + font.weight: Font.Bold + } + } + + // Text input + TextField { + id: taskInput + Layout.fillWidth: true + Layout.preferredHeight: 36 + placeholderText: qsTr("Add a new task...") + placeholderTextColor: root.darkMode ? "#888888" : "#999999" + color: root.textColor + font.pixelSize: 16 + selectByMouse: true + + background: Rectangle { + color: "transparent" + border.color: "transparent" + } + + Keys.onReturnPressed: root.addTask() + Keys.onEnterPressed: root.addTask() + + } + + // Add button + Button { + id: addButton + Layout.preferredWidth: 80 + Layout.preferredHeight: 36 + text: qsTr("Add") + enabled: taskInput.text.trim().length > 0 + + background: Rectangle { + color: addButton.enabled ? + (addButton.pressed ? Qt.darker(root.primaryColor, 1.2) : root.primaryColor) : + (root.darkMode ? "#404040" : "#e0e0e0") + radius: 8 + + } + + contentItem: Text { + text: addButton.text + color: addButton.enabled ? "#ffffff" : (root.darkMode ? "#888888" : "#cccccc") + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + } + + onClicked: root.addTask() + } + } + } + } + + function addTask() { + if (taskInput.text.trim().length > 0) { + root.taskAdded(taskInput.text.trim()) + taskInput.text = "" + taskInput.focus = false + } + } + +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/AppHeader.qml new file mode 100644 index 0000000..97f5e13 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/AppHeader.qml @@ -0,0 +1,86 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + //Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/TaskItem.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/TaskItem.qml new file mode 100644 index 0000000..23db305 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/TaskItem.qml @@ -0,0 +1,129 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 56 + + required property string taskTitle + required property bool taskDone + + signal toggleDone() + signal deleteTask() + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color completedColor: "#999999" + property color primaryColor: "#007aff" + property bool darkMode: false + + // Constants for this component + readonly property int itemHeight: 56 + readonly property int margins: 4 + readonly property int innerMargins: 12 + readonly property int checkboxSize: 24 + readonly property int deleteButtonSize: 32 + + Rectangle { + id: taskItemBackground + anchors.fill: parent + color: "transparent" + + Rectangle { + id: itemBackground + anchors.fill: parent + anchors.margins: root.margins + color: root.backgroundColor + radius: 8 + border.color: root.taskDone ? "transparent" : (root.darkMode ? "#404040" : "#f0f0f0") + border.width: 1 + opacity: root.taskDone ? 0.7 : 1.0 + + RowLayout { + anchors.fill: parent + anchors.margins: root.innerMargins + spacing: 12 + + // Checkbox + Rectangle { + id: checkbox + Layout.preferredWidth: root.checkboxSize + Layout.preferredHeight: root.checkboxSize + color: root.taskDone ? root.primaryColor : "transparent" + border.color: root.taskDone ? root.primaryColor : (root.darkMode ? "#666666" : "#cccccc") + border.width: 2 + radius: 4 + + // Checkmark + Text { + anchors.centerIn: parent + text: "✓" + color: "#ffffff" + font.pixelSize: 16 + font.weight: Font.Bold + opacity: root.taskDone ? 1.0 : 0.0 + + } + + MouseArea { + anchors.fill: parent + onClicked: { + root.toggleDone() + } + cursorShape: Qt.PointingHandCursor + } + + } + + // Task text + Text { + id: taskText + Layout.fillWidth: true + text: root.taskTitle + color: root.taskDone ? root.completedColor : root.textColor + font.pixelSize: 16 + font.strikeout: root.taskDone + wrapMode: Text.WordWrap + + MouseArea { + anchors.fill: parent + onClicked: root.toggleDone() + cursorShape: Qt.PointingHandCursor + } + } + + // Delete button + Button { + id: deleteButton + Layout.preferredWidth: root.deleteButtonSize + Layout.preferredHeight: root.deleteButtonSize + opacity: itemBackground.hovered ? 1.0 : 0.3 + + background: Rectangle { + color: deleteButton.pressed ? "#ff3b30" : "transparent" + radius: 16 + } + + contentItem: Text { + text: "🗑" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: { + root.deleteTask() + } + } + } + + // Hover effect + property bool hovered: false + + HoverHandler { + onHoveredChanged: itemBackground.hovered = hovered + } + } +} +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/TaskStats.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/TaskStats.qml new file mode 100644 index 0000000..6d3cde5 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/components/TaskStats.qml @@ -0,0 +1,95 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: visible ? 60 : 0 + visible: totalTasks > 0 + + property int totalTasks: 0 + property int completedTasks: 0 + property int remainingTasks: 0 + property bool hasCompleted: false + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color secondaryTextColor: "#666666" + property color primaryColor: "#007aff" + property color dangerColor: "#ff3b30" + property bool darkMode: false + + signal clearCompleted() + + Rectangle { + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 16 + + // Statistics text + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: root.totalTasks === 1 ? + qsTr("%1 task").arg(root.totalTasks) : + qsTr("%1 tasks").arg(root.totalTasks) + color: root.textColor + font.pixelSize: 16 + font.weight: Font.Medium + } + + Text { + text: root.completedTasks > 0 ? + qsTr("%1 completed, %2 remaining").arg(root.completedTasks).arg(root.remainingTasks) : + qsTr("No tasks completed yet") + color: root.secondaryTextColor + font.pixelSize: 14 + visible: root.totalTasks > 0 + } + } + + // Clear completed button + Button { + id: clearButton + Layout.preferredHeight: 36 + text: qsTr("Clear Completed") + visible: root.hasCompleted + enabled: root.hasCompleted + + background: Rectangle { + color: clearButton.pressed ? + Qt.darker(root.dangerColor, 1.2) : + (clearButton.hovered ? root.dangerColor : "transparent") + border.color: root.dangerColor + border.width: 1 + radius: 8 + } + + contentItem: Text { + text: clearButton.text + color: clearButton.hovered ? "#ffffff" : root.dangerColor + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: root.clearCompleted() + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/main.cpp new file mode 100644 index 0000000..2919679 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/models/TaskListModel.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/models/TaskListModel.qml new file mode 100644 index 0000000..3a2f9d2 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/models/TaskListModel.qml @@ -0,0 +1,89 @@ +import QtQuick + +ListModel { + id: root + + // Add some sample tasks for testing + Component.onCompleted: { + addTask("Learn Qt QML") + addTask("Build a todo app") + addTask("Practice QML components") + } + + // Add a new task + function addTask(title) { + if (title && title.trim().length > 0) { + append({ + "title": title.trim(), + "completed": false, + "id": generateId() + }) + } + } + + // Toggle task completion status + function toggleTask(index) { + if (index >= 0 && index < count) { + setProperty(index, "completed", !get(index).completed) + } + } + + // Delete a task + function deleteTask(index) { + if (index >= 0 && index < count) { + remove(index) + } + } + + // Delete task by ID + function deleteTaskById(taskId) { + for (let i = 0; i < count; i++) { + if (get(i).id === taskId) { + remove(i) + break + } + } + } + + // Clear all completed tasks + function clearCompletedTasks() { + for (let i = count - 1; i >= 0; i--) { + if (get(i).completed) { + remove(i) + } + } + } + + // Get statistics + function getStats() { + let total = count + let completed = 0 + + for (let i = 0; i < count; i++) { + if (get(i).completed) { + completed++ + } + } + + return { + "total": total, + "completed": completed, + "remaining": total - completed + } + } + + // Check if there are any completed tasks + function hasCompletedTasks() { + for (let i = 0; i < count; i++) { + if (get(i).completed) { + return true + } + } + return false + } + + // Generate a unique ID for tasks + function generateId() { + return Date.now() + Math.random().toString(36).substr(2, 9) + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/views/MainView.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/views/MainView.qml new file mode 100644 index 0000000..179ac5f --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/14-TodoListModelView/src/views/MainView.qml @@ -0,0 +1,165 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + // Task model - Using the dedicated TaskListModel + TaskListModel { + id: taskModel + } + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + // Header + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + // Add task bar + AddTaskBar { + id: addTaskBar + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onTaskAdded: function(taskText) { + taskModel.addTask(taskText) + } + } + + // Tasks list + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: root.cardColor + radius: 12 + border.width: 1 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + + ScrollView { + anchors.fill: parent + anchors.margins: 1 + clip: true + + ListView { + id: taskListView + model: taskModel + spacing: 8 + anchors.margins: 12 + + delegate: TaskItem { + required property int index + required property string title + required property bool completed + + width: taskListView.width + taskTitle: title + taskDone: completed + backgroundColor: root.cardColor + textColor: root.textColor + completedColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onToggleDone: { + taskModel.toggleTask(index) + } + + onDeleteTask: { + taskModel.deleteTask(index) + } + } + + // Empty state + Rectangle { + anchors.centerIn: parent + width: parent.width - 40 + height: 120 + color: "transparent" + visible: taskListView.count === 0 + + Column { + anchors.centerIn: parent + spacing: 16 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: "📝" + font.pixelSize: 48 + opacity: 0.3 + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("No tasks yet") + color: root.completedColor + font.pixelSize: 18 + font.weight: Font.Medium + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Add a task above to get started") + color: root.completedColor + font.pixelSize: 14 + horizontalAlignment: Text.AlignHCenter + } + } + } + } + } + + + } + + // Task statistics at bottom + TaskStats { + id: taskStats + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + secondaryTextColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + totalTasks: taskModel.count + completedTasks: taskModel.getStats().completed + remainingTasks: taskModel.getStats().remaining + hasCompleted: taskModel.hasCompletedTasks() + + onClearCompleted: { + taskModel.clearCompletedTasks() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/CMakeLists.txt new file mode 100644 index 0000000..b20b107 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-ListViewListModel VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-ListViewListModel + main.cpp +) + +qt_add_qml_module(app2-ListViewListModel + URI ListViewListModel + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-ListViewListModel PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-ListViewListModel + PRIVATE Qt6::Quick +) + +install(TARGETS app2-ListViewListModel + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/Main.qml new file mode 100644 index 0000000..7c590dd --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/Main.qml @@ -0,0 +1,103 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("ListView and ListModel Demo") + + ListView { + id: mListViewId + anchors.fill: parent + model: mModelId + //delegate: delegateId + + + delegate: Rectangle { + id: rectangleId + width: parent.width + height: 50 + color: "beige" + border.color: "yellowgreen" + radius: 10 + + Text { + id: textId + anchors.centerIn: parent + font.pointSize: 20 + text: country + " : " + capital + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: "+ capital + ", "+ country) + } + } + } + + } + + + ListModel { + id: mModelId + ListElement { + country: "Rwanda" + capital: "Kigali" + } + ListElement { + country: "Germany"; capital: "Berlin" + } + ListElement { + country: "Japan"; capital: "Tokyo" + } + + ListElement { + country :"Nigeria"; capital: "Lagos" + } + ListElement { + country: "Ghana"; capital: "Accra" + } + ListElement { + country: "Kenya"; capital: "Nairobi" + } + ListElement { + country: "India"; capital: "New Delhi" + } + ListElement { + country: "Uganda"; capital: "Kampala" + } + + } + + Component { + id: delegateId + Rectangle { + id: rectangleId + width: parent.width + height: 50 + color: "dodgerblue" + border.color: "black" + radius: 15 + + Text { + id: textId + anchors.centerIn: parent + font.pointSize: 20 + text: country + ": " + capital + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: "+ capital + ", "+ country) + } + } + } + } + +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/main.cpp new file mode 100644 index 0000000..3248aa5 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/2-ListViewListModel/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("ListViewListModel", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/CMakeLists.txt new file mode 100644 index 0000000..eca2ac9 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-InlineModels VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-InlineModels + main.cpp +) + +qt_add_qml_module(app3-InlineModels + URI 3-InlineModels + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-InlineModels PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-InlineModels + PRIVATE Qt6::Quick +) + +install(TARGETS app3-InlineModels + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/Main.qml new file mode 100644 index 0000000..93153ae --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/Main.qml @@ -0,0 +1,43 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + id: rootId + visible: true + width: 640 + height: 480 + title: qsTr("Inline Model") + + + ListView { + id: mListViewId + anchors.fill: parent + //model : ["January", "February", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"] + model: 100 + delegate: Rectangle { + id: rectangleId + width: rootId.width + height: 50 + color: "beige" + border.color: "yellowgreen" + radius: 10 + + Text { + id: textId + anchors.centerIn: parent + font.pointSize: 20 + text: modelData + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: "+ modelData) + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/main.cpp new file mode 100644 index 0000000..c679732 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/3-InlineModels/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-InlineModels", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/CMakeLists.txt new file mode 100644 index 0000000..9dc5f15 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-HeaderFooterHighlight VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-HeaderFooterHighlight + main.cpp +) + +qt_add_qml_module(app4-HeaderFooterHighlight + URI 4-HeaderFooterHighlight + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-HeaderFooterHighlight PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-HeaderFooterHighlight + PRIVATE Qt6::Quick +) + +install(TARGETS app4-HeaderFooterHighlight + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/Main.qml new file mode 100644 index 0000000..1a7c5ba --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/Main.qml @@ -0,0 +1,75 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + id: rootId + visible: true + width: 640 + height: 480 + title: qsTr("Header Footer and Highlight") + + ListView { + id: mListViewId + anchors.fill: parent + header: headerId + footer: Rectangle{ + width: rootId.width + height: 50 + color: "dodgerblue" + } + highlight: Rectangle{ + width: rootId.width + color: "blue" + radius: 14 + border.color: "yellowgreen" + z: 3 + opacity: 0.1 + } + + model: ["January", "February", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"] + delegate: Rectangle { + id: delegateId + width: rootId.width + height: 50 + color: "beige" + border.color: "yellowgreen" + radius: 10 + + Text { + id: textId + anchors.centerIn: parent + font.pointSize: 20 + text : modelData + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: "+ modelData) + mListViewId.currentIndex = index + } + } + } + } + + Component { + id: headerId + Rectangle { + id: headerRectId + width: rootId.width + height: 50 + color: "yellowgreen" + border {color: "#9EDDF2"; width: 2} + + Text { + anchors.centerIn: parent + text: "Months" + font.pointSize: 20 + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/main.cpp new file mode 100644 index 0000000..e8041c6 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/4-HeaderFooterHighlight/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-HeaderFooterHighlight", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/CMakeLists.txt new file mode 100644 index 0000000..80404f4 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-DecorationSection VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-DecorationSection + main.cpp +) + +qt_add_qml_module(app5-DecorationSection + URI 5-DecorationSection + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-DecorationSection PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-DecorationSection + PRIVATE Qt6::Quick +) + +install(TARGETS app5-DecorationSection + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/Main.qml new file mode 100644 index 0000000..7f62db8 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/Main.qml @@ -0,0 +1,106 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Section (Decoration)") + + + ListModel { + id: mListModel + + ListElement { + names: "Seth Moris"; company: "GOOGLE" + } + ListElement { + names: "Miriam Katv"; company: "GOOGLE" + } + + ListElement { + names: "Eugene Fitzgerald"; company: "GOOGLE" + } + ListElement { + names: "Kantkl Vikney"; company : "GOOGLE" + } + ListElement { + names: "Mary Beige"; company: "TESLA" + } + ListElement { + names: "Bamba Pikt"; company: "TESLA" + } + ListElement { + names: "Jeffery Mor"; company: "SIEMENS" + } + ListElement { + names: "Pick Mo"; company: "SIEMENS" + } + + } + + + ListView { + id: mListViewId + anchors.fill: parent + model : mListModel + delegate: delegateId + section { + property: "company" + criteria: ViewSection.FullString + delegate: Rectangle{ + id: sectionRectId + width : parent.width + height: 50 + color: "red" + border.color: "yellowgreen" + radius: 14 + + Text { + id: sectionTextId + text : section + anchors.centerIn: parent + font.pointSize: 20 + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: " + section) + } + } + } + } + } + + + Component { + id: delegateId + Rectangle { + id: rectangleId + width : parent.width // Remember to specify these sizes or you'll have problems + height: 50 + color: "beige" + border.color: "yellowgreen" + radius: 14 + + Text { + id: textId + anchors.centerIn: parent + text: names + font.pointSize: 20 + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: " + names) + } + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/main.cpp new file mode 100644 index 0000000..f4b3aab --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/5-DecorationSection/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-DecorationSection", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/CMakeLists.txt new file mode 100644 index 0000000..0f94e78 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-Repeater VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-Repeater + main.cpp +) + +qt_add_qml_module(app6-Repeater + URI 6-Repeater + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app6-Repeater PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-Repeater + PRIVATE Qt6::Quick +) + +install(TARGETS app6-Repeater + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/Main.qml new file mode 100644 index 0000000..02f1eb8 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/Main.qml @@ -0,0 +1,51 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Repeater") + + Flickable { + contentHeight: columnId.implicitHeight + anchors.fill : parent + + + Column { + id: columnId + anchors.fill: parent + spacing: 2 + + Repeater { + id: repeaterId + + //model: 15 + model: ["Jan", "Feb", "March"] + delegate: Rectangle { + width: parent.width + height: 50 + color: "dodgerblue" + + Text { + anchors.centerIn: parent + text: modelData + font.pointSize: 20 + } + + MouseArea{ + anchors.fill: parent + onClicked: { + console.log("Clicked on: "+modelData) + console.log("count: " + repeaterId.count) + } + } + } + + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/main.cpp new file mode 100644 index 0000000..e5c4a68 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/6-Repeater/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-Repeater", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/CMakeLists.txt new file mode 100644 index 0000000..d82b106 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(7-DynamicModels VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app7-DynamicModels + main.cpp +) + +qt_add_qml_module(app7-DynamicModels + URI 7-DynamicModels + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app7-DynamicModels PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-DynamicModels + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app7-DynamicModels + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/Main.qml new file mode 100644 index 0000000..5765eb0 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/Main.qml @@ -0,0 +1,116 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Layouts + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Dynamic Models Demo") + + ListModel { + id: mListModel + + ListElement { + firstName: "John"; lastName: "Snow" + } + ListElement { + firstName: "Nicholai"; lastName: "Itchenko" + } + ListElement { + firstName: "Mitch"; lastName: "Mathson" + } + ListElement { + firstName: "Ken"; lastName: "Kologorov" + } + ListElement { + firstName: "Vince"; lastName: "Luvkyj" + } + + + } + + ColumnLayout { + anchors.fill: parent + ListView{ + id: mListViewId + model: mListModel + delegate: delegateId + Layout.fillWidth : true + Layout.fillHeight: true + + } + + + + Button { + text: "Add Item" + Layout.fillWidth : true + onClicked: { + mListModel.append({"firstName": "Daniel", "lastName": "Gakwaya"}) + } + } + + + Button { + text: "Clear" + Layout.fillWidth : true + onClicked: { + mListModel.clear() + + } + } + + Button { + text: "Delete Item at index 2" + Layout.fillWidth: true + onClicked: { + if ( 2 < mListViewId.model.count){ + mListModel.remove(2,1) + }else{ + console.log("index is invalid") + } + } + } + + Button { + text: "Set item at index 1" + Layout.fillWidth: true + onClicked: { + mListModel.set(1,{"firstName": "John", "lastName": "Doe"}) + + } + } + + } + + Component { + id: delegateId + Rectangle { + id: rectangleId + width: mListViewId.width + height: 50 + color: "beige" + border.color: "yellowgreen" + radius: 14 + + Text { + id: textId + anchors.centerIn: parent + text : firstName + " " + lastName + font.pointSize: 20 + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: " + firstName + " " + lastName) + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/main.cpp new file mode 100644 index 0000000..b816289 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/7-DynamicModels/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("7-DynamicModels", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/CMakeLists.txt new file mode 100644 index 0000000..e79754e --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(8-GridView VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app8-GridView + main.cpp +) + +qt_add_qml_module(app8-GridView + URI 8-GridView + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app8-GridView PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app8-GridView + PRIVATE Qt6::Quick +) + +install(TARGETS app8-GridView + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/Main.qml new file mode 100644 index 0000000..d0651ce --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/Main.qml @@ -0,0 +1,73 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("GridView") + + + ListModel { + id: modelId + + ListElement { + mNumber: 1 + mColor: "red" + } + ListElement { + mNumber: 2 + mColor: "green" + } + ListElement { + mNumber: 3 + mColor: "beige" + } + ListElement { + mNumber: 4 + mColor: "yellowgreen" + } + ListElement { + mNumber: 5 + mColor: "dodgerblue" + } + ListElement { + mNumber: 6 + mColor: "lightyellow" + } + ListElement { + mNumber: 7 + mColor: "pink" + } + ListElement { + mNumber: 8 + mColor: "magenta" + } + ListElement { + mNumber: 9 + mColor: "silver" + } + } + + GridView{ + id: mGridViewId + anchors.fill: parent + flow : GridView.FlowTopToBottom + layoutDirection: Qt.RightToLeft + model: modelId + delegate: Rectangle { + width: 100 + height: width + color: mColor + Text { + text: mNumber + anchors.centerIn: parent + font.pointSize: 20 + + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/main.cpp new file mode 100644 index 0000000..37fc0ea --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/8-GridView/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("8-GridView", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/CMakeLists.txt b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/CMakeLists.txt new file mode 100644 index 0000000..878b383 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(9-XmlListModel VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app9-XmlListModel + main.cpp resource.qrc +) + +qt_add_qml_module(app9-XmlListModel + URI 9-XmlListModel + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app9-XmlListModel PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app9-XmlListModel + PRIVATE Qt6::Quick +) + +install(TARGETS app9-XmlListModel + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/Main.qml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/Main.qml new file mode 100644 index 0000000..ecb7424 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/Main.qml @@ -0,0 +1,67 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtQml.XmlListModel + + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("XmlListModel") + + + XmlListModel { + id: mXmlListModelId + source: "qrc:/xml/employees.xml" + query: "/courses/course" + + XmlListModelRole { + name: "instructor" + elementName: "instructor" + } + XmlListModelRole { + name: "year" + elementName: "year" + } + XmlListModelRole { + name: "coursename" + elementName: "coursename" + } + XmlListModelRole { name: "hot" + elementName: "coursename" + attributeName: "hot" + } + } + + ListView{ + id: mListViewId + anchors.fill: parent + model : mXmlListModelId + delegate: Rectangle { + width : parent.width + height: 50 + color: "beige" + Row { + spacing: 30 + Text { + text: instructor + font.pointSize: 15 + } + Text { + text: coursename + " (" + year + ")" + font.bold: hot === "true" ? true : false + font.pointSize: 15 + } + } + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on: "+ hot) + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/main.cpp b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/main.cpp new file mode 100644 index 0000000..528ddaa --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("9-XmlListModel", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/resource.qrc b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/resource.qrc new file mode 100644 index 0000000..3c3053b --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/resource.qrc @@ -0,0 +1,5 @@ + + + xml/employees.xml + + diff --git a/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/xml/employees.xml b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/xml/employees.xml new file mode 100644 index 0000000..ead30f5 --- /dev/null +++ b/Qt6QMLBeginnersCode/11-ModelViewArchitecture/9-XmlListModel/xml/employees.xml @@ -0,0 +1,30 @@ + + + + + + Matt Kabwe + 2002 + Operating Systems + + + Daniel Gwo + 2010 + Object Oriented Programming (Java) + + + Nathan Mepp + 2011 + Embedded Systems + + + Lilian Gwiza + 2015 + IT Project Management + + + John Wiks + 2023 + C is Still King + + diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/CMakeLists.txt new file mode 100644 index 0000000..04e82c1 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.16) + +project(10-EasingCurves VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app10-EasingCurves + main.cpp +) + +qt_add_qml_module(app10-EasingCurves + URI 10-EasingCurves + VERSION 1.0 + QML_FILES Main.qml + QML_FILES MovingRectangle.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app10-EasingCurves PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app10-EasingCurves + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app10-EasingCurves + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app10-EasingCurves + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/Main.qml new file mode 100644 index 0000000..6b1374d --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/Main.qml @@ -0,0 +1,298 @@ +import QtQuick +import QtQuick.Layouts + +Window { + id: rootId + width: 640 + height: 480 + visible: true + title: qsTr("Easing Curves") + + property int animDuration: 500 + property color startColor : "beige" + property color endColor: "blue" + + + Flickable{ + anchors.fill: parent + contentHeight: columnId.implicitHeight + ColumnLayout{ + id: columnId + width: parent.width + spacing: 2 + + //The container rectangle + /* + Rectangle{ + id: containerRectId + width: parent.width + height: 50 + color: "gray" + + Text{ + text: "Easing.Linear" + anchors.centerIn: parent + } + + Rectangle{ + id: containedRectId + color: startColor + width: 50 + height: 50 + border{ + width: 5 + color: "black" + } + radius: 10 + + MouseArea{ + anchors.fill: parent + property bool toRight: false + + onClicked: function(){ + if( toRight === false){ + //Move towards the right + toRight = true + //Animate x + numberAnimationId.to = containerRectId.width - containedRectId.width + numberAnimationId.start() + + //Animate the color + colorAnimationId.from = startColor + colorAnimationId.to = endColor + colorAnimationId.start() + }else{ + //Move towards the left + toRight = false + //Animate x + numberAnimationId.to = 0 + numberAnimationId.start() + + //Animate the color + colorAnimationId.from = endColor + colorAnimationId.to = startColor + colorAnimationId.start() + } + } + + } + + + NumberAnimation { + id: numberAnimationId + target: containedRectId + property: "x" + easing.type: Easing.Linear + to: containerRectId.width - containedRectId.width + duration: animDuration + } + + ColorAnimation{ + id: colorAnimationId + target: containedRectId + property: "color" + from: startColor + to: endoColor + duration: animDuration + } + } + } + */ + + MovingRectangle { + backgroundColor: "gray" + startColor: "beige" + endColor: "blue" + animDuration: rootId.animDuration + easingText: "Linear" + easingType: Easing.Linear + containerwidth: rootId.width + } + + MovingRectangle { + backgroundColor: "gray" + startColor: "beige" + endColor: "green" + animDuration: rootId.animDuration + easingText: "InQuad" + easingType: Easing.InQuad + containerwidth: rootId.width + } + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "salmon"; + animDuration:rootId.animDuration ; easingText: "OutQuad"; easingType: Easing.OutQuad; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "tomato"; + animDuration:rootId.animDuration ; easingText: "InOutQuad"; easingType: Easing.InOutQuad; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "darkorange" + animDuration:rootId.animDuration ; easingText: "OutInQuad"; easingType: Easing.OutInQuad; + containerwidth: rootId.width} + + + //Cubic + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "gold" + animDuration:rootId.animDuration ; easingText: "InCubic"; easingType: Easing.InCubic; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "yellow" + animDuration:rootId.animDuration ; easingText: "OutCubic"; easingType: Easing.OutCubic; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "peachpuff" + animDuration:rootId.animDuration ; easingText: "InOutCubic"; easingType: Easing.InOutCubic; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "thistle" + animDuration:rootId.animDuration ; easingText: "OutInCubic"; easingType: Easing.OutInCubic; + containerwidth: rootId.width} + + //Quart + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "orchid" + animDuration: rootId.animDuration; easingText: "InQuart"; easingType: Easing.InQuart; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "purple" + animDuration:rootId.animDuration ; easingText: "OutQuart"; easingType: Easing.OutQuart; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "slateblue" + animDuration:rootId.animDuration ; easingText: "InOutQuart"; easingType: Easing.InOutQuart; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "chartreuse" + animDuration:rootId.animDuration ; easingText: "OutInQuart"; easingType: Easing.OutInQuart; + containerwidth: rootId.width} + + //Quint + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "limegreen" + animDuration:rootId.animDuration ; easingText: "InQuint"; easingType: Easing.InQuint; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "seagreen" + animDuration:rootId.animDuration ; easingText: "OutQuint"; easingType: Easing.OutQuint; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "darkgreen" + animDuration:rootId.animDuration ; easingText: "InOutQuint"; easingType: Easing.InOutQuint; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "olive" + animDuration:rootId.animDuration ; easingText: "OutInQuint"; easingType: Easing.OutInQuint; + containerwidth: rootId.width} + + //Sine + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "darkseagreen" + animDuration:rootId.animDuration ; easingText: "InSine"; easingType: Easing.InSine; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "teal" + animDuration:rootId.animDuration ; easingText: "OutSine"; easingType: Easing.OutSine; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "turquoise" + animDuration: rootId.animDuration; easingText: "InOutSine"; easingType: Easing.InOutSine; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "steelblue" + animDuration:rootId.animDuration ; easingText: "OutInSine"; easingType: Easing.OutInSine; + containerwidth: rootId.width} + + //Expo + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "skyblue" + animDuration:rootId.animDuration ; easingText: "InExpo"; easingType: Easing.InExpo; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "royalblue" + animDuration:rootId.animDuration ; easingText: "OutExpo"; easingType: Easing.OutExpo; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "mediumblue" + animDuration:rootId.animDuration ; easingText: "InOutExpo"; easingType: Easing.InOutExpo; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "midnightblue" + animDuration:rootId.animDuration ; easingText: "OutInExpo"; easingType: Easing.OutInExpo; + containerwidth: rootId.width} + + //Circ + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "cornsilk" + animDuration:rootId.animDuration ; easingText: "InCirc"; easingType: Easing.InCirc; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "bisque" + animDuration:rootId.animDuration ; easingText: "OutCirc"; easingType: Easing.OutCirc; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "rosybrown" + animDuration:rootId.animDuration ; easingText: "InOutCirc"; easingType: Easing.InOutCirc; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "sandybrown" + animDuration:rootId.animDuration ; easingText: "OutInCirc"; easingType: Easing.OutInCirc; + containerwidth: rootId.width} + + + //Elastic + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "cornsilk" + animDuration:rootId.animDuration ; easingText: "InElastic"; easingType: Easing.InElastic; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "bisque" + animDuration:rootId.animDuration ; easingText: "OutElastic"; easingType: Easing.OutElastic; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "rosybrown" + animDuration:rootId.animDuration ; easingText: "InOutElastic"; easingType: Easing.InOutElastic; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "sandybrown" + animDuration:rootId.animDuration ; easingText: "OutInElastic"; easingType: Easing.OutInElastic; + containerwidth: rootId.width} + + + //Black + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "maroon" + animDuration:rootId.animDuration ; easingText: "InBack"; easingType: Easing.InBack; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "lavenderblush" + animDuration:rootId.animDuration ; easingText: "OutBack"; easingType: Easing.OutBack; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "mistyrose" + animDuration:rootId.animDuration ; easingText: "InOutBack"; easingType: Easing.InOutBack; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "gainsboro" + animDuration:rootId.animDuration ; easingText: "OutInBack"; easingType: Easing.OutInBack; + containerwidth: rootId.width} + + + //Bounce + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "silver" + animDuration:rootId.animDuration ; easingText: "InBounce"; easingType: Easing.InBounce; + containerwidth: rootId.width } + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "dimgray" + animDuration:rootId.animDuration ; easingText: "OutBounce"; easingType: Easing.OutBounce; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "slategray" + animDuration:rootId.animDuration ; easingText: "InOutBounce"; easingType: Easing.InOutBounce; + containerwidth: rootId.width} + + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "darkslategray" + animDuration:rootId.animDuration ; easingText: "OutInBounce"; easingType: Easing.OutInBounce; + containerwidth: rootId.width} + + //Bezier + MovingRectangle {backgroundColor: "gray"; startColor: "beige"; endColor: "darkslategray" + animDuration:rootId.animDuration ; easingText: "Bezier"; easingType: Easing.Bezier; + containerwidth: rootId.width} + + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/MovingRectangle.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/MovingRectangle.qml new file mode 100644 index 0000000..1a16eb2 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/MovingRectangle.qml @@ -0,0 +1,99 @@ +import QtQuick + +Item { + + property var backgroundColor + property var startColor + property var endColor + property string easingText + property int animDuration + property var easingType + property int containerwidth + + + width: containerRectId.width + height: containerRectId.height + + property int finalX: containerRectId.width - containedRectId.width + + Rectangle { + id : containerRectId + width: containerwidth + height: 50 + color: backgroundColor + + Text { + + text: easingText + anchors.centerIn: parent + } + + Rectangle{ + id : containedRectId + color: startColor + width: 50 + height: 50 + border {width : 5 ; color : "black" } + radius: 10 + + + MouseArea{ + anchors.fill: parent + + property bool toRight : false + onClicked: { + + if ( toRight === false) + { + toRight = true + //Animate X + mNumberAnimationId.to = finalX + mNumberAnimationId.start() + + //Animate color + mColorAnimationId.from = startColor + mColorAnimationId.to = endColor + mColorAnimationId.start() + + //Move to right + }else{ + //Move to left + toRight = false + //Animate X + mNumberAnimationId.to = 0 + mNumberAnimationId.start() + + //Animate color + mColorAnimationId.from = endColor + mColorAnimationId.to = startColor + mColorAnimationId.start() + } + + } + } + NumberAnimation{ + id : mNumberAnimationId + target: containedRectId + property : "x" + easing.type : easingType + to : finalX + duration: animDuration + } + + + ColorAnimation { + id : mColorAnimationId + target: containedRectId + property : "color" + from: startColor + to: endColor + duration: animDuration + } + Component.onCompleted: { + //console.log("The width of the contained rect is :" + parent.width) + } + + } + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/main.cpp new file mode 100644 index 0000000..e581996 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/10-EasingCurves/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/10-EasingCurves/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/CMakeLists.txt new file mode 100644 index 0000000..f643183 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(11-GroupedAnimations VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app11-GroupedAnimations + main.cpp +) + +qt_add_qml_module(app11-GroupedAnimations + URI 11-GroupedAnimations + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app11-GroupedAnimations PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app11-GroupedAnimations + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app11-GroupedAnimations + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app11-GroupedAnimations + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/Main.qml new file mode 100644 index 0000000..6e2d778 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/Main.qml @@ -0,0 +1,76 @@ +import QtQuick + +Window { + id: rootId + width: 640 + height: 480 + visible: true + title: qsTr("Grouped Animations") + readonly property int animationDuration: 500 + property bool going_down: false + + function animateCircle(){ + + if (going_down === false){ + //Go down + going_down = true + xAnimationId.from = 0 + xAnimationId.to = rootId.width - circleId.width + + yAnimationId.from = 0 + yAnimationId.to = rootId.height - circleId.height + }else{ + //Go up + going_down = false + xAnimationId.from = rootId.width - circleId.width + xAnimationId.to = 0 + + yAnimationId.from = rootId.height - circleId.height + yAnimationId.to = 0 + } + groupedAnimationId.start() + } + + + Rectangle{ + anchors.fill: parent + color: "gray" + + Rectangle{ + id: circleId + width: 100 + height: 100 + radius: 70 + color: "yellowgreen" + + + //SequentialAnimation{ + ParallelAnimation{ + id: groupedAnimationId + + //Animate x + NumberAnimation{ + id: xAnimationId + target: circleId + property: "x" + duration: animationDuration + } + + //Animate y + NumberAnimation{ + id: yAnimationId + target: circleId + property: "y" + duration: animationDuration + } + } + } + + MouseArea{ + anchors.fill: parent + onClicked: function(){ + animateCircle() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/main.cpp new file mode 100644 index 0000000..b35f247 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/11-GroupedAnimations/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/11-GroupedAnimations/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/CMakeLists.txt new file mode 100644 index 0000000..9f811a5 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(12-PendulumSwing VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app12-PendulumSwing + main.cpp +) + +qt_add_qml_module(app12-PendulumSwing + URI 12-PendulumSwing + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app12-PendulumSwing PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app12-PendulumSwing + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app12-PendulumSwing + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app12-PendulumSwing + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/Main.qml new file mode 100644 index 0000000..10b02b1 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/Main.qml @@ -0,0 +1,57 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Pendulum Swing") + + readonly property int pendulumAngle: 30 + readonly property int animDuration: 700 + + Rectangle{ + id: pendulumId + width: 20 + height: 200 + color: "black" + x: (parent.width - width)/2 + y: 50 + transformOrigin: Item.Top + + Rectangle{ + id: bobId + width: 50 + height: 50 + color: "red" + radius: width/2 + x: (pendulumId.width - width)/2 + y: pendulumId.height + transformOrigin: Item.Bottom + rotation: pendulumId.rotation + } + + SequentialAnimation{ + loops: Animation.Infinite + running: true + NumberAnimation{ + id: rightToLeftAnimationId + target: pendulumId + property: "rotation" + from: -pendulumAngle + to: pendulumAngle + duration: animDuration + easing.type: Easing.InOutQuad + } + + NumberAnimation{ + id: leftToRightAnimationId + target: pendulumId + property: "rotation" + from: pendulumAngle + to: -pendulumAngle + duration: animDuration + easing.type: Easing.InOutQuad + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/main.cpp new file mode 100644 index 0000000..229a549 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/12-PendulumSwing/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/12-PendulumSwing/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/CMakeLists.txt new file mode 100644 index 0000000..7f5036b --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.16) + +project(13-StatesTransitions VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app13-StatesTransitions + main.cpp +) + +qt_add_resources(app13-StatesTransitions "images" + PREFIX / + FILES + images/treespringsmall.png + images/treesummersmall.png +) + +qt_add_qml_module(app13-StatesTransitions + URI 13-StatesTransitions + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app13-StatesTransitions PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app13-StatesTransitions + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app13-StatesTransitions + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app13-StatesTransitions + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/Main.qml new file mode 100644 index 0000000..d904fd7 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/Main.qml @@ -0,0 +1,152 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("States and Transitions") + + Rectangle{ + id: containerRectId + anchors.fill: parent + + //Sky + Rectangle{ + id: skyId + width: parent.width + height: 200 + color: "blue" + } + + + Rectangle{ + id: groundId + anchors.top: skyId.bottom + anchors.bottom: parent.bottom + width: parent.width + color: "lime" + } + + + Image{ + id: treeSummerId + x: 50 + y: 100 + width: 200 + height: 300 + source: "qrc:/images/treesummersmall.png" + } + + Image{ + id: treeSpringId + x: 50 + y: 100 + width: 200 + height: 300 + source: "qrc:/images/treespringsmall.png" + } + + Rectangle{ + id: sunId + x: parent.width - width - 100 + y: 50 + width: 100 + height: 100 + color: "yellow" + radius: 600 + } + + state: "spring" + + states: [ + + //Spring + State{ + name: "spring" + PropertyChanges { + target: skyId + color: "deepskyblue" + } + PropertyChanges { + target: treeSummerId + opacity: 0 + } + PropertyChanges { + target: treeSpringId + opacity: 1 + } + PropertyChanges { + target: groundId + color: "lime" + } + PropertyChanges { + target: sunId + color: "lightyellow" + + } + }, + + //Summer + State{ + name: "summer" + PropertyChanges { + target: skyId + color: "lightblue" + } + PropertyChanges { + target: treeSummerId + opacity: 1 + } + PropertyChanges { + target: treeSpringId + opacity: 0 + } + PropertyChanges { + target: groundId + color: "darkkhaki" + } + PropertyChanges { + target: sunId + color: "yellow" + + } + } + + ] + + //Transitions + transitions: [ + Transition{ + from: "summer" + to: "spring" + ColorAnimation{ + duration: 500 + } + NumberAnimation{ + property: "opacity" + duration: 500 + } + }, + + Transition{ + from: "spring" + to: "summer" + ColorAnimation{ + duration: 500 + } + NumberAnimation{ + property: "opacity" + duration: 500 + } + + } + ] + + MouseArea{ + anchors.fill: parent + onClicked: function(){ + containerRectId.state = (containerRectId.state === "spring" ? "summer" : "spring") + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/images/treespringsmall.png b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/images/treespringsmall.png new file mode 100644 index 0000000..8e855ae Binary files /dev/null and b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/images/treespringsmall.png differ diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/images/treesummersmall.png b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/images/treesummersmall.png new file mode 100644 index 0000000..0e426f4 Binary files /dev/null and b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/images/treesummersmall.png differ diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/main.cpp new file mode 100644 index 0000000..847ddfd --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/13-StatesTransitions/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/13-StatesTransitions/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/CMakeLists.txt new file mode 100644 index 0000000..d56955b --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.16) + +project(14-StatesWithGradients VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app14-StatesWithGradients + main.cpp +) + +qt_add_resources(app14-StatesWithGradients "images" + PREFIX / + FILES + images/treespringsmall.png + images/treesummersmall.png +) + +qt_add_qml_module(app14-StatesWithGradients + URI 14-StatesWithGradients + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app14-StatesWithGradients PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app14-StatesWithGradients + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app14-StatesWithGradients + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app14-StatesWithGradients + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/Main.qml new file mode 100644 index 0000000..f78352f --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/Main.qml @@ -0,0 +1,234 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("States with Gradients") + + Rectangle{ + id: containerRectId + anchors.fill: parent + + //Sky + Rectangle{ + id: skyId + width: parent.width + height: 200 + //color: "blue" + gradient: Gradient{ + GradientStop{ + id: skyStartColorId + position: 0.0 + color: "blue" + } + GradientStop{ + id: skyEndColorId + position: 1.0 + color: "#66CCFF" + } + } + } + + + Rectangle{ + id: groundId + anchors.top: skyId.bottom + anchors.bottom: parent.bottom + width: parent.width + //color: "lime" + gradient: Gradient{ + GradientStop{ + id: groundStartColorId + position: 0.0 + color: "lime" + } + GradientStop{ + id: groundEndColorId + position: 1.0 + color: "#66CCFF" + } + } + } + + + Image{ + id: treeSummerId + x: 50 + y: 100 + width: 200 + height: 300 + source: "qrc:/images/treesummersmall.png" + } + + Image{ + id: treeSpringId + x: 50 + y: 100 + width: 200 + height: 300 + source: "qrc:/images/treespringsmall.png" + } + + Rectangle{ + id: sunId + x: parent.width - width - 100 + y: 50 + width: 100 + height: 100 + color: "yellow" + radius: 600 + } + + state: "spring" + + states: [ + + //Spring + State{ + name: "spring" + /* + PropertyChanges { + target: skyId + color: "deepskyblue" + } + */ + PropertyChanges { + target: skyStartColorId + color: "deepskyblue" + } + + PropertyChanges { + target: skyEndColorId + color: "#AACCFF" + } + + PropertyChanges { + target: treeSummerId + opacity: 0 + } + PropertyChanges { + target: treeSpringId + opacity: 1 + } + /* + PropertyChanges { + target: groundId + color: "lime" + } + */ + PropertyChanges { + target: groundStartColorId + color: "lime" + } + PropertyChanges { + target: groundEndColorId + color: "#66CCFF" + } + + PropertyChanges { + target: sunId + color: "lightyellow" + + } + }, + + //Summer + State{ + name: "summer" + /* + PropertyChanges { + target: skyId + color: "lightblue" + } + */ + PropertyChanges{ + target: skyStartColorId + color: "lightblue" + } + PropertyChanges{ + target: skyEndColorId + color: "#EECCFF" + } + PropertyChanges { + target: treeSummerId + opacity: 1 + } + PropertyChanges { + target: treeSpringId + opacity: 0 + } + /* + PropertyChanges { + target: groundId + color: "darkkhaki" + } + */ + PropertyChanges { + target: groundStartColorId + color: "lime" + } + PropertyChanges { + target: groundEndColorId + color: "darkkhaki" + } + PropertyChanges { + target: sunId + color: "yellow" + + } + } + + ] + + //Transitions + /* + transitions: [ + Transition{ + from: "summer" + to: "spring" + ColorAnimation{ + duration: 500 + } + NumberAnimation{ + property: "opacity" + duration: 500 + } + }, + + Transition{ + from: "spring" + to: "summer" + ColorAnimation{ + duration: 500 + } + NumberAnimation{ + property: "opacity" + duration: 500 + } + + } + ] + */ + + transitions: Transition{ + from: "*" + to: "*" + ColorAnimation{ + duration: 500 + } + NumberAnimation{ + property: "opacity" + duration: 500 + } + } + + + MouseArea{ + anchors.fill: parent + onClicked: function(){ + containerRectId.state = (containerRectId.state === "spring" ? "summer" : "spring") + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/images/treespringsmall.png b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/images/treespringsmall.png new file mode 100644 index 0000000..8e855ae Binary files /dev/null and b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/images/treespringsmall.png differ diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/images/treesummersmall.png b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/images/treesummersmall.png new file mode 100644 index 0000000..0e426f4 Binary files /dev/null and b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/images/treesummersmall.png differ diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/main.cpp new file mode 100644 index 0000000..9bafb92 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/14-StatesWithGradients/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/14-StatesWithGradients/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/.gitignore b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/.gitignore new file mode 100644 index 0000000..7803df3 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/.gitignore @@ -0,0 +1,57 @@ +# Qt QML Language Server configuration +qmlls.ini + +# Build directories +build/ +Desktop_Qt_6_9_0_MinGW_64_bit-Debug/ + +# Qt Creator user settings +CMakeLists.txt.user + +# Compiled Object files +*.o +*.obj + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Compiled Static libraries +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Qt-specific +*.qm +*.prl +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +Makefile* +*build-* + +# QML cache and compiled files +*.qmlc +*.jsc + +# Qt temporary files +*~ + +# macOS +.DS_Store + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini \ No newline at end of file diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/CMakeLists.txt new file mode 100644 index 0000000..bd05f5c --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/CMakeLists.txt @@ -0,0 +1,52 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml + src/components/AddTaskBar.qml + src/components/TaskItem.qml + src/components/TaskStats.qml + + # Models + src/models/TaskListModel.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/AddTaskBar.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/AddTaskBar.qml new file mode 100644 index 0000000..72719d0 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/AddTaskBar.qml @@ -0,0 +1,110 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 60 + + signal taskAdded(string taskText) + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color primaryColor: "#007aff" + property bool darkMode: false + + Rectangle { + id: background + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // Add icon + Rectangle { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + color: root.primaryColor + radius: 18 + + Text { + anchors.centerIn: parent + text: "+" + color: "#ffffff" + font.pixelSize: 20 + font.weight: Font.Bold + } + } + + // Text input + TextField { + id: taskInput + Layout.fillWidth: true + Layout.preferredHeight: 36 + placeholderText: qsTr("Add a new task...") + placeholderTextColor: root.darkMode ? "#888888" : "#999999" + color: root.textColor + font.pixelSize: 16 + selectByMouse: true + + background: Rectangle { + color: "transparent" + border.color: "transparent" + } + + Keys.onReturnPressed: root.addTask() + Keys.onEnterPressed: root.addTask() + + } + + // Add button + Button { + id: addButton + Layout.preferredWidth: 80 + Layout.preferredHeight: 36 + text: qsTr("Add") + enabled: taskInput.text.trim().length > 0 + + background: Rectangle { + color: addButton.enabled ? + (addButton.pressed ? Qt.darker(root.primaryColor, 1.2) : root.primaryColor) : + (root.darkMode ? "#404040" : "#e0e0e0") + radius: 8 + + } + + contentItem: Text { + text: addButton.text + color: addButton.enabled ? "#ffffff" : (root.darkMode ? "#888888" : "#cccccc") + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + } + + onClicked: root.addTask() + } + } + } + } + + function addTask() { + if (taskInput.text.trim().length > 0) { + root.taskAdded(taskInput.text.trim()) + taskInput.text = "" + taskInput.focus = false + } + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/AppHeader.qml new file mode 100644 index 0000000..97f5e13 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/AppHeader.qml @@ -0,0 +1,86 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + //Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/TaskItem.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/TaskItem.qml new file mode 100644 index 0000000..cfd5cee --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/TaskItem.qml @@ -0,0 +1,209 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 56 + + required property string taskTitle + required property bool taskDone + + signal toggleDone() + signal deleteTask() + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color completedColor: "#999999" + property color primaryColor: "#007aff" + property bool darkMode: false + + // Constants for this component + readonly property int itemHeight: 56 + readonly property int margins: 4 + readonly property int innerMargins: 12 + readonly property int checkboxSize: 24 + readonly property int deleteButtonSize: 32 + + Rectangle { + id: taskItemBackground + anchors.fill: parent + color: "transparent" + + Rectangle { + id: itemBackground + anchors.fill: parent + anchors.margins: root.margins + color: root.backgroundColor + radius: 8 + border.color: root.taskDone ? "transparent" : (root.darkMode ? "#404040" : "#f0f0f0") + border.width: 1 + opacity: root.taskDone ? 0.7 : 1.0 + + scale: itemBackground.hovered ? 1.02 : 1.0 + + // Smooth transitions for background properties + Behavior on opacity { + NumberAnimation { duration: 300 } + } + + Behavior on border.color { + ColorAnimation { duration: 300 } + } + + Behavior on scale { + NumberAnimation { duration: 150; easing.type: Easing.OutQuad } + } + + RowLayout { + anchors.fill: parent + anchors.margins: root.innerMargins + spacing: 12 + + // Checkbox + Rectangle { + id: checkbox + Layout.preferredWidth: root.checkboxSize + Layout.preferredHeight: root.checkboxSize + color: root.taskDone ? root.primaryColor : "transparent" + border.color: root.taskDone ? root.primaryColor : (root.darkMode ? "#666666" : "#cccccc") + border.width: 2 + radius: 4 + + // Smooth transitions for checkbox state changes + Behavior on color { + ColorAnimation { duration: 200 } + } + + Behavior on border.color { + ColorAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 100; easing.type: Easing.OutBack } + } + + // Checkmark + Text { + anchors.centerIn: parent + text: "✓" + color: "#ffffff" + font.pixelSize: 16 + font.weight: Font.Bold + opacity: root.taskDone ? 1.0 : 0.0 + + scale: root.taskDone ? 1.0 : 0.3 + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutBack } + } + + } + + MouseArea { + anchors.fill: parent + onClicked: { + // Add click animation + checkbox.scale = 0.9 + scaleResetTimer.restart() + + //Toggle the task + root.toggleDone() + } + cursorShape: Qt.PointingHandCursor + } + + // Timer to reset scale after click + Timer { + id: scaleResetTimer + interval: 100 + onTriggered: checkbox.scale = 1.0 + } + + } + + // Task text + Text { + id: taskText + Layout.fillWidth: true + text: root.taskTitle + color: root.taskDone ? root.completedColor : root.textColor + font.pixelSize: 16 + font.strikeout: root.taskDone + wrapMode: Text.WordWrap + + // Smooth color transition when task state changes + Behavior on color { + ColorAnimation { duration: 300 } + } + + // Subtle scale animation on completion + scale: root.taskDone ? 0.95 : 1.0 + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutQuad } + } + + MouseArea { + anchors.fill: parent + onClicked: root.toggleDone() + cursorShape: Qt.PointingHandCursor + } + } + + // Delete button + Button { + id: deleteButton + Layout.preferredWidth: root.deleteButtonSize + Layout.preferredHeight: root.deleteButtonSize + opacity: itemBackground.hovered ? 1.0 : 0.3 + scale: deleteButton.pressed ? 0.9 : 1.0 + + // Smooth transitions + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 100; easing.type: Easing.OutQuad } + } + + background: Rectangle { + color: deleteButton.pressed ? "#ff3b30" : "transparent" + radius: 16 + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text { + text: "🗑" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + rotation: deleteButton.pressed ? 15 : 0 + + Behavior on rotation { + NumberAnimation { duration: 100 } + } + } + + onClicked: { + root.deleteTask() + } + } + } + + // Hover effect + property bool hovered: false + + HoverHandler { + onHoveredChanged: itemBackground.hovered = hovered + } + } +} +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/TaskStats.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/TaskStats.qml new file mode 100644 index 0000000..6d3cde5 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/components/TaskStats.qml @@ -0,0 +1,95 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: visible ? 60 : 0 + visible: totalTasks > 0 + + property int totalTasks: 0 + property int completedTasks: 0 + property int remainingTasks: 0 + property bool hasCompleted: false + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color secondaryTextColor: "#666666" + property color primaryColor: "#007aff" + property color dangerColor: "#ff3b30" + property bool darkMode: false + + signal clearCompleted() + + Rectangle { + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 16 + + // Statistics text + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: root.totalTasks === 1 ? + qsTr("%1 task").arg(root.totalTasks) : + qsTr("%1 tasks").arg(root.totalTasks) + color: root.textColor + font.pixelSize: 16 + font.weight: Font.Medium + } + + Text { + text: root.completedTasks > 0 ? + qsTr("%1 completed, %2 remaining").arg(root.completedTasks).arg(root.remainingTasks) : + qsTr("No tasks completed yet") + color: root.secondaryTextColor + font.pixelSize: 14 + visible: root.totalTasks > 0 + } + } + + // Clear completed button + Button { + id: clearButton + Layout.preferredHeight: 36 + text: qsTr("Clear Completed") + visible: root.hasCompleted + enabled: root.hasCompleted + + background: Rectangle { + color: clearButton.pressed ? + Qt.darker(root.dangerColor, 1.2) : + (clearButton.hovered ? root.dangerColor : "transparent") + border.color: root.dangerColor + border.width: 1 + radius: 8 + } + + contentItem: Text { + text: clearButton.text + color: clearButton.hovered ? "#ffffff" : root.dangerColor + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: root.clearCompleted() + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/main.cpp new file mode 100644 index 0000000..2919679 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/models/TaskListModel.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/models/TaskListModel.qml new file mode 100644 index 0000000..3a2f9d2 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/models/TaskListModel.qml @@ -0,0 +1,89 @@ +import QtQuick + +ListModel { + id: root + + // Add some sample tasks for testing + Component.onCompleted: { + addTask("Learn Qt QML") + addTask("Build a todo app") + addTask("Practice QML components") + } + + // Add a new task + function addTask(title) { + if (title && title.trim().length > 0) { + append({ + "title": title.trim(), + "completed": false, + "id": generateId() + }) + } + } + + // Toggle task completion status + function toggleTask(index) { + if (index >= 0 && index < count) { + setProperty(index, "completed", !get(index).completed) + } + } + + // Delete a task + function deleteTask(index) { + if (index >= 0 && index < count) { + remove(index) + } + } + + // Delete task by ID + function deleteTaskById(taskId) { + for (let i = 0; i < count; i++) { + if (get(i).id === taskId) { + remove(i) + break + } + } + } + + // Clear all completed tasks + function clearCompletedTasks() { + for (let i = count - 1; i >= 0; i--) { + if (get(i).completed) { + remove(i) + } + } + } + + // Get statistics + function getStats() { + let total = count + let completed = 0 + + for (let i = 0; i < count; i++) { + if (get(i).completed) { + completed++ + } + } + + return { + "total": total, + "completed": completed, + "remaining": total - completed + } + } + + // Check if there are any completed tasks + function hasCompletedTasks() { + for (let i = 0; i < count; i++) { + if (get(i).completed) { + return true + } + } + return false + } + + // Generate a unique ID for tasks + function generateId() { + return Date.now() + Math.random().toString(36).substr(2, 9) + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/views/MainView.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/views/MainView.qml new file mode 100644 index 0000000..6199c54 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/15-TodoListAnimations/src/views/MainView.qml @@ -0,0 +1,239 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + // Task model - Using the dedicated TaskListModel + TaskListModel { + id: taskModel + } + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + // Header + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + // Add task bar + AddTaskBar { + id: addTaskBar + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onTaskAdded: function(taskText) { + taskModel.addTask(taskText) + } + } + + // Tasks list + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: root.cardColor + radius: 12 + border.width: 1 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + + ScrollView { + anchors.fill: parent + anchors.margins: 1 + clip: true + + ListView { + id: taskListView + model: taskModel + spacing: 8 + anchors.margins: 12 + + + + // Add animation transitions + add: Transition { + NumberAnimation { + properties: "x" + from: 100; to: 0 + duration: 300 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 0; to: 1 + duration: 300 + } + } + + remove: Transition { + NumberAnimation { + properties: "x" + to: 100 + duration: 250 + easing.type: Easing.InCubic + } + NumberAnimation { + property: "opacity" + to: 0 + duration: 250 + } + } + + displaced: Transition { + NumberAnimation { + properties: "x,y" + duration: 200 + easing.type: Easing.OutQuad + } + } + + + + + + delegate: TaskItem { + required property int index + required property string title + required property bool completed + + width: taskListView.width + taskTitle: title + taskDone: completed + backgroundColor: root.cardColor + textColor: root.textColor + completedColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onToggleDone: { + taskModel.toggleTask(index) + } + + onDeleteTask: { + taskModel.deleteTask(index) + } + } + + // Empty state + Rectangle { + anchors.centerIn: parent + width: parent.width - 40 + height: 120 + color: "transparent" + visible: taskListView.count === 0 + opacity: taskListView.count === 0 ? 1.0 : 0.0 + + + Behavior on opacity { + NumberAnimation { duration: 400; easing.type: Easing.InOutQuad } + } + + Column { + anchors.centerIn: parent + spacing: 16 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: "📝" + font.pixelSize: 48 + opacity: 0.3 + + // Subtle floating animation + SequentialAnimation on y { + running: taskListView.count === 0 + loops: Animation.Infinite + NumberAnimation { from: 0; to: -5; duration: 1000; easing.type: Easing.InOutSine } + NumberAnimation { from: -5; to: 0; duration: 1000; easing.type: Easing.InOutSine } + } + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("No tasks yet") + color: root.completedColor + font.pixelSize: 18 + font.weight: Font.Medium + + // Gentle opacity breathing animation + SequentialAnimation on opacity { + running: taskListView.count === 0 + loops: Animation.Infinite + NumberAnimation { from: 0.7; to: 1.0; duration: 1500; easing.type: Easing.InOutSine } + NumberAnimation { from: 1.0; to: 0.7; duration: 1500; easing.type: Easing.InOutSine } + } + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Add a task above to get started") + color: root.completedColor + font.pixelSize: 14 + horizontalAlignment: Text.AlignHCenter + + // Gentle opacity breathing animation with slight delay + SequentialAnimation on opacity { + running: taskListView.count === 0 + loops: Animation.Infinite + PauseAnimation { duration: 300 } // Small delay for staggered effect + NumberAnimation { from: 0.6; to: 0.9; duration: 1500; easing.type: Easing.InOutSine } + NumberAnimation { from: 0.9; to: 0.6; duration: 1500; easing.type: Easing.InOutSine } + } + } + } + } + } + } + + + } + + // Task statistics at bottom + TaskStats { + id: taskStats + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + secondaryTextColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + totalTasks: taskModel.count + completedTasks: taskModel.getStats().completed + remainingTasks: taskModel.getStats().remaining + hasCompleted: taskModel.hasCompletedTasks() + + onClearCompleted: { + taskModel.clearCompletedTasks() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/CMakeLists.txt new file mode 100644 index 0000000..d3d57c3 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.16) + +project(2-Transforms VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app2-Transforms + main.cpp +) + +qt_add_qml_module(app2-Transforms + URI 2-Transforms + VERSION 1.0 + QML_FILES Main.qml + QML_FILES ClickableRect.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app2-Transforms PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app2-Transforms + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-Transforms + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app2-Transforms + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/ClickableRect.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/ClickableRect.qml new file mode 100644 index 0000000..f8dfd72 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/ClickableRect.qml @@ -0,0 +1,12 @@ +import QtQuick + +Rectangle{ + id: rootId + signal clicked + MouseArea{ + anchors.fill: parent + onClicked: function(){ + rootId.clicked() + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/Main.qml new file mode 100644 index 0000000..a085481 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/Main.qml @@ -0,0 +1,51 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Transforms") + + ClickableRect{ + id: rect1Id + width: 100 + height: 100 + x: 50 + y: 100 + color: "red" + onClicked: function(){ + //Translation on x + x += 20 + } + } + ClickableRect{ + id: rect2Id + width: 100 + height: 100 + transformOrigin: Item.TopRight + x: 250 + y: 100 + color: "green" + onClicked: function(){ + // Rotation + rotation += 15 + } + } + ClickableRect{ + id: rect3Id + width: 100 + height: 100 + transformOrigin: Item.BottomLeft + x: 450 + y: 100 + color: "blue" + onClicked: function(){ + //scaling + scale += 0.05 + + //rotation + rotation += 20 + } + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/main.cpp new file mode 100644 index 0000000..063a39c --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/2-Transforms/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/2-Transforms/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/CMakeLists.txt new file mode 100644 index 0000000..babb62b --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(3-AnimationsIntro VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app3-AnimationsIntro + main.cpp +) + +qt_add_qml_module(app3-AnimationsIntro + URI 3-AnimationsIntro + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app3-AnimationsIntro PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app3-AnimationsIntro + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-AnimationsIntro + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app3-AnimationsIntro + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/Main.qml new file mode 100644 index 0000000..578dd4b --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/Main.qml @@ -0,0 +1,55 @@ +import QtQuick + +Window { + id: rootId + width: 640 + height: 480 + visible: true + title: qsTr("Animations Intro") + property bool running: false + + Rectangle{ + id: containerRectId + anchors.fill: parent + color: "beige" + + + Rectangle{ + id: containedRectId + width: 100 + height: 100 + x: 50 + y: 50 + color: "dodgerblue" + + PropertyAnimation on x { + to: 530 + duration: 2000 + running: rootId.running + } + + NumberAnimation on y { + to: 300 + duration: 2000 + running: rootId.running + } + + RotationAnimation on rotation { + to: 600 + duration: 2000 + running: rootId.running + } + } + + MouseArea{ + anchors.fill: parent + onPressed: function(){ + rootId.running = true + } + onReleased: function(){ + rootId.running = false + } + } + + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/main.cpp new file mode 100644 index 0000000..9bcff38 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/3-AnimationsIntro/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/3-AnimationsIntro/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/CMakeLists.txt new file mode 100644 index 0000000..27d6200 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(4-AnimationsTargets VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app4-AnimationsTargets + main.cpp +) + +qt_add_qml_module(app4-AnimationsTargets + URI 4-AnimationsTargets + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app4-AnimationsTargets PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app4-AnimationsTargets + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-AnimationsTargets + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app4-AnimationsTargets + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/Main.qml new file mode 100644 index 0000000..d29a0ef --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/Main.qml @@ -0,0 +1,66 @@ +import QtQuick + +Window { + id: rootId + width: 640 + height: 480 + visible: true + title: qsTr("Animations with targets") + + Rectangle{ + id: containerRectId + anchors.fill: parent + color: "beige" + + + Rectangle{ + id: containedRectId + width: 100 + height: 100 + x: 50 + y: 50 + color: "dodgerblue" + + PropertyAnimation { + id: xAnimationId + target: containedRectId + property: "x" + to: 530 + duration: 2000 + } + + NumberAnimation { + id: yAnimationId + target: containedRectId + property: "y" + to: 300 + duration: 2000 + } + + RotationAnimation { + id: rotationAnimationId + target: containedRectId + property: "rotation" + to: 600 + duration: 2000 + } + } + + MouseArea{ + anchors.fill: parent + onPressed: function(){ + //Start the animations + xAnimationId.start() + yAnimationId.start() + rotationAnimationId.start() + } + onReleased: function(){ + ///Stop the animations + xAnimationId.stop() + yAnimationId.stop() + rotationAnimationId.stop() + } + } + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/main.cpp new file mode 100644 index 0000000..1592973 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/4-AnimationsTargets/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/4-AnimationsTargets/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/CMakeLists.txt new file mode 100644 index 0000000..a77fc27 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(5-Behavior VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app5-Behavior + main.cpp +) + +qt_add_qml_module(app5-Behavior + URI 5-Behavior + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app5-Behavior PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app5-Behavior + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-Behavior + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app5-Behavior + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/Main.qml new file mode 100644 index 0000000..8387e1e --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/Main.qml @@ -0,0 +1,38 @@ +import QtQuick + +Window { + id: rooId + width: 640 + height: 480 + visible: true + title: qsTr("Behavior") + + + Rectangle{ + id: containerRectId + anchors.fill: parent + color: "beige" + + Rectangle{ + id: containedRectId + width: 100 + height: 100 + x: 50 + y: 50 + color: "dodgerblue" + + Behavior on x{ + NumberAnimation{ + duration: 1000 + } + } + } + + MouseArea{ + anchors.fill: parent + onClicked: (mouse) => { //Arrow function + containedRectId.x = mouse.x + } + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/main.cpp new file mode 100644 index 0000000..f03aadd --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/5-Behavior/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/5-Behavior/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/CMakeLists.txt new file mode 100644 index 0000000..fbfd807 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(6-SmoothedAnimation VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app6-SmoothedAnimation + main.cpp +) + +qt_add_qml_module(app6-SmoothedAnimation + URI 6-SmoothedAnimation + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app6-SmoothedAnimation PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app6-SmoothedAnimation + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-SmoothedAnimation + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app6-SmoothedAnimation + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/Main.qml new file mode 100644 index 0000000..4da888b --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/Main.qml @@ -0,0 +1,71 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("SmoothedAnimation") + + /* + Rectangle{ + id: containerRectId + anchors.fill: parent + color: "beige" + + Rectangle{ + id: containedRectId + width: 100 + height: 100 + x: 50 + y: 50 + color: "dodgerblue" + + + SmoothedAnimation{ + id: smoothedAnimationId + target: containedRectId + property: "x" + duration: 2000 + } + } + } + + MouseArea{ + anchors.fill: parent + onClicked: function(mouse){ + smoothedAnimationId.from = containedRectId.x + smoothedAnimationId.to = mouse.x + smoothedAnimationId.start() + } + } + */ + + Rectangle{ + anchors.fill: parent + color: "lightgray" + + Rectangle { + //The rectangle doing the tracking + width: 60; height: 60 + x: rect1.x - 5; y: rect1.y - 5 + color: "green" + + Behavior on x { SmoothedAnimation { velocity: 200 } } + Behavior on y { SmoothedAnimation { velocity: 200 } } + } + + Rectangle { + //The rectangle being tracked. + id: rect1 + width: 50; height: 50 + color: "red" + } + + focus: true + Keys.onRightPressed: rect1.x = rect1.x + 100 + Keys.onLeftPressed: rect1.x = rect1.x - 100 + Keys.onUpPressed: rect1.y = rect1.y - 100 + Keys.onDownPressed: rect1.y = rect1.y + 100 + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/main.cpp new file mode 100644 index 0000000..817a6ac --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/6-SmoothedAnimation/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/6-SmoothedAnimation/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/CMakeLists.txt new file mode 100644 index 0000000..66e25c9 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(7-SpringAnimation VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app7-SpringAnimation + main.cpp +) + +qt_add_qml_module(app7-SpringAnimation + URI 7-SpringAnimation + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app7-SpringAnimation PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app7-SpringAnimation + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-SpringAnimation + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app7-SpringAnimation + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/Main.qml new file mode 100644 index 0000000..2a76f63 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/Main.qml @@ -0,0 +1,68 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("SpringAnimation") + + Rectangle{ + id: containerRectId + anchors.fill: parent + color: "beige" + + Rectangle{ + id: containedRectId + width: 100 + height: 100 + x: 50 + y: 50 + color: "dodgerblue" + + + /* + Behavior on x{ + SpringAnimation{ + spring: 5 + damping: 0.2 + duration: 3000 + } + } + + Behavior on y{ + SpringAnimation{ + spring: 5 + damping: 0.2 + duration: 3000 + } + } + */ + + + SpringAnimation{ + id: springAnimationId + target: containedRectId + property: "x" + spring: 5 + damping: 0.2 + duration: 3000 + } + } + + MouseArea{ + anchors.fill: parent + onClicked: function(mouse){ + /* + containedRectId.x = mouse.x + containedRectId.y = mouse.y + */ + + springAnimationId.stop() + springAnimationId.from = containedRectId.x + springAnimationId.to = mouse.x + springAnimationId.start() + } + } + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/main.cpp new file mode 100644 index 0000000..6cff849 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/7-SpringAnimation/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/7-SpringAnimation/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/CMakeLists.txt new file mode 100644 index 0000000..64f1fcb --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(8-PathAnimation VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app8-PathAnimation + main.cpp +) + +qt_add_qml_module(app8-PathAnimation + URI 8-PathAnimation + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app8-PathAnimation PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app8-PathAnimation + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app8-PathAnimation + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app8-PathAnimation + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/Main.qml new file mode 100644 index 0000000..ab19122 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/Main.qml @@ -0,0 +1,89 @@ +import QtQuick + +Window { + id: rootId + width: 640 + height: 480 + visible: true + title: qsTr("PathAnimation") + + + Rectangle{ + id: containerRectId + anchors.fill: parent + color: "beige" + + + Rectangle{ + id: containedRectId + width: 100 + height: 100 + x: rootId.width/2 - 50 + y: rootId.height - 50 -50 + color: "dodgerblue" + radius: 80 + + PathAnimation{ + id: pathAnimationId + target: containedRectId + duration: 1000 + anchorPoint: Qt.point(50,50) + path: Path { + //Bottom : Starting Point + startX: rootId.width/2 + startY: rootId.height - 50 + + // Towards Left + PathCubic { + x: 50 + y: rootId.height/2 + + control1X: rootId.width/2 - rootId.width/8 + control1Y: rootId.height + control2X: 0 + control2Y: rootId.height/2 + rootId.height/8 + + } + + //Towards Top: Q2 + PathCubic { + x: rootId.width/2 + y: 50 + control1X: 0 + control1Y: (rootId.height/2 - rootId.height/8) + control2X : (rootId.width/2 - rootId.width/8) + control2Y: 0 + } + + //Towards Right: Q3 + PathCubic { + x: rootId.width - 50 + y: rootId.height/2 + control1X: rootId.width/2 + rootId.width/8 + control1Y: 0 + control2X: rootId.width + control2Y: rootId.height/2 - rootId.height/8 + } + + //Towards bottom: Q4 + PathCubic { + x: rootId.width/2 + y: rootId.height - 50 + control1X: rootId.width + control1Y: rootId.height/2 + rootId.height/8 + control2X: rootId.width/2 + rootId.width/8 + control2Y: rootId.height + } + } + } + } + + MouseArea{ + anchors.fill: parent + onClicked: function(mouse){ + pathAnimationId.start() + } + } + } + +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/main.cpp new file mode 100644 index 0000000..abad786 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/8-PathAnimation/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/8-PathAnimation/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/CMakeLists.txt b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/CMakeLists.txt new file mode 100644 index 0000000..b568ff0 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(9-ColorAnimation VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app9-ColorAnimation + main.cpp +) + +qt_add_qml_module(app9-ColorAnimation + URI 9-ColorAnimation + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app9-ColorAnimation PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app9-ColorAnimation + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app9-ColorAnimation + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app9-ColorAnimation + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/Main.qml b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/Main.qml new file mode 100644 index 0000000..f5ba8f9 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/Main.qml @@ -0,0 +1,32 @@ +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("ColorAnimation") + + + Rectangle{ + id: rectId + width: 100 + height: 100 + color: "red" + + ColorAnimation{ + id: colorAnimationId + target: rectId + property: "color" + from: rectId.color + to: "blue" + duration: 1000 + } + } + + MouseArea{ + anchors.fill: parent + onClicked: function(){ + colorAnimationId.start() + } + } +} diff --git a/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/main.cpp b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/main.cpp new file mode 100644 index 0000000..373a049 --- /dev/null +++ b/Qt6QMLBeginnersCode/12-TransformsTransitionsAnimations/9-ColorAnimation/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/9-ColorAnimation/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/CMakeLists.txt b/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/CMakeLists.txt new file mode 100644 index 0000000..54a98be --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-SettingsAutomatic VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-SettingsAutomatic + main.cpp +) + +qt_add_qml_module(app2-SettingsAutomatic + URI 2-SettingsAutomatic + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-SettingsAutomatic PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-SettingsAutomatic + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app2-SettingsAutomatic + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/Main.qml b/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/Main.qml new file mode 100644 index 0000000..feef4ac --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/Main.qml @@ -0,0 +1,54 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Dialogs +import QtCore + +Window { + id: rootId + visible: true + width: 640 + height: 480 + title: qsTr("SettingsDemo1") + + Rectangle { + id: rectId + anchors.fill: parent + color: "red" + + MouseArea{ + anchors.fill: parent + onClicked: { + colorDialogId.open() + } + + ColorDialog { + id: colorDialogId + title: "Please choose a color" + onAccepted: { + console.log("The new color is: "+ selectedColor) + rectId.color = selectedColor + } + onRejected: { + console.log("Canceled") + } + } + } + } + + + Settings{ + category: "window" + property alias x: rootId.x + property alias y: rootId.y + property alias width: rootId.width + property alias height: rootId.height + } + + Settings{ + category: "colors" + property alias rectColor: rectId.color + } + +} diff --git a/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/main.cpp b/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/main.cpp new file mode 100644 index 0000000..4bfe7db --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/2-SettingsAutomatic/main.cpp @@ -0,0 +1,28 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQuickStyle::setStyle("Basic"); + + //App Information + app.setOrganizationName("LearnQt"); + app.setOrganizationDomain("learnqt.guide"); + app.setApplicationName("SettingsDemo"); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-SettingsAutomatic", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/CMakeLists.txt b/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/CMakeLists.txt new file mode 100644 index 0000000..921acf2 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-SettingsCustom VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-SettingsCustom + main.cpp +) + +qt_add_qml_module(app3-SettingsCustom + URI 3-SettingsCustom + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-SettingsCustom PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-SettingsCustom + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app3-SettingsCustom + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/Main.qml b/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/Main.qml new file mode 100644 index 0000000..54f28a7 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/Main.qml @@ -0,0 +1,75 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Dialogs +import QtCore + +Window { + id: rootId + visible: true + + //2.Read data from the Settings object + x: windowSettingsId.x + y: windowSettingsId.y + width: windowSettingsId.width + height: windowSettingsId.height + + title: qsTr("Custom Settings") + + Rectangle { + id : rectId + anchors.fill: parent + + //2.Read data from the Settings object + color: colorSettingsId.rectColor + + MouseArea{ + anchors.fill: parent + onClicked: { + colorDialogId.open() + } + + ColorDialog { + id: colorDialogId + title: "Please choose a color" + onAccepted: { + console.log("The new color is: "+ selectedColor) + rectId.color = selectedColor + } + onRejected: { + console.log("Canceled") + } + } + } + } + + + //1. Don't use property aliases in the Settings objects + Settings{ + id: windowSettingsId + category: "window" + property int x: 300 + property int y: 300 + property int width: 640 + property int height: 480 + } + + Settings{ + id: colorSettingsId + category: "colors" + property color rectColor: "red" + } + + //3.Save the data when the Window object is about to die + Component.onDestruction: { + //Save the window properties + windowSettingsId.x = rootId.x + windowSettingsId.y = rootId.y + windowSettingsId.width = rootId.width + windowSettingsId.height = rootId.height + + //Save the color property + colorSettingsId.rectColor = rectId.color + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/main.cpp b/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/main.cpp new file mode 100644 index 0000000..1b4d1d9 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/3-SettingsCustom/main.cpp @@ -0,0 +1,28 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQuickStyle::setStyle("Basic"); + + //App Information + app.setOrganizationName("LearnQt2"); + app.setOrganizationDomain("learnqts.guide"); + app.setApplicationName("SettingsDemos"); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-SettingsCustom", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/CMakeLists.txt b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/CMakeLists.txt new file mode 100644 index 0000000..97e34e2 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-SaveTheStates VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-SaveTheStates + main.cpp resource.qrc +) + +qt_add_qml_module(app4-SaveTheStates + URI 4-SaveTheStates + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-SaveTheStates PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-SaveTheStates + PRIVATE Qt6::Quick +) + +install(TARGETS app4-SaveTheStates + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/Main.qml b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/Main.qml new file mode 100644 index 0000000..3954022 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/Main.qml @@ -0,0 +1,189 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtCore +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Custom Settings Demo") + + Rectangle { + id: containerRectId + anchors.fill: parent + + Rectangle { + id: skyId + width: parent.width + height: 200 + //color : "blue" + gradient: Gradient { + GradientStop {id: skyStartColorId; position: 0.0; color: "blue" } + GradientStop {id: skyEndColorId; position: 1.0; color: "#66CCFF" } + } + } + + Rectangle { + id: groundId + anchors.top: skyId.bottom + anchors.bottom: parent.bottom + width: parent.width + //color: "lime" + gradient: Gradient { + GradientStop {id: groundStartColorId; position: 0.0; color: "lime" } + GradientStop {id: groundEndColorId; position: 1.0; color: "#66CCFF" } + } + } + + Image { + id: treespringId + x: 50 + y: 100 + width: 200 + height: 300 + source: "qrc:/images/treespringsmall.png" + } + Image { + id: treeSummerId + x: 50 + y: 100 + width: 200 + height: 300 + source: "qrc:/images/treesummersmall.png" + } + + Rectangle { + id : sunId + x: parent.width - width -100 + y: 50 + width: 100 + height: 100 + color: "yellow" + radius: 60 + + + } + + //state : "spring" + state: settings.state + + //States + states: [ + State { + name : "summer" + PropertyChanges { + target: skyId + color: "lightblue" + + } + + PropertyChanges { + target: skyStartColorId + color: "lightblue" + } + PropertyChanges { + target: skyEndColorId + color: "#EECCFF" + } + + + + PropertyChanges { + target: treeSummerId + opacity: 1 + } + PropertyChanges { + target: treespringId + opacity: 0 + } + + + PropertyChanges { + target: groundStartColorId + color: "lime" + } + PropertyChanges { + target: groundEndColorId + color: "darkkhaki" + } + PropertyChanges { + target: sunId + color: "yellow" + + } + + + }, + State { + name: "spring" + PropertyChanges { + target: skyId + color: "deepskyblue" + } + + PropertyChanges { + target: skyStartColorId + color: "deepskyblue" + } + + PropertyChanges { + target: skyEndColorId + color: "#AACCFF" + } + + PropertyChanges { + target: treeSummerId + opacity: 0 + } + PropertyChanges { + target: treespringId + opacity: 1 + } + + PropertyChanges { + target: groundStartColorId + color: "lime" + } + PropertyChanges { + target: groundStartColorId + color: "lime" + } + + PropertyChanges { + target: sunId + color: "lightyellow" + } + } + ] + + transitions : Transition { + from: "*" ; to: "*" + + ColorAnimation { + duration: 500 + } + NumberAnimation { + properties: "opacity" + duration: 500 + } + } + + MouseArea{ + anchors.fill: parent + onClicked: { + containerRectId.state = (containerRectId.state === "spring" ? "summer" : "spring") + } + } + + Settings { + id: settings + property string state: "spring" + } + + Component.onDestruction: { + settings.state = containerRectId.state + } + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/images/treespringsmall.png b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/images/treespringsmall.png new file mode 100644 index 0000000..8e855ae Binary files /dev/null and b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/images/treespringsmall.png differ diff --git a/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/images/treesummersmall.png b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/images/treesummersmall.png new file mode 100644 index 0000000..0e426f4 Binary files /dev/null and b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/images/treesummersmall.png differ diff --git a/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/main.cpp b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/main.cpp new file mode 100644 index 0000000..183b70d --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/main.cpp @@ -0,0 +1,26 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + + //App Information + app.setOrganizationName("LearnQt1"); + app.setOrganizationDomain("learnqt1.guide"); + app.setApplicationName("SettingsDemo1"); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-SaveTheStates", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/resource.qrc b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/resource.qrc new file mode 100644 index 0000000..224b853 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/4-SaveTheStates/resource.qrc @@ -0,0 +1,6 @@ + + + images/treespringsmall.png + images/treesummersmall.png + + diff --git a/Qt6QMLBeginnersCode/13-Storage/5-SQLite/CMakeLists.txt b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/CMakeLists.txt new file mode 100644 index 0000000..40243a3 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-SQLite VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-SQLite + main.cpp +) + +qt_add_qml_module(app5-SQLite + URI 5-SQLite + VERSION 1.0 + QML_FILES Main.qml Database.js +) + +set_target_properties(app5-SQLite PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-SQLite + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app5-SQLite + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/13-Storage/5-SQLite/Database.js b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/Database.js new file mode 100644 index 0000000..a38b0df --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/Database.js @@ -0,0 +1,79 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +function dbInit(){ + console.log(" Initializing database...") + + db = LocalStorage.openDatabaseSync("sqlitedemodb", "1.0", "SQLite Demo database", 100000); + db.transaction( function(tx) { + print('... create table') + tx.executeSql('CREATE TABLE IF NOT EXISTS sqlitedemotable(name TEXT, value TEXT)'); + }); +} + + +function storeData(){ + console.log(" Storing data...") + + //Check if the database was ever created + if (!db){ + return ; + } + + db.transaction(function(tx){ + //Check if sqlitedemo entry is available in database table + var result = tx.executeSql('SELECT * from sqlitedemotable where name = "sqlitedemo"'); + + //Prepare json object data from qml code + var obj = { x: rootId.x, y: rootId.y, + width : rootId.width,height : rootId.height, + colorred : rectId.color.r,colorgreen : rectId.color.g , + colorblue : rectId.color.b }; + + if ( result.rows.length ===1 ){ + //Update + console.log("Updating database table...") + result = tx.executeSql('UPDATE sqlitedemotable set value=? where name="sqlitedemo"', + [JSON.stringify(obj)]) + }else{ + //Create entry + console.log("Creating new database table entry") + result = tx.executeSql('INSERT INTO sqlitedemotable VALUES (?,?)', + ['sqlitedemo', JSON.stringify(obj)]) + } + + }); + +} + + +function readData(){ + console.log(" Reading data...") + + if (!db){ + return ; + } + + db.transaction( function(tx) { + print('... Reading data from database') + var result = tx.executeSql('select * from sqlitedemotable where name="sqlitedemo"'); + + if(result.rows.length === 1){ + //We have data that we can work with + + // get the value column + var value = result.rows[0].value; + // convert to JS object + var obj = JSON.parse(value) + + // apply to object + rootId.x = obj.x; + rootId.y = obj.y; + rootId.width= obj.width; + rootId.height = obj.height + rectId.color= Qt.rgba(obj.colorred,obj.colorgreen,obj.colorblue,1) + } + + }); + +} diff --git a/Qt6QMLBeginnersCode/13-Storage/5-SQLite/Main.qml b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/Main.qml new file mode 100644 index 0000000..cd9ed06 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/Main.qml @@ -0,0 +1,51 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.LocalStorage +import QtQuick.Dialogs +import "Database.js" as JS + +Window { + id: rootId + visible: true + width: 640 + height: 480 + title: qsTr("SQLite") + property var db ; + + Rectangle{ + id: rectId + anchors.fill: parent + color: "red" + + MouseArea{ + anchors.fill: parent + onClicked: { + colorDialogId.open() + } + + ColorDialog { + id: colorDialogId + title: "Please choose a color" + onAccepted: { + console.log("The new color is: "+ selectedColor) + rectId.color = selectedColor + } + onRejected: { + console.log("Canceled") + } + } + } + } + + Component.onCompleted: { + //Read data + JS.dbInit() + JS.readData() + } + + Component.onDestruction: { + JS.storeData() + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/5-SQLite/main.cpp b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/main.cpp new file mode 100644 index 0000000..6ee808f --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/5-SQLite/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + QQuickStyle::setStyle("Basic"); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-SQLite", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/.gitignore b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/.gitignore new file mode 100644 index 0000000..7803df3 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/.gitignore @@ -0,0 +1,57 @@ +# Qt QML Language Server configuration +qmlls.ini + +# Build directories +build/ +Desktop_Qt_6_9_0_MinGW_64_bit-Debug/ + +# Qt Creator user settings +CMakeLists.txt.user + +# Compiled Object files +*.o +*.obj + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Compiled Static libraries +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Qt-specific +*.qm +*.prl +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +Makefile* +*build-* + +# QML cache and compiled files +*.qmlc +*.jsc + +# Qt temporary files +*~ + +# macOS +.DS_Store + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini \ No newline at end of file diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/CMakeLists.txt b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/CMakeLists.txt new file mode 100644 index 0000000..c38c443 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml + src/components/AddTaskBar.qml + src/components/TaskItem.qml + src/components/TaskStats.qml + + # Models + src/models/TaskListModel.qml + + # Utils + src/utils/TaskStorage.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/AddTaskBar.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/AddTaskBar.qml new file mode 100644 index 0000000..72719d0 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/AddTaskBar.qml @@ -0,0 +1,110 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 60 + + signal taskAdded(string taskText) + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color primaryColor: "#007aff" + property bool darkMode: false + + Rectangle { + id: background + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // Add icon + Rectangle { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + color: root.primaryColor + radius: 18 + + Text { + anchors.centerIn: parent + text: "+" + color: "#ffffff" + font.pixelSize: 20 + font.weight: Font.Bold + } + } + + // Text input + TextField { + id: taskInput + Layout.fillWidth: true + Layout.preferredHeight: 36 + placeholderText: qsTr("Add a new task...") + placeholderTextColor: root.darkMode ? "#888888" : "#999999" + color: root.textColor + font.pixelSize: 16 + selectByMouse: true + + background: Rectangle { + color: "transparent" + border.color: "transparent" + } + + Keys.onReturnPressed: root.addTask() + Keys.onEnterPressed: root.addTask() + + } + + // Add button + Button { + id: addButton + Layout.preferredWidth: 80 + Layout.preferredHeight: 36 + text: qsTr("Add") + enabled: taskInput.text.trim().length > 0 + + background: Rectangle { + color: addButton.enabled ? + (addButton.pressed ? Qt.darker(root.primaryColor, 1.2) : root.primaryColor) : + (root.darkMode ? "#404040" : "#e0e0e0") + radius: 8 + + } + + contentItem: Text { + text: addButton.text + color: addButton.enabled ? "#ffffff" : (root.darkMode ? "#888888" : "#cccccc") + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + } + + onClicked: root.addTask() + } + } + } + } + + function addTask() { + if (taskInput.text.trim().length > 0) { + root.taskAdded(taskInput.text.trim()) + taskInput.text = "" + taskInput.focus = false + } + } + +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/AppHeader.qml new file mode 100644 index 0000000..97f5e13 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/AppHeader.qml @@ -0,0 +1,86 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + //Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/TaskItem.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/TaskItem.qml new file mode 100644 index 0000000..cfd5cee --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/TaskItem.qml @@ -0,0 +1,209 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 56 + + required property string taskTitle + required property bool taskDone + + signal toggleDone() + signal deleteTask() + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color completedColor: "#999999" + property color primaryColor: "#007aff" + property bool darkMode: false + + // Constants for this component + readonly property int itemHeight: 56 + readonly property int margins: 4 + readonly property int innerMargins: 12 + readonly property int checkboxSize: 24 + readonly property int deleteButtonSize: 32 + + Rectangle { + id: taskItemBackground + anchors.fill: parent + color: "transparent" + + Rectangle { + id: itemBackground + anchors.fill: parent + anchors.margins: root.margins + color: root.backgroundColor + radius: 8 + border.color: root.taskDone ? "transparent" : (root.darkMode ? "#404040" : "#f0f0f0") + border.width: 1 + opacity: root.taskDone ? 0.7 : 1.0 + + scale: itemBackground.hovered ? 1.02 : 1.0 + + // Smooth transitions for background properties + Behavior on opacity { + NumberAnimation { duration: 300 } + } + + Behavior on border.color { + ColorAnimation { duration: 300 } + } + + Behavior on scale { + NumberAnimation { duration: 150; easing.type: Easing.OutQuad } + } + + RowLayout { + anchors.fill: parent + anchors.margins: root.innerMargins + spacing: 12 + + // Checkbox + Rectangle { + id: checkbox + Layout.preferredWidth: root.checkboxSize + Layout.preferredHeight: root.checkboxSize + color: root.taskDone ? root.primaryColor : "transparent" + border.color: root.taskDone ? root.primaryColor : (root.darkMode ? "#666666" : "#cccccc") + border.width: 2 + radius: 4 + + // Smooth transitions for checkbox state changes + Behavior on color { + ColorAnimation { duration: 200 } + } + + Behavior on border.color { + ColorAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 100; easing.type: Easing.OutBack } + } + + // Checkmark + Text { + anchors.centerIn: parent + text: "✓" + color: "#ffffff" + font.pixelSize: 16 + font.weight: Font.Bold + opacity: root.taskDone ? 1.0 : 0.0 + + scale: root.taskDone ? 1.0 : 0.3 + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutBack } + } + + } + + MouseArea { + anchors.fill: parent + onClicked: { + // Add click animation + checkbox.scale = 0.9 + scaleResetTimer.restart() + + //Toggle the task + root.toggleDone() + } + cursorShape: Qt.PointingHandCursor + } + + // Timer to reset scale after click + Timer { + id: scaleResetTimer + interval: 100 + onTriggered: checkbox.scale = 1.0 + } + + } + + // Task text + Text { + id: taskText + Layout.fillWidth: true + text: root.taskTitle + color: root.taskDone ? root.completedColor : root.textColor + font.pixelSize: 16 + font.strikeout: root.taskDone + wrapMode: Text.WordWrap + + // Smooth color transition when task state changes + Behavior on color { + ColorAnimation { duration: 300 } + } + + // Subtle scale animation on completion + scale: root.taskDone ? 0.95 : 1.0 + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutQuad } + } + + MouseArea { + anchors.fill: parent + onClicked: root.toggleDone() + cursorShape: Qt.PointingHandCursor + } + } + + // Delete button + Button { + id: deleteButton + Layout.preferredWidth: root.deleteButtonSize + Layout.preferredHeight: root.deleteButtonSize + opacity: itemBackground.hovered ? 1.0 : 0.3 + scale: deleteButton.pressed ? 0.9 : 1.0 + + // Smooth transitions + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 100; easing.type: Easing.OutQuad } + } + + background: Rectangle { + color: deleteButton.pressed ? "#ff3b30" : "transparent" + radius: 16 + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text { + text: "🗑" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + rotation: deleteButton.pressed ? 15 : 0 + + Behavior on rotation { + NumberAnimation { duration: 100 } + } + } + + onClicked: { + root.deleteTask() + } + } + } + + // Hover effect + property bool hovered: false + + HoverHandler { + onHoveredChanged: itemBackground.hovered = hovered + } + } +} +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/TaskStats.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/TaskStats.qml new file mode 100644 index 0000000..6d3cde5 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/components/TaskStats.qml @@ -0,0 +1,95 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: visible ? 60 : 0 + visible: totalTasks > 0 + + property int totalTasks: 0 + property int completedTasks: 0 + property int remainingTasks: 0 + property bool hasCompleted: false + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color secondaryTextColor: "#666666" + property color primaryColor: "#007aff" + property color dangerColor: "#ff3b30" + property bool darkMode: false + + signal clearCompleted() + + Rectangle { + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 16 + + // Statistics text + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: root.totalTasks === 1 ? + qsTr("%1 task").arg(root.totalTasks) : + qsTr("%1 tasks").arg(root.totalTasks) + color: root.textColor + font.pixelSize: 16 + font.weight: Font.Medium + } + + Text { + text: root.completedTasks > 0 ? + qsTr("%1 completed, %2 remaining").arg(root.completedTasks).arg(root.remainingTasks) : + qsTr("No tasks completed yet") + color: root.secondaryTextColor + font.pixelSize: 14 + visible: root.totalTasks > 0 + } + } + + // Clear completed button + Button { + id: clearButton + Layout.preferredHeight: 36 + text: qsTr("Clear Completed") + visible: root.hasCompleted + enabled: root.hasCompleted + + background: Rectangle { + color: clearButton.pressed ? + Qt.darker(root.dangerColor, 1.2) : + (clearButton.hovered ? root.dangerColor : "transparent") + border.color: root.dangerColor + border.width: 1 + radius: 8 + } + + contentItem: Text { + text: clearButton.text + color: clearButton.hovered ? "#ffffff" : root.dangerColor + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: root.clearCompleted() + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/main.cpp b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/main.cpp new file mode 100644 index 0000000..1038e99 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/main.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set application identifiers for Settings + app.setOrganizationName("TodoApp"); + app.setOrganizationDomain("todoapp.local"); + app.setApplicationName("TodoList"); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + // Print the settings location + QSettings settings; + qDebug() << "Settings location:" << settings.fileName(); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/models/TaskListModel.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/models/TaskListModel.qml new file mode 100644 index 0000000..9369bc7 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/models/TaskListModel.qml @@ -0,0 +1,164 @@ +import QtQuick + +Item { + id: root + + // Signal emitted when storage is initialized and ready + signal storageInitialized() + + // The actual ListModel for tasks + property alias model: taskListModel + property alias count: taskListModel.count + + // Auto-save flag + property bool autoSave: true + + ListModel { + id: taskListModel + } + + // Storage component for persistence + TaskStorage { + id: storage + + onTasksLoaded: function(tasks) { + root.loadTasksFromArray(tasks) + } + + Component.onCompleted: { + // Emit signal that storage is ready + root.storageInitialized() + + // Load existing tasks + let savedTasks = loadTasks() + if (savedTasks.length === 0) { + // Add some sample tasks only if no saved tasks exist + root.addTask("Learn Qt QML") + root.addTask("Build a todo app") + root.addTask("Practice QML components") + } + } + } + + // Auto-save trigger - called after any modification + function saveToStorage() { + if (autoSave) { + storage.saveTasks(taskListModel) + } + } + + // Load tasks from an array (used by storage) + function loadTasksFromArray(taskArray) { + taskListModel.clear() + for (let i = 0; i < taskArray.length; i++) { + let task = taskArray[i] + taskListModel.append({ + "id": task.id || generateId(), + "title": task.title || "", + "completed": task.completed || false + }) + } + } + + // Add a new task + function addTask(title) { + if (title && title.trim().length > 0) { + taskListModel.append({ + "title": title.trim(), + "completed": false, + "id": generateId() + }) + saveToStorage() + } + } + + // Toggle task completion status + function toggleTask(index) { + if (index >= 0 && index < taskListModel.count) { + taskListModel.setProperty(index, "completed", !taskListModel.get(index).completed) + saveToStorage() + } + } + + // Delete a task + function deleteTask(index) { + if (index >= 0 && index < taskListModel.count) { + taskListModel.remove(index) + saveToStorage() + } + } + + // Delete task by ID + function deleteTaskById(taskId) { + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).id === taskId) { + taskListModel.remove(i) + saveToStorage() + break + } + } + } + + // Clear all completed tasks + function clearCompletedTasks() { + for (let i = taskListModel.count - 1; i >= 0; i--) { + if (taskListModel.get(i).completed) { + taskListModel.remove(i) + } + } + saveToStorage() + } + + // Get statistics + function getStats() { + let total = taskListModel.count + let completed = 0 + + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).completed) { + completed++ + } + } + + return { + "total": total, + "completed": completed, + "remaining": total - completed + } + } + + // Check if there are any completed tasks + function hasCompletedTasks() { + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).completed) { + return true + } + } + return false + } + + // Get item at index + function get(index) { + return taskListModel.get(index) + } + + // Generate a unique ID for tasks + function generateId() { + return Date.now() + Math.random().toString(36).substr(2, 9) + } + + // Storage utility functions + function clearAllData() { + storage.clearStorage() + taskListModel.clear() + } + + // Access to storage for dark mode preference + function saveDarkMode(darkMode) { + storage.saveDarkMode(darkMode) + } + + function loadDarkMode() { + return storage.loadDarkMode() + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/utils/TaskStorage.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/utils/TaskStorage.qml new file mode 100644 index 0000000..8cf2e23 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/utils/TaskStorage.qml @@ -0,0 +1,83 @@ +import QtQuick +import QtCore + +Item { + id: root + + // Signal emitted when tasks are loaded from storage + signal tasksLoaded(var tasks) + + // Settings component for persistent storage + Settings { + id: settings + category: "Tasks" + + // Store tasks as a JSON string + property string tasksData: "[]" + // Store dark mode preference + property bool darkMode: false + } + + // Save tasks to storage + function saveTasks(tasks) { + try { + // Convert ListModel data to a proper array + let taskArray = [] + for (let i = 0; i < tasks.count; i++) { + let task = tasks.get(i) + taskArray.push({ + id: task.id, + title: task.title, + completed: task.completed + }) + } + + // Save as JSON string + settings.tasksData = JSON.stringify(taskArray) + settings.sync() // Force immediate save + + console.log("Tasks saved to storage:", taskArray.length, "tasks") + } catch (error) { + console.error("Error saving tasks:", error) + } + } + + // Load tasks from storage + function loadTasks() { + try { + if (settings.tasksData && settings.tasksData !== "[]") { + let taskArray = JSON.parse(settings.tasksData) + console.log("Tasks loaded from storage:", taskArray.length, "tasks") + root.tasksLoaded(taskArray) + return taskArray + } else { + console.log("No saved tasks found, starting with empty list") + root.tasksLoaded([]) + return [] + } + } catch (error) { + console.error("Error loading tasks:", error) + root.tasksLoaded([]) + return [] + } + } + + // Save dark mode preference + function saveDarkMode(darkMode) { + settings.darkMode = darkMode + settings.sync() + } + + // Load dark mode preference + function loadDarkMode() { + return settings.darkMode + } + + // Clear all stored data + function clearStorage() { + settings.tasksData = "[]" + settings.darkMode = false + settings.sync() + console.log("Storage cleared") + } +} diff --git a/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/views/MainView.qml b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/views/MainView.qml new file mode 100644 index 0000000..7af9ae8 --- /dev/null +++ b/Qt6QMLBeginnersCode/13-Storage/6-TodolistStorage/src/views/MainView.qml @@ -0,0 +1,261 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + //Change 1 + // Task model - Using the dedicated TaskListModel + /* + TaskListModel { + id: taskModel + } + */ + + // Task model - Using the dedicated TaskListModel + TaskListModel { + id: taskModel + + // Connect to storage ready signal to load dark mode + onStorageInitialized: { + root.darkMode = loadDarkMode() + } + } + + // Save dark mode preference when changed + onDarkModeChanged: { + taskModel.saveDarkMode(darkMode) + } + + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + // Header + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + // Add task bar + AddTaskBar { + id: addTaskBar + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onTaskAdded: function(taskText) { + taskModel.addTask(taskText) + } + } + + // Tasks list + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: root.cardColor + radius: 12 + border.width: 1 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + + ScrollView { + anchors.fill: parent + anchors.margins: 1 + clip: true + + ListView { + id: taskListView + + //Change 2 + //model: taskModel + model: taskModel.model + spacing: 8 + anchors.margins: 12 + + + + // Add animation transitions + add: Transition { + NumberAnimation { + properties: "x" + from: 100; to: 0 + duration: 300 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 0; to: 1 + duration: 300 + } + } + + remove: Transition { + NumberAnimation { + properties: "x" + to: 100 + duration: 250 + easing.type: Easing.InCubic + } + NumberAnimation { + property: "opacity" + to: 0 + duration: 250 + } + } + + displaced: Transition { + NumberAnimation { + properties: "x,y" + duration: 200 + easing.type: Easing.OutQuad + } + } + + + + + + delegate: TaskItem { + required property int index + required property string title + required property bool completed + + width: taskListView.width + taskTitle: title + taskDone: completed + backgroundColor: root.cardColor + textColor: root.textColor + completedColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onToggleDone: { + taskModel.toggleTask(index) + } + + onDeleteTask: { + taskModel.deleteTask(index) + } + } + + // Empty state + Rectangle { + anchors.centerIn: parent + width: parent.width - 40 + height: 120 + color: "transparent" + visible: taskListView.count === 0 + opacity: taskListView.count === 0 ? 1.0 : 0.0 + + + Behavior on opacity { + NumberAnimation { duration: 400; easing.type: Easing.InOutQuad } + } + + Column { + anchors.centerIn: parent + spacing: 16 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: "📝" + font.pixelSize: 48 + opacity: 0.3 + + // Subtle floating animation + SequentialAnimation on y { + running: taskListView.count === 0 + loops: Animation.Infinite + NumberAnimation { from: 0; to: -5; duration: 1000; easing.type: Easing.InOutSine } + NumberAnimation { from: -5; to: 0; duration: 1000; easing.type: Easing.InOutSine } + } + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("No tasks yet") + color: root.completedColor + font.pixelSize: 18 + font.weight: Font.Medium + + // Gentle opacity breathing animation + SequentialAnimation on opacity { + running: taskListView.count === 0 + loops: Animation.Infinite + NumberAnimation { from: 0.7; to: 1.0; duration: 1500; easing.type: Easing.InOutSine } + NumberAnimation { from: 1.0; to: 0.7; duration: 1500; easing.type: Easing.InOutSine } + } + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Add a task above to get started") + color: root.completedColor + font.pixelSize: 14 + horizontalAlignment: Text.AlignHCenter + + // Gentle opacity breathing animation with slight delay + SequentialAnimation on opacity { + running: taskListView.count === 0 + loops: Animation.Infinite + PauseAnimation { duration: 300 } // Small delay for staggered effect + NumberAnimation { from: 0.6; to: 0.9; duration: 1500; easing.type: Easing.InOutSine } + NumberAnimation { from: 0.9; to: 0.6; duration: 1500; easing.type: Easing.InOutSine } + } + } + } + } + } + } + + + } + + // Task statistics at bottom + TaskStats { + id: taskStats + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + secondaryTextColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + totalTasks: taskModel.count + completedTasks: taskModel.getStats().completed + remainingTasks: taskModel.getStats().remaining + hasCompleted: taskModel.hasCompletedTasks() + + onClearCompleted: { + taskModel.clearCompletedTasks() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/CMakeLists.txt b/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/CMakeLists.txt new file mode 100644 index 0000000..b83c749 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(2-XmlHttpRequest VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app2-XmlHttpRequest + main.cpp +) + +qt_add_qml_module(app2-XmlHttpRequest + URI 2-XmlHttpRequest + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app2-XmlHttpRequest PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app2-XmlHttpRequest + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-XmlHttpRequest + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app2-XmlHttpRequest + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/Main.qml b/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/Main.qml new file mode 100644 index 0000000..1396ea6 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/Main.qml @@ -0,0 +1,99 @@ +import QtQuick +import QtQuick.Controls + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("XmlHttpRequest") + + //Process the data right away + /* + function downloadData(url){ + //Create the object + var xhr = new XMLHttpRequest() + + //Apply initial settings to the object + xhr.onreadystatechange = function(){ + //HEADERS_RECEIVED + //DONE + + if(xhr.readyState === XMLHttpRequest.HEADERS_RECEVED){ + console.log("Headers received") + }else if(xhr.readyState === XMLHttpRequest.DONE){ + if(xhr.status == 200){ + //console.log("Got the data from the server it is: " + xhr.responseText.toString()) + textAreaId.text = xhr.responseText.toString() + }else{ + console.log("Something went wrong") + } + + } + } + xhr.open("GET",url) + xhr.send() + } + */ + + //Go through a callback + function downloadData(url,callback){ + //Create the object + var xhr = new XMLHttpRequest() + + //Apply initial settings to the object + xhr.onreadystatechange = function(){ + //HEADERS_RECEIVED + //DONE + + if(xhr.readyState === XMLHttpRequest.HEADERS_RECEVED){ + console.log("Headers received") + }else if(xhr.readyState === XMLHttpRequest.DONE){ + if(xhr.status == 200){ + //console.log("Got the data from the server it is: " + xhr.responseText.toString()) + //textAreaId.text = xhr.responseText.toString() + callback(xhr.responseText.toString()) + }else{ + console.log("Something went wrong") + } + + } + } + xhr.open("GET",url) + xhr.send() + } + + TextArea{ + id: textAreaId + anchors.fill: parent + textFormat: TextArea.RichText + text: "Click to download html data" + + } + + MouseArea{ + anchors.fill: parent + onClicked: function(){ + /* + Urls to try : + . https://www.qt.io/ + . https://github.com/ + . https://jsonplaceholder.typicode.com/ + */ + //Download data right away + /* + console.log("Clicked") + downloadData("https://www.qt.io") + */ + + //Download the data through a callback + downloadData("https://jsonplaceholder.typicode.com/",function(response){ + if(response){ + textAreaId.text = response + }else{ + console.log("Something went wrong") + } + + }) + } + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/main.cpp b/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/main.cpp new file mode 100644 index 0000000..e6fe8fa --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/2-XmlHttpRequest/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/2-XmlHttpRequest/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/CMakeLists.txt b/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/CMakeLists.txt new file mode 100644 index 0000000..e6c5f6e --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.16) + +project(3-RestAPI VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.4 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup() + +qt_add_executable(app3-RestAPI + main.cpp +) + +qt_add_qml_module(app3-RestAPI + URI 3-RestAPI + VERSION 1.0 + QML_FILES Main.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(app3-RestAPI PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app3-RestAPI + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-RestAPI + PRIVATE Qt6::Quick +) + +include(GNUInstallDirs) +install(TARGETS app3-RestAPI + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/Main.qml b/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/Main.qml new file mode 100644 index 0000000..83c0dc4 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/Main.qml @@ -0,0 +1,106 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Rest API") + + function fetchData(url, callback) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) { + print('HEADERS_RECEIVED'); + } else if (xhr.readyState === XMLHttpRequest.DONE) { + print('DONE'); + if (xhr.status == 200) { + console.log("resource found" + xhr.responseText.toString()); + callback(xhr.responseText.toString()); + } else { + callback(null); + } + } + }; + xhr.open("GET", url); + xhr.send(); + } + + + ColumnLayout{ + anchors.fill: parent + spacing: 0 + + ListModel{ + id: listModelId + } + + ListView{ + id: listViewId + model: listModelId + delegate: delegateId + Layout.fillWidth: true + Layout.fillHeight: true + } + + Button{ + id: buttonId + Layout.fillWidth: true + text: "Fetch" + onClicked: function(){ + listModelId.clear() + + //Call the function to download data + fetchData("https://jsonplaceholder.typicode.com/users",function(response){ + + if(response){ + console.log("Response is good") + //Parse the data + var object = JSON.parse(response) + + //Loop over the JSON array + object.forEach(function(userdata){ + listModelId.append({ + "userdata": userdata.name + }) + }) + + }else{ + console.log("Something went wrong") + } + + + + }) + + } + + } + + Component { + id: delegateId + Rectangle { + id: rectangleId + width: parent.width + height: textId.implicitHeight + 30 + color: "beige" + border.color: "yellowgreen" + radius: 5 + + Text { + id: textId + width: parent.width + height: parent.height + anchors.centerIn: parent + text: userdata //Or modelData + //text: modelData + font.pointSize: 13 + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/main.cpp b/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/main.cpp new file mode 100644 index 0000000..c0e7e05 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/3-RestAPI/main.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + const QUrl url(u"qrc:/3-RestAPI/Main.qml"_qs); + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.load(url); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/.gitignore b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/.gitignore new file mode 100644 index 0000000..7803df3 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/.gitignore @@ -0,0 +1,57 @@ +# Qt QML Language Server configuration +qmlls.ini + +# Build directories +build/ +Desktop_Qt_6_9_0_MinGW_64_bit-Debug/ + +# Qt Creator user settings +CMakeLists.txt.user + +# Compiled Object files +*.o +*.obj + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Compiled Static libraries +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Qt-specific +*.qm +*.prl +*.pro.user +*.pro.user.* +*.qbs.user +*.qbs.user.* +*.moc +moc_*.cpp +moc_*.h +qrc_*.cpp +ui_*.h +Makefile* +*build-* + +# QML cache and compiled files +*.qmlc +*.jsc + +# Qt temporary files +*~ + +# macOS +.DS_Store + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini \ No newline at end of file diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/.qmlls.ini b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/.qmlls.ini new file mode 100644 index 0000000..b12c87d --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/.qmlls.ini @@ -0,0 +1,5 @@ +[General] +buildDir="D:/Sandbox/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/build" +no-cmake-calls=false +docDir=C:/Qt/Docs/Qt-6.9.0 +importPaths="C:/Qt/6.9.0/mingw_64/qml" diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/CMakeLists.txt b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/CMakeLists.txt new file mode 100644 index 0000000..b0a5b4d --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.16) + +project(TodoList VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.8) + +qt_add_executable(TodoList + src/main.cpp +) + +qt_add_qml_module(TodoList + URI TodoList + VERSION 1.0 + QML_FILES + # Main View + src/views/MainView.qml + + # Components + src/components/AppHeader.qml + src/components/AddTaskBar.qml + src/components/TaskItem.qml + src/components/TaskStats.qml + + # Models + src/models/TaskListModel.qml + + # Utils + src/utils/TaskStorage.qml + QML_FILES src/utils/RestStorage.qml +) + +# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. +# If you are developing for iOS or macOS you should consider setting an +# explicit, fixed bundle identifier manually though. +set_target_properties(TodoList PROPERTIES +# MACOSX_BUNDLE_GUI_IDENTIFIER com.example.app01_todolist_starter + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(TodoList + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +include(GNUInstallDirs) +install(TARGETS TodoList + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/AddTaskBar.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/AddTaskBar.qml new file mode 100644 index 0000000..72719d0 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/AddTaskBar.qml @@ -0,0 +1,110 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 60 + + signal taskAdded(string taskText) + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color primaryColor: "#007aff" + property bool darkMode: false + + Rectangle { + id: background + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 12 + spacing: 12 + + // Add icon + Rectangle { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + color: root.primaryColor + radius: 18 + + Text { + anchors.centerIn: parent + text: "+" + color: "#ffffff" + font.pixelSize: 20 + font.weight: Font.Bold + } + } + + // Text input + TextField { + id: taskInput + Layout.fillWidth: true + Layout.preferredHeight: 36 + placeholderText: qsTr("Add a new task...") + placeholderTextColor: root.darkMode ? "#888888" : "#999999" + color: root.textColor + font.pixelSize: 16 + selectByMouse: true + + background: Rectangle { + color: "transparent" + border.color: "transparent" + } + + Keys.onReturnPressed: root.addTask() + Keys.onEnterPressed: root.addTask() + + } + + // Add button + Button { + id: addButton + Layout.preferredWidth: 80 + Layout.preferredHeight: 36 + text: qsTr("Add") + enabled: taskInput.text.trim().length > 0 + + background: Rectangle { + color: addButton.enabled ? + (addButton.pressed ? Qt.darker(root.primaryColor, 1.2) : root.primaryColor) : + (root.darkMode ? "#404040" : "#e0e0e0") + radius: 8 + + } + + contentItem: Text { + text: addButton.text + color: addButton.enabled ? "#ffffff" : (root.darkMode ? "#888888" : "#cccccc") + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + } + + onClicked: root.addTask() + } + } + } + } + + function addTask() { + if (taskInput.text.trim().length > 0) { + root.taskAdded(taskInput.text.trim()) + taskInput.text = "" + taskInput.focus = false + } + } + +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/AppHeader.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/AppHeader.qml new file mode 100644 index 0000000..97f5e13 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/AppHeader.qml @@ -0,0 +1,86 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 80 + + signal toggleDarkMode() + + // Properties that will be bound from parent + property color textColor: "#333333" + property color textSecondary: "#999999" + property bool darkMode: false + + Rectangle { + anchors.fill: parent + color: "transparent" + + RowLayout{ + anchors.fill: parent + anchors.leftMargin: 8 + anchors.rightMargin: 8 + spacing: 12 + + // App icon + Text { + text: "📝" + font.pixelSize: 32 + } + + // App title and subtitle + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: "My Tasks" + font.pixelSize: 28 + font.weight: Font.Bold + color: root.textColor + } + + Text { + text: qsTr("Stay organized, stay productive") + font.pixelSize: 12 + color: root.textSecondary + opacity: 0.8 + } + + } + + // Dark mode toggle + Button { + id: themeToggle + Layout.preferredWidth: 50 + Layout.preferredHeight: 50 + + background: Rectangle { + color: themeToggle.pressed ? + (root.darkMode ? "#404040" : "#e0e0e0") : + (root.darkMode ? "#2d2d2d" : "#f5f5f5") + radius: 25 + border.color: root.darkMode ? "#555555" : "#d0d0d0" + border.width: 1 + + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text{ + text: root.darkMode ? "☀️" : "🌙" + font.pixelSize: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + //Emit the signal when the button is clicked + onClicked: root.toggleDarkMode() + + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/TaskItem.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/TaskItem.qml new file mode 100644 index 0000000..cfd5cee --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/TaskItem.qml @@ -0,0 +1,209 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: 56 + + required property string taskTitle + required property bool taskDone + + signal toggleDone() + signal deleteTask() + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color completedColor: "#999999" + property color primaryColor: "#007aff" + property bool darkMode: false + + // Constants for this component + readonly property int itemHeight: 56 + readonly property int margins: 4 + readonly property int innerMargins: 12 + readonly property int checkboxSize: 24 + readonly property int deleteButtonSize: 32 + + Rectangle { + id: taskItemBackground + anchors.fill: parent + color: "transparent" + + Rectangle { + id: itemBackground + anchors.fill: parent + anchors.margins: root.margins + color: root.backgroundColor + radius: 8 + border.color: root.taskDone ? "transparent" : (root.darkMode ? "#404040" : "#f0f0f0") + border.width: 1 + opacity: root.taskDone ? 0.7 : 1.0 + + scale: itemBackground.hovered ? 1.02 : 1.0 + + // Smooth transitions for background properties + Behavior on opacity { + NumberAnimation { duration: 300 } + } + + Behavior on border.color { + ColorAnimation { duration: 300 } + } + + Behavior on scale { + NumberAnimation { duration: 150; easing.type: Easing.OutQuad } + } + + RowLayout { + anchors.fill: parent + anchors.margins: root.innerMargins + spacing: 12 + + // Checkbox + Rectangle { + id: checkbox + Layout.preferredWidth: root.checkboxSize + Layout.preferredHeight: root.checkboxSize + color: root.taskDone ? root.primaryColor : "transparent" + border.color: root.taskDone ? root.primaryColor : (root.darkMode ? "#666666" : "#cccccc") + border.width: 2 + radius: 4 + + // Smooth transitions for checkbox state changes + Behavior on color { + ColorAnimation { duration: 200 } + } + + Behavior on border.color { + ColorAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 100; easing.type: Easing.OutBack } + } + + // Checkmark + Text { + anchors.centerIn: parent + text: "✓" + color: "#ffffff" + font.pixelSize: 16 + font.weight: Font.Bold + opacity: root.taskDone ? 1.0 : 0.0 + + scale: root.taskDone ? 1.0 : 0.3 + + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutBack } + } + + } + + MouseArea { + anchors.fill: parent + onClicked: { + // Add click animation + checkbox.scale = 0.9 + scaleResetTimer.restart() + + //Toggle the task + root.toggleDone() + } + cursorShape: Qt.PointingHandCursor + } + + // Timer to reset scale after click + Timer { + id: scaleResetTimer + interval: 100 + onTriggered: checkbox.scale = 1.0 + } + + } + + // Task text + Text { + id: taskText + Layout.fillWidth: true + text: root.taskTitle + color: root.taskDone ? root.completedColor : root.textColor + font.pixelSize: 16 + font.strikeout: root.taskDone + wrapMode: Text.WordWrap + + // Smooth color transition when task state changes + Behavior on color { + ColorAnimation { duration: 300 } + } + + // Subtle scale animation on completion + scale: root.taskDone ? 0.95 : 1.0 + Behavior on scale { + NumberAnimation { duration: 200; easing.type: Easing.OutQuad } + } + + MouseArea { + anchors.fill: parent + onClicked: root.toggleDone() + cursorShape: Qt.PointingHandCursor + } + } + + // Delete button + Button { + id: deleteButton + Layout.preferredWidth: root.deleteButtonSize + Layout.preferredHeight: root.deleteButtonSize + opacity: itemBackground.hovered ? 1.0 : 0.3 + scale: deleteButton.pressed ? 0.9 : 1.0 + + // Smooth transitions + Behavior on opacity { + NumberAnimation { duration: 200 } + } + + Behavior on scale { + NumberAnimation { duration: 100; easing.type: Easing.OutQuad } + } + + background: Rectangle { + color: deleteButton.pressed ? "#ff3b30" : "transparent" + radius: 16 + Behavior on color { + ColorAnimation { duration: 150 } + } + } + + contentItem: Text { + text: "🗑" + font.pixelSize: 16 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + rotation: deleteButton.pressed ? 15 : 0 + + Behavior on rotation { + NumberAnimation { duration: 100 } + } + } + + onClicked: { + root.deleteTask() + } + } + } + + // Hover effect + property bool hovered: false + + HoverHandler { + onHoveredChanged: itemBackground.hovered = hovered + } + } +} +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/TaskStats.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/TaskStats.qml new file mode 100644 index 0000000..6d3cde5 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/components/TaskStats.qml @@ -0,0 +1,95 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + height: visible ? 60 : 0 + visible: totalTasks > 0 + + property int totalTasks: 0 + property int completedTasks: 0 + property int remainingTasks: 0 + property bool hasCompleted: false + + property color backgroundColor: "#ffffff" + property color textColor: "#333333" + property color secondaryTextColor: "#666666" + property color primaryColor: "#007aff" + property color dangerColor: "#ff3b30" + property bool darkMode: false + + signal clearCompleted() + + Rectangle { + anchors.fill: parent + color: "transparent" + + Rectangle { + anchors.fill: parent + color: root.backgroundColor + radius: 12 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + border.width: 1 + + RowLayout { + anchors.fill: parent + anchors.margins: 16 + spacing: 16 + + // Statistics text + Column { + Layout.fillWidth: true + spacing: 2 + + Text { + text: root.totalTasks === 1 ? + qsTr("%1 task").arg(root.totalTasks) : + qsTr("%1 tasks").arg(root.totalTasks) + color: root.textColor + font.pixelSize: 16 + font.weight: Font.Medium + } + + Text { + text: root.completedTasks > 0 ? + qsTr("%1 completed, %2 remaining").arg(root.completedTasks).arg(root.remainingTasks) : + qsTr("No tasks completed yet") + color: root.secondaryTextColor + font.pixelSize: 14 + visible: root.totalTasks > 0 + } + } + + // Clear completed button + Button { + id: clearButton + Layout.preferredHeight: 36 + text: qsTr("Clear Completed") + visible: root.hasCompleted + enabled: root.hasCompleted + + background: Rectangle { + color: clearButton.pressed ? + Qt.darker(root.dangerColor, 1.2) : + (clearButton.hovered ? root.dangerColor : "transparent") + border.color: root.dangerColor + border.width: 1 + radius: 8 + } + + contentItem: Text { + text: clearButton.text + color: clearButton.hovered ? "#ffffff" : root.dangerColor + font.pixelSize: 14 + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + onClicked: root.clearCompleted() + } + } + } + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/main.cpp b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/main.cpp new file mode 100644 index 0000000..1038e99 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/main.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + // Set application identifiers for Settings + app.setOrganizationName("TodoApp"); + app.setOrganizationDomain("todoapp.local"); + app.setApplicationName("TodoList"); + + // Set Qt Quick Controls style to Basic to enable customization + QQuickStyle::setStyle("Basic"); + + // Print the settings location + QSettings settings; + qDebug() << "Settings location:" << settings.fileName(); + + QQmlApplicationEngine engine; + QObject::connect( + &engine, + &QQmlApplicationEngine::objectCreationFailed, + &app, + []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("TodoList", "MainView"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/models/TaskListModel.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/models/TaskListModel.qml new file mode 100644 index 0000000..aa1e589 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/models/TaskListModel.qml @@ -0,0 +1,198 @@ +import QtQuick + +Item { + id: root + + // Signal emitted when storage is initialized and ready + signal storageInitialized() + + // Signal emitted when settings are loaded + signal settingsLoaded(bool darkMode) + + // The actual ListModel for tasks + property alias model: taskListModel + property alias count: taskListModel.count + + ListModel { + id: taskListModel + } + + RestStorage{ + id: storage + + onTasksLoaded: function(tasks) { + root.loadTasksFromArray(tasks) + } + + + onTaskCreated: function(task) { + // Add the newly created task to the model - filter out unsupported fields + taskListModel.append({ + "id": task.id, + "title": task.title, + "completed": task.completed || false + // Note: We don't include createdAt, updatedAt as they're not needed in the UI + }) + } + + onTaskUpdated: function(task) { + // Update the task in the model - only update the fields we need + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).id === task.id) { + // Only set the properties that exist in our model + if (task.title !== undefined) { + taskListModel.setProperty(i, "title", task.title) + } + if (task.completed !== undefined) { + taskListModel.setProperty(i, "completed", task.completed) + } + break + } + } + } + + + onTaskDeleted: function(taskId) { + // Remove the task from the model + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).id === taskId) { + taskListModel.remove(i) + break + } + } + } + + onSettingsLoaded: function(settings) { + console.log("Settings loaded:", JSON.stringify(settings)) + // Emit signal with dark mode value + root.settingsLoaded(settings.darkMode || false) + } + + onSettingsUpdated: function(settings) { + console.log("Settings updated:", JSON.stringify(settings)) + // Settings have been successfully updated + } + + + Component.onCompleted: { + //Emit signal that storage is read + root.storageInitialized() + + //Load existing tasks from REST API + storage.loadTasks() + } + } + + + + // Load tasks from an array (used by storage) + function loadTasksFromArray(taskArray) { + taskListModel.clear() + for (let i = 0; i < taskArray.length; i++) { + let task = taskArray[i] + taskListModel.append({ + "id": task.id || generateId(), + "title": task.title || "", + "completed": task.completed || false + }) + } + } + + // Add a new task + function addTask(title) { + if (title && title.trim().length > 0) { + // Use REST API to create task + storage.createTask(title.trim()) + // The task will be added to the model via onTaskCreated signal + } + } + + // Toggle task completion status + function toggleTask(index) { + if (index >= 0 && index < taskListModel.count) { + + let task = taskListModel.get(index) + let newCompleted = !task.completed + + // Update via REST API + storage.updateTask(task.id, { completed: newCompleted }) + // The model will be updated via onTaskUpdated signal + } + } + + // Delete a task + function deleteTask(index) { + if (index >= 0 && index < taskListModel.count) { + + let task = taskListModel.get(index) + // Delete via REST API + storage.deleteTask(task.id) + // The task will be removed from the model via onTaskDeleted signal + } + } + + + + // Clear all completed tasks + function clearCompletedTasks() { + + // Get all completed task IDs and delete them via REST API + let completedTasks = [] + let i + for (i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).completed) { + completedTasks.push(taskListModel.get(i).id) + } + } + + // Delete each completed task via REST API + for (i = 0; i < completedTasks.length; i++) { + storage.deleteTask(completedTasks[i]) + } + // Tasks will be removed from the model via onTaskDeleted signals + } + + // Get statistics + function getStats() { + let total = taskListModel.count + let completed = 0 + + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).completed) { + completed++ + } + } + + return { + "total": total, + "completed": completed, + "remaining": total - completed + } + } + + // Check if there are any completed tasks + function hasCompletedTasks() { + for (let i = 0; i < taskListModel.count; i++) { + if (taskListModel.get(i).completed) { + return true + } + } + return false + } + + // Get item at index + function get(index) { + return taskListModel.get(index) + } + + + + // Access to storage for dark mode preference + function saveDarkMode(darkMode) { + storage.updateSettings({ darkMode: darkMode }) + } + + function loadDarkMode() { + storage.loadSettings() + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/utils/RestStorage.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/utils/RestStorage.qml new file mode 100644 index 0000000..09f4ee9 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/utils/RestStorage.qml @@ -0,0 +1,192 @@ +import QtQuick + +Item{ + id: root + + // Base URL for the REST API + readonly property string baseUrl: "http://localhost:3000" + + // Signals + signal tasksLoaded(var tasks) + signal taskCreated(var task) + signal taskUpdated(var task) + signal taskDeleted(string taskId) + signal settingsLoaded(var settings) + signal settingsUpdated(var settings) + signal error(string message) + + + Component.onCompleted: { + // Test connection on startup + checkConnection() + } + + // Check if API is available + function checkConnection() { + performRequest("GET", "/health", null, function(response) { + console.log("API connection established") + }, function(error) { + console.error("API connection failed:", error) + root.error("Cannot connect to API server at " + baseUrl) + }) + } + + // Load all tasks from the API + function loadTasks() { + performRequest("GET", "/api/tasks", null, function(response) { + try { + let data = JSON.parse(response) + let tasks = data.data || [] + console.log("Tasks loaded from API:", tasks.length, "tasks") + root.tasksLoaded(tasks) + } catch (e) { + console.error("Error parsing tasks response:", e) + root.error("Failed to parse tasks data") + } + }, function(error) { + console.error("Error loading tasks:", error) + root.error("Failed to load tasks from server") + }) + } + + // Create a new task + function createTask(title) { + if (!title || title.trim().length === 0) { + root.error("Task title cannot be empty") + return + } + + let taskData = { + title: title.trim() + } + + performRequest("POST", "/api/tasks", taskData, function(response) { + try { + let data = JSON.parse(response) + let task = data.data + console.log("Task created:", task.title) + root.taskCreated(task) + } catch (e) { + console.error("Error parsing create task response:", e) + root.error("Failed to parse server response") + } + }, function(error) { + console.error("Error creating task:", error) + root.error("Failed to create task") + }) + } + + // Update an existing task + function updateTask(taskId, updates) { + if (!taskId) { + root.error("Task ID is required for update") + return + } + + performRequest("PUT", "/api/tasks/" + taskId, updates, function(response) { + try { + let data = JSON.parse(response) + let task = data.data + console.log("Task updated:", task.id) + root.taskUpdated(task) + } catch (e) { + console.error("Error parsing update task response:", e) + root.error("Failed to parse server response") + } + }, function(error) { + console.error("Error updating task:", error) + root.error("Failed to update task") + }) + } + + // Delete a task + function deleteTask(taskId) { + if (!taskId) { + root.error("Task ID is required for deletion") + return + } + + performRequest("DELETE", "/api/tasks/" + taskId, null, function(response) { + console.log("Task deleted:", taskId) + root.taskDeleted(taskId) + }, function(error) { + console.error("Error deleting task:", error) + root.error("Failed to delete task") + }) + } + + // Load user settings + function loadSettings() { + performRequest("GET", "/api/settings", null, function(response) { + try { + let data = JSON.parse(response) + let settings = data.data + console.log("Settings loaded from API") + root.settingsLoaded(settings) + } catch (e) { + console.error("Error parsing settings response:", e) + root.error("Failed to parse settings data") + } + }, function(error) { + console.error("Error loading settings:", error) + root.error("Failed to load settings from server") + }) + } + + // Update user settings + function updateSettings(settings) { + performRequest("PUT", "/api/settings", settings, function(response) { + try { + let data = JSON.parse(response) + let updatedSettings = data.data + console.log("Settings updated") + root.settingsUpdated(updatedSettings) + } catch (e) { + console.error("Error parsing update settings response:", e) + root.error("Failed to parse server response") + } + }, function(error) { + console.error("Error updating settings:", error) + root.error("Failed to update settings") + }) + } + + + + // Generic HTTP request function + function performRequest(method, endpoint, data, successCallback, errorCallback) { + // Create XMLHttpRequest object + var xhr = new XMLHttpRequest() + let url = baseUrl + endpoint + + xhr.onreadystatechange = function() { + if (xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status >= 200 && xhr.status < 300) { + if (successCallback) { + successCallback(xhr.responseText) + } + } else { + let errorMessage = "HTTP " + xhr.status + try { + let errorData = JSON.parse(xhr.responseText) + errorMessage = errorData.error || errorMessage + } catch (e) { + // Use default error message + } + if (errorCallback) { + errorCallback(errorMessage) + } + } + } + } + + xhr.open(method, url, true) + xhr.setRequestHeader("Content-Type", "application/json") + + if (data) { + xhr.send(JSON.stringify(data)) + } else { + xhr.send() + } + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/utils/TaskStorage.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/utils/TaskStorage.qml new file mode 100644 index 0000000..8cf2e23 --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/utils/TaskStorage.qml @@ -0,0 +1,83 @@ +import QtQuick +import QtCore + +Item { + id: root + + // Signal emitted when tasks are loaded from storage + signal tasksLoaded(var tasks) + + // Settings component for persistent storage + Settings { + id: settings + category: "Tasks" + + // Store tasks as a JSON string + property string tasksData: "[]" + // Store dark mode preference + property bool darkMode: false + } + + // Save tasks to storage + function saveTasks(tasks) { + try { + // Convert ListModel data to a proper array + let taskArray = [] + for (let i = 0; i < tasks.count; i++) { + let task = tasks.get(i) + taskArray.push({ + id: task.id, + title: task.title, + completed: task.completed + }) + } + + // Save as JSON string + settings.tasksData = JSON.stringify(taskArray) + settings.sync() // Force immediate save + + console.log("Tasks saved to storage:", taskArray.length, "tasks") + } catch (error) { + console.error("Error saving tasks:", error) + } + } + + // Load tasks from storage + function loadTasks() { + try { + if (settings.tasksData && settings.tasksData !== "[]") { + let taskArray = JSON.parse(settings.tasksData) + console.log("Tasks loaded from storage:", taskArray.length, "tasks") + root.tasksLoaded(taskArray) + return taskArray + } else { + console.log("No saved tasks found, starting with empty list") + root.tasksLoaded([]) + return [] + } + } catch (error) { + console.error("Error loading tasks:", error) + root.tasksLoaded([]) + return [] + } + } + + // Save dark mode preference + function saveDarkMode(darkMode) { + settings.darkMode = darkMode + settings.sync() + } + + // Load dark mode preference + function loadDarkMode() { + return settings.darkMode + } + + // Clear all stored data + function clearStorage() { + settings.tasksData = "[]" + settings.darkMode = false + settings.sync() + console.log("Storage cleared") + } +} diff --git a/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/views/MainView.qml b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/views/MainView.qml new file mode 100644 index 0000000..058a20c --- /dev/null +++ b/Qt6QMLBeginnersCode/14-Networking/4-TodolistNetworking/src/views/MainView.qml @@ -0,0 +1,274 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + width: 400 + height: 700 + visible: true + title: qsTr("My Tasks") + + + property bool isInitializing: true + + // Theme properties + property bool darkMode: false + property color backgroundColor: darkMode ? "#1e1e1e" : "#f0f2f5" + property color primaryColor: "#007aff" + property color textColor: darkMode ? "#ffffff" : "#333333" + property color cardColor: darkMode ? "#2d2d2d" : "#ffffff" + property color completedColor: darkMode ? "#666666" : "#999999" + + //Change 1 + // Task model - Using the dedicated TaskListModel + /* + TaskListModel { + id: taskModel + } + */ + + // Task model - Using the dedicated TaskListModel + TaskListModel { + id: taskModel + + // Connect to storage ready signal to load dark mode + onStorageInitialized: { + loadDarkMode() + } + + // Handle settings loaded from REST API + onSettingsLoaded: function(darkModeValue) { + console.log("Dark mode loaded from API:", darkModeValue) + root.darkMode = darkModeValue + root.isInitializing = false + } + + } + + // Save dark mode preference when changed + onDarkModeChanged: { + if(!root.isInitializing){ + taskModel.saveDarkMode(darkMode) + } + } + + + // Background + Rectangle { + anchors.fill: parent + color: root.backgroundColor + } + + //The components of the ui + ColumnLayout { + anchors.fill: parent + anchors.margins: 20 + spacing: 20 + + // Header + AppHeader { + id: header + Layout.fillWidth: true + textColor: root.textColor + textSecondary: root.completedColor + darkMode: root.darkMode + onToggleDarkMode: root.darkMode = !root.darkMode + } + + // Add task bar + AddTaskBar { + id: addTaskBar + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onTaskAdded: function(taskText) { + taskModel.addTask(taskText) + } + } + + // Tasks list + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + color: root.cardColor + radius: 12 + border.width: 1 + border.color: root.darkMode ? "#404040" : "#e0e0e0" + + ScrollView { + anchors.fill: parent + anchors.margins: 1 + clip: true + + ListView { + id: taskListView + + //Change 2 + //model: taskModel + model: taskModel.model + spacing: 8 + anchors.margins: 12 + + + + // Add animation transitions + add: Transition { + NumberAnimation { + properties: "x" + from: 100; to: 0 + duration: 300 + easing.type: Easing.OutCubic + } + NumberAnimation { + property: "opacity" + from: 0; to: 1 + duration: 300 + } + } + + remove: Transition { + NumberAnimation { + properties: "x" + to: 100 + duration: 250 + easing.type: Easing.InCubic + } + NumberAnimation { + property: "opacity" + to: 0 + duration: 250 + } + } + + displaced: Transition { + NumberAnimation { + properties: "x,y" + duration: 200 + easing.type: Easing.OutQuad + } + } + + + + + + delegate: TaskItem { + required property int index + required property string title + required property bool completed + + width: taskListView.width + taskTitle: title + taskDone: completed + backgroundColor: root.cardColor + textColor: root.textColor + completedColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + + onToggleDone: { + taskModel.toggleTask(index) + } + + onDeleteTask: { + taskModel.deleteTask(index) + } + } + + // Empty state + Rectangle { + anchors.centerIn: parent + width: parent.width - 40 + height: 120 + color: "transparent" + visible: taskListView.count === 0 + opacity: taskListView.count === 0 ? 1.0 : 0.0 + + + Behavior on opacity { + NumberAnimation { duration: 400; easing.type: Easing.InOutQuad } + } + + Column { + anchors.centerIn: parent + spacing: 16 + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: "📝" + font.pixelSize: 48 + opacity: 0.3 + + // Subtle floating animation + SequentialAnimation on y { + running: taskListView.count === 0 + loops: Animation.Infinite + NumberAnimation { from: 0; to: -5; duration: 1000; easing.type: Easing.InOutSine } + NumberAnimation { from: -5; to: 0; duration: 1000; easing.type: Easing.InOutSine } + } + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("No tasks yet") + color: root.completedColor + font.pixelSize: 18 + font.weight: Font.Medium + + // Gentle opacity breathing animation + SequentialAnimation on opacity { + running: taskListView.count === 0 + loops: Animation.Infinite + NumberAnimation { from: 0.7; to: 1.0; duration: 1500; easing.type: Easing.InOutSine } + NumberAnimation { from: 1.0; to: 0.7; duration: 1500; easing.type: Easing.InOutSine } + } + } + + Text { + anchors.horizontalCenter: parent.horizontalCenter + text: qsTr("Add a task above to get started") + color: root.completedColor + font.pixelSize: 14 + horizontalAlignment: Text.AlignHCenter + + // Gentle opacity breathing animation with slight delay + SequentialAnimation on opacity { + running: taskListView.count === 0 + loops: Animation.Infinite + PauseAnimation { duration: 300 } // Small delay for staggered effect + NumberAnimation { from: 0.6; to: 0.9; duration: 1500; easing.type: Easing.InOutSine } + NumberAnimation { from: 0.9; to: 0.6; duration: 1500; easing.type: Easing.InOutSine } + } + } + } + } + } + } + + + } + + // Task statistics at bottom + TaskStats { + id: taskStats + Layout.fillWidth: true + backgroundColor: root.cardColor + textColor: root.textColor + secondaryTextColor: root.completedColor + primaryColor: root.primaryColor + darkMode: root.darkMode + totalTasks: taskModel.count + completedTasks: taskModel.getStats().completed + remainingTasks: taskModel.getStats().remaining + hasCompleted: taskModel.hasCompletedTasks() + + onClearCompleted: { + taskModel.clearCompletedTasks() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/CMakeLists.txt b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/CMakeLists.txt new file mode 100644 index 0000000..2a277d3 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(1-SyntaxOverview VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app1-SyntaxOverview + main.cpp +) + +qt_add_qml_module(app1-SyntaxOverview + URI 1-SyntaxOverview + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app1-SyntaxOverview PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app1-SyntaxOverview + PRIVATE Qt6::Quick +) + +install(TARGETS app1-SyntaxOverview + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/Main.qml b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/Main.qml new file mode 100644 index 0000000..d4532c8 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/Main.qml @@ -0,0 +1,82 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + id: rootId + visible: true + width: 640 + height: 480 + title: qsTr("QML Syntax Demo") + + property string textToShow: "hello" + + Row { + id: row1 + anchors.centerIn: parent + spacing: 20 + + Rectangle { + id: redRectId + width: 100; height: 100 + color: "red" + radius: 20 + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on the red rectangle") + textToShow = "red" + } + } + } + + Rectangle { + id: greenRectId + width: 100; height: 100 + color: "green" + radius: 20 + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on the green rectangle") + textToShow = "green" + } + } + } + + Rectangle { + id: blueRectId + width: 100; height: 100 + color: "blue" + radius: 20 + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on the blue rectangle") + textToShow = "blue" + } + } + } + + Rectangle { + id: textRectId + width: 100; height: 100 + color: "dodgerblue" + radius: 100 + Text { + id: textId + anchors.centerIn: parent + text: textToShow + } + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on the dodgerblue rectangle") + textId.text = "broken" + } + } + } + } +} + diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/main.cpp b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/main.cpp new file mode 100644 index 0000000..007e6b6 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/1-SyntaxOverview/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("1-SyntaxOverview", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/CMakeLists.txt b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/CMakeLists.txt new file mode 100644 index 0000000..c325c89 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-ExploringDataTypes VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-ExploringDataTypes + main.cpp +) + +qt_add_qml_module(app2-ExploringDataTypes + URI 2-ExploringDataTypes + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-ExploringDataTypes PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-ExploringDataTypes + PRIVATE Qt6::Quick +) + +install(TARGETS app2-ExploringDataTypes + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/Main.qml b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/Main.qml new file mode 100644 index 0000000..920a439 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/Main.qml @@ -0,0 +1,101 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("QML Datatypes Demo") + + property string mString: "https://www.learnqt.guide" + property int mInt: 45 + property bool isFemale: true + property double mDouble: 77.5 + property url mUrl: "https://www.learnqt.guide" + + property var aNumber: 100 + property var aBool: false + property var aString: "Hello world!" + property var anotherString: String("#FF008800") + property var aColor: Qt.rgba(0.2, 0.3, 0.4, 0.5) + property var aRect: Qt.rect(10, 10, 10, 10) + property var aPoint: Qt.point(10, 10) + property var aSize: Qt.size(10, 10) + property var aVector3d: Qt.vector3d(100, 100, 100) + property var anArray: [1, 2, 3, "four", "five", (function() { return "six"; })] + property var anObject: { "foo": 10, "bar": 20 } + property var aFunction: (function() { return "one"; }) + + property var aFont: Qt.font({family: "Consolas", pointSize: 30, bold: false}) + property date mDate: "2018-07-19" + + Rectangle { + width: 200 + height: 100 + mInt + anchors.centerIn: parent + color: aColor + + Text { + id: mTextId + anchors.centerIn: parent + text: mString + font.bold: isFemale ? true : false + //font: aFont + } + } + + Component.onCompleted: { + //console.log("The value of mString is: " + mString) + print("The value of mString is: " + mString) + console.log("The value of mInt is: " + mInt) + + if (isFemale) { + console.log("You may wear a dress") + } else { + console.log("You may wear a suit") + } + console.log("The value of mDouble is: " + mDouble) + console.log("The value of mUrl is: " + mUrl) + + if (mString == mUrl) { + console.log("They are the same") + } else { + console.log("They are NOT the same") + } + + console.log("-----------------Playing with var datatype---------------") + console.log("The value of aNumber is: " + aNumber) + console.log("The value of aBool is: " + aBool) + console.log("The value of aString is: " + aString) + console.log("The value of anotherString is: " + anotherString) + + console.log("The components of aRect are x:" + aRect.x + ", y:" + aRect.y + ", width:" + aRect.width + ", height:" + aRect.height) + + console.log("The length of the array is: " + anArray.length) + + /* + anArray.forEach(function(value,index){ + if( index ===5){ + console.log(value()) + }else + { + console.log(value) + }}) + */ + + for (var i = 0; i < anArray.length; i++) { + if (i === 5) { + console.log(anArray[i]()) + } else { + console.log(anArray[i]) + } + } + + console.log("The date is: " + mDate) + + console.log("The function value is: " + aFunction()) + } +} + diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/main.cpp b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/main.cpp new file mode 100644 index 0000000..ce8d956 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/2-ExploringDataTypes/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-ExploringDataTypes", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/CMakeLists.txt b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/CMakeLists.txt new file mode 100644 index 0000000..58b1823 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-PropertyBinding VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-PropertyBinding + main.cpp +) + +qt_add_qml_module(app3-PropertyBinding + URI 3-PropertyBinding + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-PropertyBinding PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-PropertyBinding + PRIVATE Qt6::Quick +) + +install(TARGETS app3-PropertyBinding + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/Main.qml b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/Main.qml new file mode 100644 index 0000000..c2f59d0 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/Main.qml @@ -0,0 +1,54 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Property Binding Demo") + + Rectangle { + id: redRectId + width: 50 + height: width * 1.5 + color: "red" + } + + Rectangle { + id: blueRectId + color: "blue" + width: 100 + height: 100 + anchors.bottom: parent.bottom + + MouseArea { + anchors.fill: parent + onClicked: { + redRectId.width = redRectId.width + 10 + } + } + } + + Rectangle { + id: greenRectId + color: "green" + width: 100 + height: 100 + anchors.bottom: parent.bottom + anchors.left: blueRectId.right + + MouseArea { + anchors.fill: parent + onClicked: { + //redRectId.height = 100 // Doesn't work + //redRectId.height = redRectId.width * 1.5 // Doesn't work either + + redRectId.height = Qt.binding(function() { + return redRectId.width * 2 + }) + } + } + } +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/main.cpp b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/main.cpp new file mode 100644 index 0000000..1fdb64e --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/3-PropertyBinding/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-PropertyBinding", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/CMakeLists.txt b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/CMakeLists.txt new file mode 100644 index 0000000..85dac8f --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-QtGlobalObject VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-QtGlobalObject + main.cpp +) + +qt_add_qml_module(app4-QtGlobalObject + URI 4-QtGlobalObject + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-QtGlobalObject PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-QtGlobalObject + PRIVATE Qt6::Quick +) + +install(TARGETS app4-QtGlobalObject + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/Main.qml b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/Main.qml new file mode 100644 index 0000000..7a5620b --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/Main.qml @@ -0,0 +1,51 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Qt Global Object Demo") + + property var fonts: Qt.fontFamilies() + + Rectangle { + width: 300 + height: 100 + color: "red" + anchors.centerIn: parent + MouseArea { + anchors.fill: parent + onClicked: { + //Quit the application + /* + console.log("Quitting the App") + Qt.quit() + + //List the available fonts + for (var i = 0; i < fonts.length; i++) { + console.log("[" + i + "] :" + fonts[i]) + } + */ + + /* + //Hash a string + var mName = "Daniel Gakwaya" + var mNameHash = Qt.md5(mName) + console.log("The hash of the name is: " + mNameHash) + + //Open url externally + Qt.openUrlExternally("https://www.learnqt.guide/udemy-discounted-9/") + + //Open local files with the default program + Qt.openUrlExternally("file:///D:/artwork/LearnQt.png") + */ + + //Capture platform info + console.log("The current platform is: " + Qt.platform.os) + } + } + } +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/main.cpp b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/main.cpp new file mode 100644 index 0000000..21152a3 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/4-QtGlobalObject/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-QtGlobalObject", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/CMakeLists.txt b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/CMakeLists.txt new file mode 100644 index 0000000..522bd73 --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-PropertyHandlers VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-PropertyHandlers + main.cpp +) + +qt_add_qml_module(app5-PropertyHandlers + URI 5-PropertyHandlers + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-PropertyHandlers PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-PropertyHandlers + PRIVATE Qt6::Quick +) + +install(TARGETS app5-PropertyHandlers + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/Main.qml b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/Main.qml new file mode 100644 index 0000000..36ee2ce --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/Main.qml @@ -0,0 +1,40 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + id: rootId + visible: true + width: 640 + height: 480 + title: qsTr("Properties and Handlers Demo") + + property string firstName: "Daniel" + onFirstNameChanged: { + console.log("The firstname changed to: " + firstName) + } + + onTitleChanged: { + console.log("The new title is: " + rootId.title) + } + + Rectangle { + width: 300 + height: 100 + color: "greenyellow" + anchors.centerIn: parent + + MouseArea { + anchors.fill: parent + onClicked: { + firstName = "John" + rootId.title = "The sky is blue" + } + } + } + + Component.onCompleted: { + console.log("The firstname is: " + firstName) + } +} diff --git a/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/main.cpp b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/main.cpp new file mode 100644 index 0000000..ae21bad --- /dev/null +++ b/Qt6QMLBeginnersCode/2.DissectingQmlSyntax/5-PropertyHandlers/main.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-PropertyHandlers", "Main"); + + return app.exec(); + +} diff --git a/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/CMakeLists.txt b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/CMakeLists.txt new file mode 100644 index 0000000..0418dfb --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(1-RectangleItemText VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app1-RectangleItemText + main.cpp resource.qrc +) + +qt_add_qml_module(app1-RectangleItemText + URI 1-RectangleItemText + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app1-RectangleItemText PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app1-RectangleItemText + PRIVATE Qt6::Quick +) + +install(TARGETS app1-RectangleItemText + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/Main.qml b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/Main.qml new file mode 100644 index 0000000..7a53b49 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/Main.qml @@ -0,0 +1,124 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("QML Basic Elements Demo") + + Item { + id: containerItemId + x: 50; y: 50 + width: 400 + height: 200 + + Rectangle { + anchors.fill: parent + color: "beige" + + /* + //Grouped Property Syntax Variation #1 + border.color: "black" + border.width: 5 + */ + + //Grouped Property Syntax Variation #2 + /* + border { + color: "black" + width: 5 + } + */ + + //Grouped Property Syntax Variation #3 + border { + color: "black" + //width: 5 + } + } + + Rectangle { + x: 0 + y: 10 + width: 50 + height: 50 + color: "red" + MouseArea { + anchors.fill: parent + onClicked: { + + } + } + } + + Rectangle { + x: 60 + y: 10 + width: 50 + height: 50 + color: "green" + MouseArea { + anchors.fill: parent + onClicked: { + + } + } + } + + + Rectangle { + x: 120 + y: 10 + width: 50 + height: 50 + color: "blue" + MouseArea { + anchors.fill: parent + onClicked: { + + } + } + } + + Rectangle { + x: 180 + y: 10 + width: 50 + height: 50 + color: "magenta" + MouseArea { + anchors.fill: parent + onClicked: { + + } + } + } + + + Text { + x: 100 + y: 100 + id: mTextId + text: "Hello World!" + //font.family: "Helvetica"; font.pointSize: 13; font.bold: true + + /* + font { + family: "Helvetica" + pointSize: 13 + bold: true + } + */ + + font { + family: "Helvetica"; pointSize: 13; bold: true + } + + color: "red" + } + + } +} diff --git a/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/images/LearnQt.png b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/images/LearnQt.png new file mode 100644 index 0000000..27549e4 Binary files /dev/null and b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/images/LearnQt.png differ diff --git a/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/main.cpp b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/main.cpp new file mode 100644 index 0000000..c5ff1ef --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("1-RectangleItemText", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/resource.qrc b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/resource.qrc new file mode 100644 index 0000000..10db962 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/1-RectangleItemText/resource.qrc @@ -0,0 +1,5 @@ + + + images/LearnQt.png + + diff --git a/Qt6QMLBeginnersCode/3.BasicElements/2-Image/CMakeLists.txt b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/CMakeLists.txt new file mode 100644 index 0000000..654f574 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-Image VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-Image + main.cpp resource.qrc +) + +qt_add_qml_module(app2-Image + URI 2-Image + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-Image PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-Image + PRIVATE Qt6::Quick +) + +install(TARGETS app2-Image + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/3.BasicElements/2-Image/Main.qml b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/Main.qml new file mode 100644 index 0000000..e91c127 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/Main.qml @@ -0,0 +1,78 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("QML Basic Elements Demo") + + Item { + id: containerItemId + x: 150; y: 50 + width: 600 + height: 300 + + Image { + x: 10 + y: 50 + width: 100 + height: 100 + //Loading image from the working directory + source: "file:LearnQt.png" + } + + Image { + x: 150 + y: 50 + width: 100 + height: 100 + //Loading image from the resource file + source: "qrc:/images/LearnQt.png" + } + + //Load image from a full path + Image { + x: 300 + y: 50 + width: 100 + height: 100 + //Specify the full path to the image + source: "file:///D:/Artwork/LearnQt.png" + } + + Image { + x: 450 + y: 50 + width: 100 + height: 100 + //Specify the full web path to the image + source: "https://www.learnqt.guide/images/qt_gui_intermediate.png" + } + } +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Qt6QMLBeginnersCode/3.BasicElements/2-Image/images/LearnQt.png b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/images/LearnQt.png new file mode 100644 index 0000000..27549e4 Binary files /dev/null and b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/images/LearnQt.png differ diff --git a/Qt6QMLBeginnersCode/3.BasicElements/2-Image/main.cpp b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/main.cpp new file mode 100644 index 0000000..b4eed8f --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-Image", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/3.BasicElements/2-Image/resource.qrc b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/resource.qrc new file mode 100644 index 0000000..10db962 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/2-Image/resource.qrc @@ -0,0 +1,5 @@ + + + images/LearnQt.png + + diff --git a/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/CMakeLists.txt b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/CMakeLists.txt new file mode 100644 index 0000000..083a4a1 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-CustomComponents VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-CustomComponents + main.cpp +) + +qt_add_qml_module(app3-CustomComponents + URI 3-CustomComponents + VERSION 1.0 + QML_FILES Main.qml MButton.qml +) + +set_target_properties(app3-CustomComponents PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-CustomComponents + PRIVATE Qt6::Quick +) + +install(TARGETS app3-CustomComponents + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/MButton.qml b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/MButton.qml new file mode 100644 index 0000000..8eabda9 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/MButton.qml @@ -0,0 +1,54 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Item { + id: rootId + property alias buttonText: buttonTextId.text + width: containerRectId.width + height: containerRectId.height + signal buttonClicked + + Rectangle { + id: containerRectId + width: buttonTextId.implicitWidth + 20 + height: buttonTextId.implicitHeight + 20 + color: "red" + border { color: "blue"; width : 3} + + Text { + id: buttonTextId + text: "Button" + anchors.centerIn: parent + onTextChanged: { + console.log("Text changed to "+ buttonTextId.text) + } + } + + MouseArea { + anchors.fill: parent + onClicked: { + //console.log("Clicked on :"+ buttonTextId.text) + rootId.buttonClicked() + } + } + } + +} + + + + + + + + + + + + + + + + diff --git a/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/Main.qml b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/Main.qml new file mode 100644 index 0000000..fd9f96e --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/Main.qml @@ -0,0 +1,87 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Custom Components Demo") + + //You can change Column to Row to have rectangles laid out horizontally + /* + Column { + spacing: 20 + Rectangle { + width: 300 + height: 100 + color: "red" + } + Rectangle { + width: 300 + height: 100 + color: "blue" + } + } + */ + + /* + //Button code living in the main.qml file + Rectangle { + id: containerRectId + color: "red" + border { + color: "blue" + width: 3 + } + + //The width and height of the rectangle depend on the dimensions of the text in buttonTextId + width: buttonTextId.implicitWidth + 20 + height: buttonTextId.implicitHeight + 20 + + Text { + id: buttonTextId + text: "Button" + anchors.centerIn: parent + } + MouseArea { + anchors.fill: parent + onClicked: { + console.log("Clicked on the button") + } + } + } + */ + + + /* + MButton { + id: button1 + buttonText: "Button1" + } + MButton { + id: button2 + buttonText: "Button2" + anchors.top: button1.bottom + } + */ + + Column { + MButton { + buttonText: "Button1" + onButtonClicked: { + console.log("Clicked on button1") + } + + } + MButton { + buttonText: "Button2" + onButtonClicked: { + console.log("clicked on button2") + } + } + } + +} + diff --git a/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/main.cpp b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/main.cpp new file mode 100644 index 0000000..e5cdb18 --- /dev/null +++ b/Qt6QMLBeginnersCode/3.BasicElements/3-CustomComponents/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-CustomComponents", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/CMakeLists.txt new file mode 100644 index 0000000..5a05527 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(1-SignalHandlers VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app1-SignalHandlers + main.cpp +) + +qt_add_qml_module(app1-SignalHandlers + URI 1-SignalHandlers + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app1-SignalHandlers PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app1-SignalHandlers + PRIVATE Qt6::Quick +) + +install(TARGETS app1-SignalHandlers + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/Main.qml new file mode 100644 index 0000000..a0e62d2 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/Main.qml @@ -0,0 +1,43 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Signal Handlers") + + Rectangle { + id: rect + width: 150 + height: 150 + color: "red" + + MouseArea { + anchors.fill: parent + //hoverEnabled: true + + onClicked: { + console.log("Clicked on the rect") + } + + onDoubleClicked: { + console.log("Double clicked on the rect") + } + + onEntered: { + console.log("You're in!") + } + + onExited: { + console.log("You're out!") + } + + onWheel: function(wheel) { + console.log("Wheel: " + wheel.x) + } + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/main.cpp new file mode 100644 index 0000000..381470b --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/1-SignalHandlers/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("1-SignalHandlers", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/CMakeLists.txt new file mode 100644 index 0000000..4e5f797 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(10-MultipleSignalParameters VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app10-MultipleSignalParameters + main.cpp +) + +qt_add_qml_module(app10-MultipleSignalParameters + URI 10-MultipleSignalParameters + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app10-MultipleSignalParameters PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app10-MultipleSignalParameters + PRIVATE Qt6::Quick +) + +install(TARGETS app10-MultipleSignalParameters + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/Main.qml new file mode 100644 index 0000000..0bc780b --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/Main.qml @@ -0,0 +1,56 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Multiple Signal Parameters") + + signal info(string last_name,string first_name,int age) + + //Handle all three parameters + onInfo: function(l,f,a){ + print("last name: " + l + ", first name: " + f +", age: "+ a) + } + + //Only handle the first two + /* + onInfo: function(l,f){ + print("last name: " + l + ", first name: " + f) + } + */ + //Only handle the first one + /* + onInfo: function(l){ + print("last name: " +l) + } + */ + //Can only omit trailling parameters. Can't only ignore last name + /* + onInfo: function(f,a){ + print(" first name: " + f +", age: "+ a) + } + */ + //Non trailling parameters can be ignored through some hack + /* + onInfo: function(_,f,a){ + print(" first name: " + f +", age: "+ a) + } + */ + Rectangle{ + id: rectId + width: 300; + height: 300 + color: "blue" + + MouseArea{ + anchors.fill: parent + onClicked: { + info("John", "Snow", 33) + } + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/main.cpp new file mode 100644 index 0000000..7107b35 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/10-MultipleSignalParameters/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("10-MultipleSignalParameters", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/CMakeLists.txt new file mode 100644 index 0000000..1857949 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-SignalParameters VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-SignalParameters + main.cpp +) + +qt_add_qml_module(app2-SignalParameters + URI 2-SignalParameters + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-SignalParameters PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-SignalParameters + PRIVATE Qt6::Quick +) + +install(TARGETS app2-SignalParameters + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/Main.qml new file mode 100644 index 0000000..9c12c50 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/Main.qml @@ -0,0 +1,40 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Signal Parameters") + + Rectangle{ + id: rect + width: 150 + height: 150 + color: "red" + + MouseArea{ + anchors.fill: parent + + /* + onClicked: { + //Deprecated + console.log(mouse.x) + } + */ + + //Explicit Javascript function + /* + onClicked: function(mouse_param){ + console.log(mouse_param.x) + } + */ + + //Arrow function + onClicked: (mouse_param) => console.log(mouse_param.x) + + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/main.cpp new file mode 100644 index 0000000..2c54f05 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/2-SignalParameters/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-SignalParameters", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/CMakeLists.txt new file mode 100644 index 0000000..ba9d5e4 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-PropertChangeSignals VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-PropertChangeSignals + main.cpp +) + +qt_add_qml_module(app3-PropertChangeSignals + URI 3-PropertChangeSignals + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-PropertChangeSignals PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-PropertChangeSignals + PRIVATE Qt6::Quick +) + +install(TARGETS app3-PropertChangeSignals + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/Main.qml new file mode 100644 index 0000000..f02ce23 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/Main.qml @@ -0,0 +1,47 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Property change handlers") + + Rectangle { + id: rect + width: 300 + height: width + color: "dodgerblue" + + property string description: "A rectangle to play with" + + onWidthChanged: function() { + console.log("Width changed to: " + rect.width) + } + + onHeightChanged: function() { + console.log("Height changed to: " + rect.height) + } + + onColorChanged: { + + } + + onVisibleChanged: { + + } + + onDescriptionChanged: { + + } + + MouseArea { + anchors.fill: parent + onClicked: { + rect.width = rect.width + 20 + } + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/main.cpp new file mode 100644 index 0000000..5846ee5 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/3-PropertChangeSignals/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-PropertChangeSignals", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/CMakeLists.txt new file mode 100644 index 0000000..83fe121 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-Connections VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-Connections + main.cpp +) + +qt_add_qml_module(app4-Connections + URI 4-Connections + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-Connections PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-Connections + PRIVATE Qt6::Quick +) + +install(TARGETS app4-Connections + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/Main.qml new file mode 100644 index 0000000..3ac00ba --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/Main.qml @@ -0,0 +1,33 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQml +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Connections") + + Rectangle{ + id: rectId + width : 200 + height: 200 + color: "blue" + + MouseArea{ + id:mouseAreaId + anchors.fill: parent + } + } + + Connections { + target : mouseAreaId + function onClicked(){ + console.log("Hello") + } + function onDoubleClicked(mouse){ + console.log("Doubleclicked at: "+mouse.x) + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/main.cpp new file mode 100644 index 0000000..64983f1 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/4-Connections/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-Connections", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/CMakeLists.txt new file mode 100644 index 0000000..932b5fd --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-AttachedSignalHandlers VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-AttachedSignalHandlers + main.cpp +) + +qt_add_qml_module(app5-AttachedSignalHandlers + URI 5-AttachedSignalHandlers + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-AttachedSignalHandlers PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-AttachedSignalHandlers + PRIVATE Qt6::Quick +) + +install(TARGETS app5-AttachedSignalHandlers + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/Main.qml new file mode 100644 index 0000000..3b5a527 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/Main.qml @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Attached signal handlers") + + Rectangle{ + width : 200 + height: 200 + color : "green" + anchors.left: parent.left + + Component.onCompleted: { + console.log("Finished setting up the rectangle") + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/main.cpp new file mode 100644 index 0000000..02ea8e4 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/5-AttachedSignalHandlers/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-AttachedSignalHandlers", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/CMakeLists.txt new file mode 100644 index 0000000..619252b --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-CustomSignals VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-CustomSignals + main.cpp +) + +qt_add_qml_module(app6-CustomSignals + URI 6-CustomSignals + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app6-CustomSignals PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-CustomSignals + PRIVATE Qt6::Quick +) + +install(TARGETS app6-CustomSignals + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/Main.qml new file mode 100644 index 0000000..2bed712 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/Main.qml @@ -0,0 +1,36 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Custom Signals") + + Rectangle{ + id: rectId + width : 300 + height: 300 + color: "dodgerblue" + + //Set up the signal + signal greet(string message) + + //Once you set up the signal, Qt setup a signal handler automatically + onGreet: function(message){ + console.log("Greeting with message: "+ message) + } + + MouseArea{ + anchors.fill: parent + onClicked: { + //Fire the signal by just calling it like a function + rectId.greet("The sky is blue") + } + } + } + + +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/main.cpp new file mode 100644 index 0000000..b5e573c --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/6-CustomSignals/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-CustomSignals", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/CMakeLists.txt new file mode 100644 index 0000000..6e912bb --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(7-ConnectSignalToMethod VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app7-ConnectSignalToMethod + main.cpp +) + +qt_add_qml_module(app7-ConnectSignalToMethod + URI 7-ConnectSignalToMethod + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app7-ConnectSignalToMethod PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-ConnectSignalToMethod + PRIVATE Qt6::Quick +) + +install(TARGETS app7-ConnectSignalToMethod + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/Main.qml new file mode 100644 index 0000000..1f00ac7 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/Main.qml @@ -0,0 +1,47 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Connect Signal to Method") + + Rectangle{ + id: rectId + width: 300 + height: 300 + color: "dodgerblue" + + //Set up the signal + signal greet(string message) + + //WE DON'T WANT TO USE THIS THIS TIME. + // Once you set up the signal, Qt setup a signal handler automatically + /* + onGreet: function(message){ + console.log("Greeting with message: "+ message) + } + */ + + //We want to connect, not to a built in signal handler, but to a custom + //regular function + function respond_your_way(message){ + console.log("Responding our way; greeting with message: "+ message) + } + + MouseArea{ + anchors.fill: parent + onClicked: { + //Fire the signal by just calling it like a function + rectId.greet("The sky is blue") + } + } + Component.onCompleted: { + //Make the connection explicitly + rectId.greet.connect(rectId.respond_your_way) + } + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/main.cpp new file mode 100644 index 0000000..c09eaf5 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/7-ConnectSignalToMethod/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("7-ConnectSignalToMethod", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/CMakeLists.txt new file mode 100644 index 0000000..ca34a3d --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(8-ConnectingSignalsToSignals VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app8-ConnectingSignalsToSignals + main.cpp +) + +qt_add_qml_module(app8-ConnectingSignalsToSignals + URI 8-ConnectingSignalsToSignals + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app8-ConnectingSignalsToSignals PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app8-ConnectingSignalsToSignals + PRIVATE Qt6::Quick +) + +install(TARGETS app8-ConnectingSignalsToSignals + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/Main.qml new file mode 100644 index 0000000..e00a10d --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/Main.qml @@ -0,0 +1,45 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("Custom Signals") + + Rectangle{ + id: rectId + width: 300 + height: 300 + color: "dodgerblue" + anchors.left: parent.left + + //Set up the signal + signal greet(string message) + signal forward_greeting(string message) + + //We want to connect, not to a build in signal handler, but to a custom + //regular function + function respond_your_way(message){ + console.log("Responding our way;Greeting with message: "+message) + } + + MouseArea{ + anchors.fill: parent + onClicked: { + //Fire the signal by just calling it like a function + rectId.greet("The sky is blue") + } + } + Component.onCompleted: { + //Connect a signal to another signal + rectId.greet.connect(rectId.forward_greeting) + //Respond to the final signal + rectId.forward_greeting.connect(rectId.respond_your_way) + } + + + } +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/main.cpp new file mode 100644 index 0000000..9461774 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/8-ConnectingSignalsToSignals/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("8-ConnectingSignalsToSignals", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/CMakeLists.txt b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/CMakeLists.txt new file mode 100644 index 0000000..b5ba244 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(9-DifferentQMLComponentSignals VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app9-DifferentQMLComponentSignals + main.cpp +) + +qt_add_qml_module(app9-DifferentQMLComponentSignals + URI 9-DifferentQMLComponentSignals + VERSION 1.0 + QML_FILES Main.qml Notifier.qml Receiver.qml +) + +set_target_properties(app9-DifferentQMLComponentSignals PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app9-DifferentQMLComponentSignals + PRIVATE Qt6::Quick +) + +install(TARGETS app9-DifferentQMLComponentSignals + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Main.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Main.qml new file mode 100644 index 0000000..5500f4f --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Main.qml @@ -0,0 +1,29 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("External Components with signals and slots") + + Notifier{ + id: notifierId + rectColor: "yellowgreen" + target: receiverId + } + + Receiver { + id: receiverId + rectColor: "dodgerblue" + anchors.right: parent.right + } + + /* + Component.onCompleted: { + notifierId.notify.connect(receiverId.receiveInfo)//Connect signal to slot + } + */ +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Notifier.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Notifier.qml new file mode 100644 index 0000000..30b6bd7 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Notifier.qml @@ -0,0 +1,54 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Item { + + //Could have used an alias for rectColor here, but I just want you + //to see that you can also do it this way, and rely on the property handler + // to save the new color when applied. + + + width: notifierRectId.width + height: notifierRectId.height + property int count: 0 + signal notify( string count)//Declare signal + + + property Receiver target: null + onTargetChanged: { + notify.connect(target.receiveInfo) + } + + property color rectColor: "black" + onRectColorChanged: { + notifierRectId.color = rectColor + } + + + + Rectangle { + id: notifierRectId + width: 200 + height: 200 + color: "red" + + + Text { + id: displayTextId + anchors.centerIn: parent + font.pointSize: 20 + text: count + } + + MouseArea{ + anchors.fill: parent + onClicked: { + count++ + notify(count) + } + } + } + +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Receiver.qml b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Receiver.qml new file mode 100644 index 0000000..25778d8 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/Receiver.qml @@ -0,0 +1,36 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Item { + + property alias rectColor: receiverRectId.color + width: receiverRectId.width + height: receiverRectId.height + + + function receiveInfo( count){ + receiverDisplayTextId.text = count + console.log("Receiver received number: "+ count) + } + + + + + Rectangle { + id: receiverRectId + width: 200 + height: 200 + color: "blue" + + + Text { + id: receiverDisplayTextId + anchors.centerIn: parent + font.pointSize: 20 + text: "0" + } + } + +} diff --git a/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/main.cpp b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/main.cpp new file mode 100644 index 0000000..4cf73a3 --- /dev/null +++ b/Qt6QMLBeginnersCode/4.SignalsSlots/9-DifferentQMLComponentSignals/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("9-DifferentQMLComponentSignals", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/CMakeLists.txt b/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/CMakeLists.txt new file mode 100644 index 0000000..b5b8dc1 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(1-TextInput VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app1-TextInput + main.cpp +) + +qt_add_qml_module(app1-TextInput + URI 1-TextInput + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app1-TextInput PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app1-TextInput + PRIVATE Qt6::Quick +) + +install(TARGETS app1-TextInput + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/Main.qml b/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/Main.qml new file mode 100644 index 0000000..08c1a35 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/Main.qml @@ -0,0 +1,82 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + width: 640 + height: 480 + visible: true + title: qsTr("TextInput") + + Row { + x: 10; y: 10 + spacing: 10 + + Rectangle { + id: firstNameRectId + width: firstNameLabelId.implicitWidth + 20 + height: firstNameLabelId.implicitHeight + 20 + color: "beige" + + Text { + id: firstNameLabelId + anchors.centerIn: parent + text: "FirstName: " + } + } + + Rectangle { + id: firstNameTextRectId + color: "beige" + width: firstNameTextId.implicitWidth + 20 + height: firstNameTextId.implicitHeight + 20 + + TextInput { + id: firstNameTextId + anchors.centerIn: parent + focus: true + text: "Type in your first name" + onEditingFinished: { + console.log("The first name changed to: " + text) + } + } + } + } + + Row { + x: 10; y: 60 + spacing: 10 + + Rectangle { + id: lastNameRectId + width: lastNameLabelId.implicitWidth + 20 + height: lastNameLabelId.implicitHeight + 20 + color: "beige" + + Text { + id: lastNameLabelId + anchors.centerIn: parent + text: "LastName: " + } + } + + Rectangle { + id: lastNameTextRectId + color: "beige" + width: lastNameTextId.implicitWidth + 20 + height: lastNameTextId.implicitHeight + 20 + + TextInput { + id: lastNameTextId + anchors.centerIn: parent + focus: true + text: "Type in your last name" + onEditingFinished: { + console.log("The last name changed to: " + text) + } + } + } + } +} + diff --git a/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/main.cpp b/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/main.cpp new file mode 100644 index 0000000..9b9e307 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/1-TextInput/main.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("1-TextInput", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/CMakeLists.txt b/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/CMakeLists.txt new file mode 100644 index 0000000..26bf12e --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-TextEdit VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-TextEdit + main.cpp +) + +qt_add_qml_module(app2-TextEdit + URI 2-TextEdit + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-TextEdit PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-TextEdit + PRIVATE Qt6::Quick +) + +install(TARGETS app2-TextEdit + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/Main.qml b/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/Main.qml new file mode 100644 index 0000000..decdd50 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/Main.qml @@ -0,0 +1,69 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("TextEdit Demo") + + + + /* + TextEdit { + id: textInputId + width: 240 + anchors.centerIn: parent + + text: "Because we want to use our server locally, we set our domain name \r to be localhost . If we had set it up to\n be something else, we would have to go mess with the host files to resolve whatever we put in here to a recognizable network address. ustleaveinlocalhostitisgoodenoughforourlocalusepurposes. Leave the rest to defaults and hit continue. You are then given a choice for the database you want to use" + + wrapMode: TextEdit.Wrap + //textFormat: TextEdit.RichText + font.family: "Helvetica" + font.pointSize: 20 + color: "blue" + focus: true + + onEditingFinished: { + console.log("The current text is: "+ text) + } + } + */ + + TextEdit { + id: textInputId + wrapMode: TextEdit.Wrap + textFormat: TextEdit.RichText + width: 240 + //text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + text: "Because we want to use our server locally, we set our domain name \r to be localhost ." + + font.family: "Helvetica" + font.pointSize: 20 + color: "blue" + focus: true + + onEditingFinished: { + console.log("The current text is: "+ text) + } + } + + + Rectangle { + id: mRectId + width: 240 + height: 100 + color: "red" + anchors.top: textInputId.bottom + MouseArea{ + anchors.fill: parent + onClicked: { + console.log("The new text is: "+textInputId.text) + } + } + } + + +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/main.cpp b/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/main.cpp new file mode 100644 index 0000000..b4962cd --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/2-TextEdit/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-TextEdit", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/CMakeLists.txt b/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/CMakeLists.txt new file mode 100644 index 0000000..221ccba --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-MouseArea VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-MouseArea + main.cpp +) + +qt_add_qml_module(app3-MouseArea + URI 3-MouseArea + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-MouseArea PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-MouseArea + PRIVATE Qt6::Quick +) + +install(TARGETS app3-MouseArea + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/Main.qml b/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/Main.qml new file mode 100644 index 0000000..999ed5f --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/Main.qml @@ -0,0 +1,78 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("MouseArea Demo") + + Rectangle { + id: containerRectId + width: parent.width + height: 200 + color: "beige" + + Rectangle { + id: movingRectId + width: 50 + height: width + color: "blue" + + + } + + MouseArea{ + anchors.fill: parent + onClicked: function(mouse) { + console.log(mouse.x) + movingRectId.x = mouse.x + } + + onWheel:function(wheel) { + console.log(" x: "+ wheel.x + ", y: "+ wheel.y + ", angleData: "+ wheel.angleDelta) + } + + hoverEnabled: true + onHoveredChanged: { + if (containsMouse) + { + containerRectId.color = "red" + }else { + containerRectId.color = "green" + } + } + } + } + + + Rectangle { + id: dragContainerId + width : parent.width + height: 200 + color: "beige" + y: 250 + + Rectangle { + id: draggableRect + width: 50 + height: width + color: "blue" + + onXChanged: { + console.log("x coordinate is: "+ x) + } + } + + MouseArea{ + anchors.fill: parent + drag.target: draggableRect + drag.axis: Drag.XAxis + drag.minimumX: 0 + drag.maximumX: dragContainerId.width - draggableRect.width + + } + } +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/main.cpp b/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/main.cpp new file mode 100644 index 0000000..94634bf --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/3-MouseArea/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-MouseArea", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/CMakeLists.txt b/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/CMakeLists.txt new file mode 100644 index 0000000..e9c1a07 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-KeysAttachedProperty VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-KeysAttachedProperty + main.cpp +) + +qt_add_qml_module(app4-KeysAttachedProperty + URI 4-KeysAttachedProperty + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-KeysAttachedProperty PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-KeysAttachedProperty + PRIVATE Qt6::Quick +) + +install(TARGETS app4-KeysAttachedProperty + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/Main.qml b/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/Main.qml new file mode 100644 index 0000000..6201510 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/Main.qml @@ -0,0 +1,49 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Keys Attached Property") + + Rectangle { + id: containedRect + anchors.centerIn: parent + width: 300 + height: 50 + color: "dodgerblue" + focus: true // The rectangle needs focus for key events to fire properly + + /* + Keys.onDigit5Pressed:function(event) { + console.log("Specific Signal: Pressed on Key 5") + event.accepted = true + } + */ + + + /* + Keys.onDigit5Pressed:function(event) { + if ( event.modifiers === Qt.ControlModifier) + { + console.log("Pressed Control + 5") + }else{ + console.log("Pressed regular 5") + } + event.accepted = false + + } + */ + + Keys.onPressed: function(event){ + if ((event.key === Qt.Key_5) && (event.modifiers & Qt.ControlModifier)){ + console.log("General Signal: Pressed Control + 5") + }else if(event.key === Qt.Key_5){ + console.log("General Signal: Key 5 was pressed alone.") + } + } + } +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/main.cpp b/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/main.cpp new file mode 100644 index 0000000..d5583fc --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/4-KeysAttachedProperty/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-KeysAttachedProperty", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/CMakeLists.txt b/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/CMakeLists.txt new file mode 100644 index 0000000..2fcfb99 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-KeyNavigation VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-KeyNavigation + main.cpp +) + +qt_add_qml_module(app5-KeyNavigation + URI 5-KeyNavigation + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-KeyNavigation PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-KeyNavigation + PRIVATE Qt6::Quick +) + +install(TARGETS app5-KeyNavigation + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/Main.qml b/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/Main.qml new file mode 100644 index 0000000..c86d2b5 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/Main.qml @@ -0,0 +1,98 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Key Navigation Demo") + + Grid { + anchors.centerIn: parent + columns: 2 + + Rectangle { + id: topLeft + width: 100; height: 100 + color: focus ? "red" : "lightgray" + focus: true + + KeyNavigation.right: topRight + KeyNavigation.down: bottomLeft + } + + Rectangle { + id: topRight + width: 100; height: 100 + color: focus ? "red" : "lightgray" + + KeyNavigation.left: topLeft + KeyNavigation.down: bottomRight + } + + Rectangle { + id: bottomLeft + width: 100; height: 100 + color: focus ? "red" : "lightgray" + + KeyNavigation.right: bottomRight + KeyNavigation.up: topLeft + } + + Rectangle { + id: bottomRight + width: 100; height: 100 + color: focus ? "red" : "lightgray" + + KeyNavigation.left: bottomLeft + KeyNavigation.up: topRight + } + + } + + + + + + /* + Row { + anchors.centerIn: parent + + Rectangle{ + id: firstRectId + width: 200 + height: width + border.color: "black" + color: "red" + focus: true + + onFocusChanged: { + color = focus?"red":"gray" + } + + Keys.onDigit5Pressed: { + console.log("I am Rect1") + } + KeyNavigation.right: secondRectId + } + + Rectangle{ + id: secondRectId + width: 200 + height: width + border.color: "black" + color: "gray" + onFocusChanged: { + color = focus?"red":"gray" + } + + Keys.onDigit5Pressed: { + console.log("I am Rect2") + } + KeyNavigation.left: firstRectId + } + } + */ +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/main.cpp b/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/main.cpp new file mode 100644 index 0000000..df04542 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/5-KeyNavigation/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-KeyNavigation", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/CMakeLists.txt b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/CMakeLists.txt new file mode 100644 index 0000000..b348f0c --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-FocusScope VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-FocusScope + main.cpp +) + +qt_add_qml_module(app6-FocusScope + URI 6-FocusScope + VERSION 1.0 + QML_FILES Main.qml MButton.qml +) + +set_target_properties(app6-FocusScope PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-FocusScope + PRIVATE Qt6::Quick +) + +install(TARGETS app6-FocusScope + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/MButton.qml b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/MButton.qml new file mode 100644 index 0000000..87bd485 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/MButton.qml @@ -0,0 +1,40 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +FocusScope { + + width: containerRectId.width + height: containerRectId.height + property alias color: containerRectId.color + + Rectangle { + id : containerRectId + width: 300 + height: 50 + color: "beige" + focus: true + + Text { + id : textId + anchors.centerIn: parent + text: "Default" + } + + Keys.onPressed:function(event) { + if(event.key === Qt.Key_1) + { + textId.text = "Pressed on Key1" + }else if(event.key === Qt.Key_2) + { + textId.text = "Pressed on Key2" + }else{ + textId.text = "Pressed on another key : "+ event.key + } + } + } + +} + + diff --git a/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/Main.qml b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/Main.qml new file mode 100644 index 0000000..4146c7a --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/Main.qml @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("FocusScope Demo") + + Column { + MButton{ + color: "yellow" + focus: true + } + + MButton{ + color: "green" + } + } +} diff --git a/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/main.cpp b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/main.cpp new file mode 100644 index 0000000..dd7bc31 --- /dev/null +++ b/Qt6QMLBeginnersCode/5.UserInput/6-FocusScope/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-FocusScope", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/CMakeLists.txt b/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/CMakeLists.txt new file mode 100644 index 0000000..a04507e --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-JsUsage VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-JsUsage + main.cpp +) + +qt_add_qml_module(app2-JsUsage + URI 2-JsUsage + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-JsUsage PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-JsUsage + PRIVATE Qt6::Quick +) + +install(TARGETS app2-JsUsage + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/Main.qml b/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/Main.qml new file mode 100644 index 0000000..0640583 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/Main.qml @@ -0,0 +1,38 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("JS") + + Rectangle { + id: containerRectId + width: getHeight() //JS in Function + height: 100 + color: x > 300 ? "red" : "green" //property binding + + //JS in signal handler + onXChanged: { + console.log("Current value of x: "+ x) + } + + //Custom function + function getHeight() + { + return height * 2 + } + } + + MouseArea { + anchors.fill: parent + drag.target: containerRectId + drag.axis: Drag.XAxis + drag.minimumX: 0 + drag.maximumX: parent.width - containerRectId.width + + } +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/main.cpp b/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/main.cpp new file mode 100644 index 0000000..7ea53fc --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/2-JsUsage/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-JsUsage", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/CMakeLists.txt b/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/CMakeLists.txt new file mode 100644 index 0000000..e2e5267 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-FunctionsAndScope VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-FunctionsAndScope + main.cpp +) + +qt_add_qml_module(app3-FunctionsAndScope + URI 3-FunctionsAndScope + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-FunctionsAndScope PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-FunctionsAndScope + PRIVATE Qt6::Quick +) + +install(TARGETS app3-FunctionsAndScope + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/Main.qml b/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/Main.qml new file mode 100644 index 0000000..a7b8b9e --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/Main.qml @@ -0,0 +1,45 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Functions and Scope Demo") + + function min ( a ,b) + { + return Math.min(a,b) + } + + Rectangle { + id: mRectId + width: min( 500,400) + height: 100 + anchors.centerIn: parent + color: "blue" + } + + MouseArea { + id: mMouseAreaId + anchors.fill: parent + + function sayMessage() + { + console.log("Hello there") + } + + onClicked: { + sayMessage() + console.log(min(10,12)) + + } + } + + Component.onCompleted: { + console.log("The width of the rect is: "+ min(500,400)) + mMouseAreaId.sayMessage() + } +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/main.cpp b/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/main.cpp new file mode 100644 index 0000000..d43f305 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/3-FunctionsAndScope/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-FunctionsAndScope", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/CMakeLists.txt b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/CMakeLists.txt new file mode 100644 index 0000000..dde8e70 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-JsDirectImpoart VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-JsDirectImpoart + main.cpp +) + +qt_add_qml_module(app4-JsDirectImpoart + URI 4-JsDirectImpoart + VERSION 1.0 + QML_FILES Main.qml utilities1.js +) + +set_target_properties(app4-JsDirectImpoart PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-JsDirectImpoart + PRIVATE Qt6::Quick +) + +install(TARGETS app4-JsDirectImpoart + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/Main.qml b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/Main.qml new file mode 100644 index 0000000..bde09e7 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/Main.qml @@ -0,0 +1,33 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import "utilities1.js" as Utilities1 + + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Javascript Direct Import") + + Rectangle { + width: 300 + height: 100 + color: "yellowgreen" + anchors.centerIn: parent + + Text { + text: "Click Me" + anchors.centerIn: parent + } + + MouseArea { + anchors.fill: parent + onClicked: { + //console.log("Hello there") + Utilities1.greeting() + } + } + } +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/main.cpp b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/main.cpp new file mode 100644 index 0000000..713f11b --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-JsDirectImpoart", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/utilities1.js b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/utilities1.js new file mode 100644 index 0000000..aa55b0b --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/4-JsDirectImpoart/utilities1.js @@ -0,0 +1,8 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +function greeting() +{ + console.log("Hello there from external JS file utilities1.js") +} + diff --git a/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/CMakeLists.txt b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/CMakeLists.txt new file mode 100644 index 0000000..f00ffcb --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-JsIndirectImprt VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-JsIndirectImprt + main.cpp +) + +qt_add_qml_module(app5-JsIndirectImprt + URI 5-JsIndirectImprt + VERSION 1.0 + QML_FILES Main.qml utilities1.js utilities2.js +) + +set_target_properties(app5-JsIndirectImprt PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-JsIndirectImprt + PRIVATE Qt6::Quick +) + +install(TARGETS app5-JsIndirectImprt + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/Main.qml b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/Main.qml new file mode 100644 index 0000000..38154fa --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/Main.qml @@ -0,0 +1,32 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import "utilities1.js" as Utilities1 +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Javascript Import Demo") + + Rectangle { + width: 300 + height: 100 + color: "yellowgreen" + anchors.centerIn: parent + + Text { + text: "Click Me" + anchors.centerIn: parent + } + + MouseArea { + anchors.fill: parent + onClicked: { + //console.log("The ages yield: " + Utilities1.combineAges(33,17)) + value = Utilities1.add(33,17) //Error + } + } + } +} + diff --git a/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/main.cpp b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/main.cpp new file mode 100644 index 0000000..0930f83 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-JsIndirectImprt", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/utilities1.js b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/utilities1.js new file mode 100644 index 0000000..306589a --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/utilities1.js @@ -0,0 +1,14 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +.import "utilities2.js" as Utilities2 + +function greeting() +{ + console.log("Hello there from external JS file: utilities1.js") +} + +function combineAges( age1, age2) +{ + return Utilities2.add(age1,age2) +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/utilities2.js b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/utilities2.js new file mode 100644 index 0000000..f4ac111 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/5-JsIndirectImprt/utilities2.js @@ -0,0 +1,7 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +function add(a,b) { + console.log("Method from utilities2.js called") + return a + b +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/CMakeLists.txt b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/CMakeLists.txt new file mode 100644 index 0000000..f7686de --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-QtInclude VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-QtInclude + main.cpp +) + +qt_add_qml_module(app6-QtInclude + URI 6-QtInclude + VERSION 1.0 + QML_FILES Main.qml utilities1.js utilities2.js +) + +set_target_properties(app6-QtInclude PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-QtInclude + PRIVATE Qt6::Quick +) + +install(TARGETS app6-QtInclude + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/Main.qml b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/Main.qml new file mode 100644 index 0000000..3bb11f3 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/Main.qml @@ -0,0 +1,33 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import "utilities1.js" as Utilities1 + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Javascript Import Demo") + + Rectangle { + width: 300 + height: 100 + color: "yellowgreen" + anchors.centerIn: parent + + Text { + text: "Click Me" + anchors.centerIn: parent + } + + MouseArea { + anchors.fill: parent + onClicked: { + //console.log("The ages yield: " + Utilities1.combineAges(33,17)) + console.log("The ages yield: " + Utilities1.add(33,17)) + } + } + } +} + diff --git a/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/main.cpp b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/main.cpp new file mode 100644 index 0000000..e47e3b9 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-QtInclude", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/utilities1.js b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/utilities1.js new file mode 100644 index 0000000..babd8bd --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/utilities1.js @@ -0,0 +1,14 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +Qt.include("utilities2.js") + +function greeting() +{ + console.log("Hello there from external JS file: utilities1.js") +} + +function combineAges( age1, age2) +{ + return add(age1,age2) +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/utilities2.js b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/utilities2.js new file mode 100644 index 0000000..f4ac111 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/6-QtInclude/utilities2.js @@ -0,0 +1,7 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +function add(a,b) { + console.log("Method from utilities2.js called") + return a + b +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/CMakeLists.txt b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/CMakeLists.txt new file mode 100644 index 0000000..f280073 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(7-JsModules VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app7-JsModules + main.cpp +) + +qt_add_qml_module(app7-JsModules + URI 7-JsModules + VERSION 1.0 + QML_FILES Main.qml utilities1.mjs utilities2.mjs +) + +set_target_properties(app7-JsModules PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-JsModules + PRIVATE Qt6::Quick +) + +install(TARGETS app7-JsModules + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/Main.qml b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/Main.qml new file mode 100644 index 0000000..59b230f --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/Main.qml @@ -0,0 +1,41 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import "utilities1.mjs" as Utilities1 +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Javascript Import Demo") + + Rectangle { + + width: 300 + height: 100 + color: "yellowgreen" + anchors.centerIn: parent + Text { + text: "Click Me" + anchors.centerIn: parent + } + + MouseArea { + anchors.fill: parent + onClicked: { + //Calling a properly exported mathod + /* + console.log("The ages yield: " + Utilities1.combineAges(33,17)) + */ + + + //Can't call a method that's not exported: subtract isn't exported from utilities2.mjs + console.log("Age diff: " + Utilities1.ageDiff(33,17)) + + //Just because add is usable from utilities1.js doesn't mean main.qml + // can use it. utilities2.js doesn't export it. + //console.log ("The sum is: " + Utilities1.add(33,17))//Error + } + } + } +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/main.cpp b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/main.cpp new file mode 100644 index 0000000..9c5e6ac --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("7-JsModules", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/utilities1.mjs b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/utilities1.mjs new file mode 100644 index 0000000..4ee892a --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/utilities1.mjs @@ -0,0 +1,12 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import * as Utilities2 from "utilities2.mjs"; + +export function combineAges(age1,age2){ + return Utilities2.add(age1,age2) +} + +export function ageDiff(age1,age2){ + return Utilities2.subtract(age1,age2) +} diff --git a/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/utilities2.mjs b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/utilities2.mjs new file mode 100644 index 0000000..b7be338 --- /dev/null +++ b/Qt6QMLBeginnersCode/6.Javascript/7-JsModules/utilities2.mjs @@ -0,0 +1,10 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +export function add(age1,age2){ + return age1 + age2 +} + + function subtract(age1,age2){ + return age1 - age2; +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/CMakeLists.txt b/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/CMakeLists.txt new file mode 100644 index 0000000..3ac99d1 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-Anchors VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-Anchors + main.cpp +) + +qt_add_qml_module(app2-Anchors + URI 2-Anchors + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-Anchors PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-Anchors + PRIVATE Qt6::Quick +) + +install(TARGETS app2-Anchors + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/Main.qml b/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/Main.qml new file mode 100644 index 0000000..101ecd9 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/Main.qml @@ -0,0 +1,165 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Anchors") + + Rectangle { + id: containerRectId + width: 300 + height: width + border.color: "black" + anchors.centerIn: parent + + Rectangle { + id: topLeftRectId + width: 100 + height: width + color: "magenta" + Text{ + anchors.centerIn: parent + text: "1" + font.pointSize: 20 + } + } + + + Rectangle { + id: topCenterRectId + width: 100 + height: width + color: "yellowgreen" + anchors.left: topLeftRectId.right + Text{ + anchors.centerIn: parent + text: "2" + font.pointSize: 20 + } + } + + + + Rectangle { + id: topRightRectId + width: 100 + height: width + color: "dodgerblue" + anchors.left: topCenterRectId.right + Text{ + anchors.centerIn: parent + text: "3" + font.pointSize: 20 + } + } + + + + + + Rectangle { + id: centerLeftRectId + width: 100 + height: width + color: "red" + anchors.top: topLeftRectId.bottom + Text{ + anchors.centerIn: parent + text: "4" + font.pointSize: 20 + } + } + + Rectangle { + id: centerCenterRectId + width: 100 + height: width + color: "green" + + //Position relative to other rectangles + /* + anchors.left: centerLeftRectId.right + anchors.top: topRightRectId.bottom + */ + + //Position relative to parent center lines + /* + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + */ + + //Position using the anchors.centerIn shorthand + anchors.centerIn: parent + + Text{ + anchors.centerIn: parent + text: "5" + font.pointSize: 20 + } + + } + Rectangle { + id: centerRightRectId + width: 100 + height: width + color: "blue" + anchors.left: centerCenterRectId.right + anchors.top: topRightRectId.bottom + Text{ + anchors.centerIn: parent + text: "6" + font.pointSize: 20 + } + } + + + + + //The bottom row will be positioned in terms of centerCenterRectId + Rectangle { + id: bottomLeftRectId + width: 100 + height: width + color: "royalblue" + anchors.right: centerCenterRectId.left + anchors.top: centerCenterRectId.bottom + Text{ + anchors.centerIn: parent + text: "7" + font.pointSize: 20 + } + } + Rectangle { + id: bottomCenterRectId + width: 100 + height: width + color: "yellow" + anchors.left: centerCenterRectId.left + anchors.top: centerCenterRectId.bottom + Text{ + anchors.centerIn: parent + text: "8" + font.pointSize: 20 + } + } + + Rectangle { + id: bottomRightRectId + width: 100 + height: width + color: "pink" + anchors.left: centerCenterRectId.right + anchors.top: centerCenterRectId.bottom + Text{ + anchors.centerIn: parent + text: "9" + font.pointSize: 20 + } + } + } + +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/main.cpp b/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/main.cpp new file mode 100644 index 0000000..26da6eb --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/2-Anchors/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-Anchors", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/CMakeLists.txt b/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/CMakeLists.txt new file mode 100644 index 0000000..a52ec1d --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-AnchroMarginAndOffset VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-AnchroMarginAndOffset + main.cpp +) + +qt_add_qml_module(app3-AnchroMarginAndOffset + URI 3-AnchroMarginAndOffset + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-AnchroMarginAndOffset PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-AnchroMarginAndOffset + PRIVATE Qt6::Quick +) + +install(TARGETS app3-AnchroMarginAndOffset + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/Main.qml b/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/Main.qml new file mode 100644 index 0000000..982b893 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/Main.qml @@ -0,0 +1,162 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Anchors: Margins and offsets") + + Rectangle { + id: containerRectId + width: 300 + height: width + border.color: "black" + anchors.centerIn: parent + + Rectangle { + id: topLeftRectId + width: 100 + height: width + color: "magenta" + Text{ + anchors.centerIn: parent + text: "1" + font.pointSize: 20 + } + } + + Rectangle { + id: topCenterRectId + width: 100 + height: width + color: "yellowgreen" + anchors.left: topLeftRectId.right + Text{ + anchors.centerIn: parent + text: "2" + font.pointSize: 20 + } + } + + Rectangle { + id: topRightRectId + width: 100 + height: width + color: "dodgerblue" + anchors.left: topCenterRectId.right + Text{ + anchors.centerIn: parent + text: "3" + font.pointSize: 20 + } + } + + Rectangle { + id: centerLeftRectId + width: 100 + height: width + color: "red" + anchors.top: topLeftRectId.bottom + Text{ + anchors.centerIn: parent + text: "4" + font.pointSize: 20 + } + } + + Rectangle { + id: centerCenterRectId + width: 100 + height: width + color: "green" + + /* + + + //Anchor relative to other rectangles + anchors.left: centerLeftRectId.right + anchors.top: topRightRectId.bottom + + //Margins + anchors.topMargin: 10 + //anchors.rightMargin: 10 // This margin won't work because we have no right anchor + //anchors.leftMargin: 10 + */ + + //Anchor relative to center anchor lines + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + + //Offsets + anchors.horizontalCenterOffset: -10 + anchors.verticalCenterOffset: 10 + + Text{ + anchors.centerIn: parent + text: "5" + font.pointSize: 20 + } + } + Rectangle { + id: centerRightRectId + width: 100 + height: width + color: "blue" + anchors.left: centerCenterRectId.right + anchors.top: topRightRectId.bottom + Text{ + anchors.centerIn: parent + text: "6" + font.pointSize: 20 + } + } + + + //The bottom row will be positioned in terms of centerCenterRectId + Rectangle { + id: bottomLeftRectId + width: 100 + height: width + color: "royalblue" + anchors.right: centerCenterRectId.left + anchors.top: centerCenterRectId.bottom + Text{ + anchors.centerIn: parent + text: "7" + font.pointSize: 20 + } + + } + Rectangle { + id: bottomCenterRectId + width: 100 + height: width + color: "yellow" + anchors.left: centerCenterRectId.left + anchors.top: centerCenterRectId.bottom + Text{ + anchors.centerIn: parent + text: "8" + font.pointSize: 20 + } + } + + Rectangle { + id: bottomRightRectId + width: 100 + height: width + color: "pink" + anchors.left: centerCenterRectId.right + anchors.top: centerCenterRectId.bottom + Text{ + anchors.centerIn: parent + text: "9" + font.pointSize: 20 + } + } + } +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/main.cpp b/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/main.cpp new file mode 100644 index 0000000..5140253 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/3-AnchroMarginAndOffset/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-AnchroMarginAndOffset", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/CMakeLists.txt b/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/CMakeLists.txt new file mode 100644 index 0000000..d2cc734 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-AnchorParentSibling VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-AnchorParentSibling + main.cpp +) + +qt_add_qml_module(app4-AnchorParentSibling + URI 4-AnchorParentSibling + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-AnchorParentSibling PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-AnchorParentSibling + PRIVATE Qt6::Quick +) + +install(TARGETS app4-AnchorParentSibling + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/Main.qml b/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/Main.qml new file mode 100644 index 0000000..e9dbc9a --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/Main.qml @@ -0,0 +1,39 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Anchors : Parents and Siblings") + + Rectangle { + id: containerRectId + width: 300 + height: width + border.color: "black" + anchors.centerIn: parent + + Rectangle { + id: topLeftRectId + width: 100 + height: width + color: "magenta" + + //This anchor won't work because siblingRect isn't either a ibling or a parent + anchors.top: siblingRect.bottom + } + } + + Rectangle { + id: siblingRect + width: 200 + height: 200 + color : "black" + anchors.right: containerRectId.left + } + + +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/main.cpp b/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/main.cpp new file mode 100644 index 0000000..d9b0ee9 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/4-AnchorParentSibling/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-AnchorParentSibling", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/CMakeLists.txt b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/CMakeLists.txt new file mode 100644 index 0000000..e8eff24 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-Positioning VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-Positioning + main.cpp resource.qrc +) + +qt_add_qml_module(app5-Positioning + URI 5-Positioning + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-Positioning PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-Positioning + PRIVATE Qt6::Quick +) + +install(TARGETS app5-Positioning + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/Main.qml b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/Main.qml new file mode 100644 index 0000000..fc440ac --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/Main.qml @@ -0,0 +1,59 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Posionners") + + Grid { + columns: 2 + spacing: 10 +// rowSpacing: 10 +// columnSpacing: 10 + + horizontalItemAlignment: Grid.AlignRight + verticalItemAlignment: Grid.AlignVCenter + + LayoutMirroring.enabled: true + LayoutMirroring.childrenInherit: true + + Rectangle { + id: topLeftRectId + width: 60 + height: width + color: "magenta" + Text{text: "1"; anchors.centerIn: parent; font.pointSize: 20} + } + + Rectangle { + id: topCenterRectId + width: 100 + height: width + color: "yellowgreen" + Text{text: "2"; anchors.centerIn: parent; font.pointSize: 20} + } + + Rectangle { + id: topRightRectId + width: 100 + height: width + color: "dodgerblue" + Text{text: "3"; anchors.centerIn: parent; font.pointSize: 20} + + } + + Rectangle { + id: centerLeftRectId + width: 100 + height: width + color: "beige" + Text{text: "4"; anchors.centerIn: parent; font.pointSize: 20} + + } + + } +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/images/LearnQt.png b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/images/LearnQt.png new file mode 100644 index 0000000..27549e4 Binary files /dev/null and b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/images/LearnQt.png differ diff --git a/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/main.cpp b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/main.cpp new file mode 100644 index 0000000..acc1245 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-Positioning", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/resource.qrc b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/resource.qrc new file mode 100644 index 0000000..10db962 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/5-Positioning/resource.qrc @@ -0,0 +1,5 @@ + + + images/LearnQt.png + + diff --git a/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/CMakeLists.txt b/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/CMakeLists.txt new file mode 100644 index 0000000..5d36914 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-Layouts VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-Layouts + main.cpp +) + +qt_add_qml_module(app6-Layouts + URI 6-Layouts + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app6-Layouts PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-Layouts + PRIVATE Qt6::Quick +) + +install(TARGETS app6-Layouts + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/Main.qml b/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/Main.qml new file mode 100644 index 0000000..029dab9 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/Main.qml @@ -0,0 +1,164 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Layouts +Window { + visible: true + width: mGridLayoutId.implicitWidth + height: mGridLayoutId.implicitHeight + title: qsTr("Layouts") + + GridLayout{ + id: mGridLayoutId + anchors.fill: parent + columns: 3 + layoutDirection: Qt.RightToLeft + + Rectangle { + id: topLeftRectId + width: 70 + height: width + color: "green" + Text{text: "1"; anchors.centerIn: parent; font.pointSize: 20} + + + //Showing Layout alignment + Layout.alignment: Qt.AlignRight|Qt.AlignTop + Layout.fillWidth: true + Layout.fillHeight: true + Layout.maximumWidth: 150 + Layout.maximumHeight: 150 + } + Rectangle { + id: topCenterRectId + width: 100 + height: width + color: "red" + Text{text: "2"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.columnSpan: 2 + } + + //Taking this out because topCenterRectId will span two columns + //Rectangle "3" taken out . Its space will be taken by Rectangle "2" + /* + Rectangle { + id: topRightRectId + width: 100 + height: width + color: "blue" + Text{text: "3"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + } + */ + + + Rectangle { + id: centerLeftRectId + width: 100 + height: width + color: "beige" + Text{text: "4"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + Layout.rowSpan: 2 + + } + Rectangle { + id: centerCenterRectId + width: 100 + height: width + color: "pink" + Text{text: "5"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + + } + Rectangle { + id: centerRightRectId + width: 100 + height: width + color: "yellow" + Text{text: "6"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + + } + + + //Taking this out because the beige centerLeftRectId rectangle will span two rows + //Rectangle "7" Taken out. Its space will be taken by Rectangle 4 + /* + + Rectangle { + id: bottomLeftRectId + width: 100 + height: width + color: "magenta" + Text{text: "7"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + + } + */ + + + + Rectangle { + id: bottomCenterRectId + width: 100 + height: width + color: "yellowgreen" + Text{text: "8"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + + } + Rectangle { + id: bottomRightRectId + width: 100 + height: width + color: "dodgerblue" + Text{text: "9"; anchors.centerIn: parent; font.pointSize: 20} + + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/main.cpp b/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/main.cpp new file mode 100644 index 0000000..a6c31c4 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/6-Layouts/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-Layouts", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/7-Flow/CMakeLists.txt b/Qt6QMLBeginnersCode/7-Positioning/7-Flow/CMakeLists.txt new file mode 100644 index 0000000..3440544 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/7-Flow/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(7-Flow VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app7-Flow + main.cpp +) + +qt_add_qml_module(app7-Flow + URI 7-Flow + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app7-Flow PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-Flow + PRIVATE Qt6::Quick +) + +install(TARGETS app7-Flow + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/7-Positioning/7-Flow/Main.qml b/Qt6QMLBeginnersCode/7-Positioning/7-Flow/Main.qml new file mode 100644 index 0000000..8a616c0 --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/7-Flow/Main.qml @@ -0,0 +1,140 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Flow") + + Flow { + id: containerFlowId + width : parent.width + height: parent.height + + flow: Flow.TopToBottom + layoutDirection: Qt.RightToLeft + + //spacing: 20 + + + Rectangle { + id: topLeftRectId + width : 70 + height: 70 + color: "green" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "1" + } + } + + Rectangle { + id: topCenterRectId + width : 100 + height: 100 + color: "beige" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "2" + } + } + + Rectangle { + id: topRightRectId + width : 100 + height: 100 + color: "dodgerblue" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "3" + } + } + + Rectangle { + id: leftCenterRectId + width : 100 + height: 100 + color: "magenta" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "4" + } + } + + Rectangle { + id: centerRectId + width : 100 + height: 100 + color: "red" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "5" + } + } + Rectangle { + id: rightCenterId + width : 100 + height: 100 + color: "yellow" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "6" + } + } + + Rectangle { + id: bottomLeftRectId + width : 100 + height: 100 + color: "royalblue" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "7" + } + } + + Rectangle { + id: bottomCenterRect + width : 100 + height: 100 + color: "greenyellow" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "8" + } + } + + Rectangle { + id: bottomRightRectId + width : 100 + height: 100 + color: "blue" + Text { + anchors.centerIn: parent + color: "black" + font.pointSize: 30 + text: "9" + } + } + } +} diff --git a/Qt6QMLBeginnersCode/7-Positioning/7-Flow/main.cpp b/Qt6QMLBeginnersCode/7-Positioning/7-Flow/main.cpp new file mode 100644 index 0000000..814fe9d --- /dev/null +++ b/Qt6QMLBeginnersCode/7-Positioning/7-Flow/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("7-Flow", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/CMakeLists.txt new file mode 100644 index 0000000..2ab11a0 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(10-SwipeViewPageIndicator VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app10-SwipeViewPageIndicator + main.cpp resource.qrc +) + +qt_add_qml_module(app10-SwipeViewPageIndicator + URI 10-SwipeViewPageIndicator + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app10-SwipeViewPageIndicator PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app10-SwipeViewPageIndicator + PRIVATE Qt6::Quick +) + +install(TARGETS app10-SwipeViewPageIndicator + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/Main.qml new file mode 100644 index 0000000..6939a7b --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/Main.qml @@ -0,0 +1,52 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("PageIndicator and SwipeView") + + SwipeView{ + id: swipeViewId + anchors.fill: parent + currentIndex: pageIndicatorId.currentIndex + anchors.bottomMargin: 20 + + Image { + id: image1 + fillMode: Image.PreserveAspectFit + //source: "https://www.learnqt.guide/images/qt_quick_fundamentals.png" + source:"qrc:/images/1.png" + } + Image { + id: image2 + fillMode: Image.PreserveAspectFit + //source: "https://www.learnqt.guide/images/qt_quick_intermediate.png" + source: "qrc:/images/2.png" + } + Image { + id: image3 + fillMode: Image.PreserveAspectFit + //source: "https://www.learnqt.guide/images/qt_quick_advanced.png" + source: "qrc:/images/3.png" + } + + } + + PageIndicator{ + id: pageIndicatorId + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + + //Page indicator specific properties + currentIndex: swipeViewId.currentIndex + interactive: true + count: swipeViewId.count + } + + +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/1.png b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/1.png new file mode 100644 index 0000000..7952ae5 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/1.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/2.png b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/2.png new file mode 100644 index 0000000..93273a6 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/2.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/3.png b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/3.png new file mode 100644 index 0000000..c187ab1 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/images/3.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/main.cpp new file mode 100644 index 0000000..27e9fcf --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("10-SwipeViewPageIndicator", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/resource.qrc b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/resource.qrc new file mode 100644 index 0000000..d802040 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/10-SwipeViewPageIndicator/resource.qrc @@ -0,0 +1,7 @@ + + + images/1.png + images/2.png + images/3.png + + diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/CMakeLists.txt new file mode 100644 index 0000000..2856bee --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(11-ProgressBar VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app11-ProgressBar + main.cpp +) + +qt_add_qml_module(app11-ProgressBar + URI 11-ProgressBar + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app11-ProgressBar PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app11-ProgressBar + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app11-ProgressBar + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/Main.qml new file mode 100644 index 0000000..4e28d3e --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/Main.qml @@ -0,0 +1,54 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("ProgressBar") + + Column { + width: parent.width + spacing: 20 + + Button { + text: "Start" + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + progressBarId.value = 78 + } + } + + + Dial { + id: dialId + from : 1 + to: 100 + value: 40 + anchors.horizontalCenter: parent.horizontalCenter + onValueChanged: { + progressBarId.value = value + } + + } + + + ProgressBar { + id: progressBarId + from: 1 + to: 100 + value: 40 + anchors.horizontalCenter: parent.horizontalCenter + + } + + ProgressBar { + id: progressBarId1 + indeterminate: true + anchors.horizontalCenter: parent.horizontalCenter + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/main.cpp new file mode 100644 index 0000000..bfae74f --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/11-ProgressBar/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("11-ProgressBar", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/CMakeLists.txt new file mode 100644 index 0000000..82e9204 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(12-RangeSlider VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app12-RangeSlider + main.cpp +) + +qt_add_qml_module(app12-RangeSlider + URI 12-RangeSlider + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app12-RangeSlider PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app12-RangeSlider + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app12-RangeSlider + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/Main.qml new file mode 100644 index 0000000..d566de6 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/Main.qml @@ -0,0 +1,32 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("RangeSlider") + + Row { + spacing: 40 + width: parent.width + + RangeSlider{ + //orientation: Qt.Vertical + from: 1 + to: 100 + first.value: 25 + second.value: 75 + + first.onValueChanged: { + console.log("First value changed to: "+ first.value) + } + second.onValueChanged: { + console.log("Second value changed to: "+ second.value) + } + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/main.cpp new file mode 100644 index 0000000..8593d2c --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/12-RangeSlider/main.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Default"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("12-RangeSlider", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/CMakeLists.txt new file mode 100644 index 0000000..21aa71b --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(13-FlickableScrollbar VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app13-FlickableScrollbar + main.cpp +) + +qt_add_qml_module(app13-FlickableScrollbar + URI 13-FlickableScrollbar + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app13-FlickableScrollbar PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app13-FlickableScrollbar + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app13-FlickableScrollbar + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/Main.qml new file mode 100644 index 0000000..8e81897 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/Main.qml @@ -0,0 +1,125 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Flickable and Scrollbar") + + Flickable{ + + width: parent.width + height: parent.height + contentHeight: mColumnId.implicitHeight + + + Column{ + id: mColumnId + anchors.fill: parent + + Rectangle { + color: "red" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 1" + font.pointSize: 30 + color: "white" + } + } + + + Rectangle { + color: "blue" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 2" + font.pointSize: 30 + color: "white" + } + } + + Rectangle { + color: "yellow" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 3" + font.pointSize: 30 + color: "white" + } + } + + Rectangle { + color: "magenta" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 4" + font.pointSize: 30 + color: "white" + } + } + Rectangle { + color: "yellowgreen" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 5" + font.pointSize: 30 + color: "white" + } + } + /* + Rectangle { + color: "red" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 6" + font.pointSize: 30 + color: "white" + } + } + Rectangle { + color: "beige" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 7" + font.pointSize: 30 + color: "white" + } + } + Rectangle { + color: "royalblue" + width: parent.width + height: 200 + Text { + anchors.centerIn: parent + text: "Element 8" + font.pointSize: 30 + color: "white" + } + } + */ + + + + } + + ScrollBar.vertical: ScrollBar{} + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/main.cpp new file mode 100644 index 0000000..8cf5419 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/13-FlickableScrollbar/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Universal"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("13-FlickableScrollbar", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/CMakeLists.txt new file mode 100644 index 0000000..d60d7cb --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(14-Slider VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app14-Slider + main.cpp +) + +qt_add_qml_module(app14-Slider + URI 14-Slider + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app14-Slider PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app14-Slider + PRIVATE Qt6::Quick +) + +install(TARGETS app14-Slider + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/Main.qml new file mode 100644 index 0000000..9687bc3 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/Main.qml @@ -0,0 +1,38 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Slider") + + Column { + width: parent.width + spacing: 20 + + Slider { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + from: 1 + to: 100 + value: 40 + onValueChanged: { + progressBarId.value = value + } + } + + ProgressBar { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + id: progressBarId + from : 1 + to: 100 + value: 40 + + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/main.cpp new file mode 100644 index 0000000..c18f002 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/14-Slider/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("14-Slider", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/CMakeLists.txt new file mode 100644 index 0000000..de67f3e --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(15-Switch VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app15-Switch + main.cpp +) + +qt_add_qml_module(app15-Switch + URI 15-Switch + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app15-Switch PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app15-Switch + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app15-Switch + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/Main.qml new file mode 100644 index 0000000..dfffacb --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/Main.qml @@ -0,0 +1,40 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Switch") + + Column { + width: parent.width + spacing: 20 + + Switch{ + anchors.horizontalCenter: parent.horizontalCenter + text: "WiFi" + checked: true + onCheckedChanged: { + if(checked) + { + console.log("WiFi switch is turned ON") + }else{ + console.log("WiFi switch is turned OFF") + } + } + } + Switch{ + anchors.horizontalCenter: parent.horizontalCenter + text: "Bluetooth" + } + Switch{ + anchors.horizontalCenter: parent.horizontalCenter + text: "NFC" + enabled: false + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/main.cpp new file mode 100644 index 0000000..a6cc038 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/15-Switch/main.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("15-Switch", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/CMakeLists.txt new file mode 100644 index 0000000..09c9f93 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(16-PageTabBar VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app16-PageTabBar + main.cpp resource.qrc +) + +qt_add_qml_module(app16-PageTabBar + URI 16-PageTabBar + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app16-PageTabBar PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app16-PageTabBar + PRIVATE Qt6::Quick +) + +install(TARGETS app16-PageTabBar + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/Main.qml new file mode 100644 index 0000000..4cc4d32 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/Main.qml @@ -0,0 +1,64 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 480 + height: 640 + title: qsTr("Page and TabBar") + + Page { + id: pageId + anchors.fill: parent + + header: Rectangle{ + width: parent.width + height: 50 + color: "yellowgreen" + Text{ + text: "Some header text" + anchors.centerIn: parent + } + } + + SwipeView{ + id: swipeViewId + anchors.fill: parent + currentIndex: tabBarId.currentIndex + + Image{ + fillMode: Image.PreserveAspectFit + source: "qrc:/images/1.png" + } + + Image{ + fillMode: Image.PreserveAspectFit + source: "qrc:/images/2.png" + } + Image{ + fillMode: Image.PreserveAspectFit + source: "qrc:/images/3.png" + } + + + } + + footer: TabBar{ + id: tabBarId + currentIndex: swipeViewId.currentIndex + + TabButton{ + text: "First" + } + TabButton{ + text: "Second" + } + TabButton{ + text: "Third" + } + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/1.png b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/1.png new file mode 100644 index 0000000..7952ae5 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/1.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/2.png b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/2.png new file mode 100644 index 0000000..93273a6 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/2.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/3.png b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/3.png new file mode 100644 index 0000000..c187ab1 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/images/3.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/main.cpp new file mode 100644 index 0000000..2d06f02 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("16-PageTabBar", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/resource.qrc b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/resource.qrc new file mode 100644 index 0000000..d802040 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/16-PageTabBar/resource.qrc @@ -0,0 +1,7 @@ + + + images/1.png + images/2.png + images/3.png + + diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/CMakeLists.txt new file mode 100644 index 0000000..9102742 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(17-TextAreaScrollView VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app17-TextAreaScrollView + main.cpp +) + +qt_add_qml_module(app17-TextAreaScrollView + URI 17-TextAreaScrollView + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app17-TextAreaScrollView PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app17-TextAreaScrollView + PRIVATE Qt6::Quick +) + +install(TARGETS app17-TextAreaScrollView + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/Main.qml new file mode 100644 index 0000000..e399339 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/Main.qml @@ -0,0 +1,54 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("TextArea") + + Column { + spacing: 40 + width: parent.width + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "TextArea is a multi-line text editor." + } + + + ScrollView{ + id: scrollView + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + height: 150 + TextArea { + id: textAreaId + font.pointSize: 15 + wrapMode: TextArea.WordWrap + placeholderText: "Type in your query" + text: "TextArea is a QML element where you can type in multiple lines of text and more and more and more At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat TextArea is a QML element where you can type in multiple lines of text and more and more and more At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat TextArea is a QML element where you can type in multiple lines of text and more and more and more At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat end" + } + } + + + + + + + + Button{ + text: "Submit" + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + console.log("The text inside the TextArea is: "+ textAreaId.text) + textAreaId.text = textAreaId.text + "sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facili1111" + } + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/main.cpp new file mode 100644 index 0000000..1f5f78f --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/17-TextAreaScrollView/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("17-TextAreaScrollView", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/CMakeLists.txt new file mode 100644 index 0000000..4702809 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(18-TextFieldLabel VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app18-TextFieldLabel + main.cpp +) + +qt_add_qml_module(app18-TextFieldLabel + URI 18-TextFieldLabel + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app18-TextFieldLabel PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app18-TextFieldLabel + PRIVATE Qt6::Quick +) + +install(TARGETS app18-TextFieldLabel + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/Main.qml new file mode 100644 index 0000000..58e20f2 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/Main.qml @@ -0,0 +1,49 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("TextField") + + Column { + spacing: 20 + anchors.centerIn: parent + + Row { + spacing: 30 + width: 300 + + Label { + width: 100 + height: 50 + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + text: "First Name : " + } + + TextField { + id : textFieldId + width: 200 + height: 50 + placeholderText: "Type your First Name" + onEditingFinished: { + console.log("Text Edit Finished : "+ text) + } + } + } + + Button{ + text : "Click" + onClicked: { + console.log("Text is :"+ textFieldId.text) + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/main.cpp new file mode 100644 index 0000000..daedfba --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/18-TextFieldLabel/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("18-TextFieldLabel", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/CMakeLists.txt new file mode 100644 index 0000000..2e93a28 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(19-SplitView VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app19-SplitView + main.cpp +) + +qt_add_qml_module(app19-SplitView + URI 19-SplitView + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app19-SplitView PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app19-SplitView + PRIVATE Qt6::Quick +) + +install(TARGETS app19-SplitView + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/Main.qml new file mode 100644 index 0000000..426ad45 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/Main.qml @@ -0,0 +1,43 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +Window { + visible: true + width: 640 + height: 480 + title: qsTr("SplitView") + + + SplitView { + anchors.fill: parent + orientation: Qt.Horizontal + + Rectangle { + SplitView.preferredWidth: 150 + SplitView.minimumWidth: 100 + color: "lightblue" + Text { + text: "View 1" + anchors.centerIn: parent + } + } + Rectangle { + SplitView.preferredWidth: 100 + color: "lightgray" + Text { + text: "View 2" + anchors.centerIn: parent + } + } + Rectangle { + SplitView.preferredWidth: 150 + color: "lightgreen" + Text { + text: "View 3" + anchors.centerIn: parent + } + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/main.cpp new file mode 100644 index 0000000..5cf567f --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/19-SplitView/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("19-SplitView", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/CMakeLists.txt new file mode 100644 index 0000000..633719b --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-Button VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-Button + main.cpp +) + +qt_add_qml_module(app2-Button + URI 2-Button + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-Button PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-Button + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app2-Button + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/Main.qml new file mode 100644 index 0000000..f6506f6 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/Main.qml @@ -0,0 +1,35 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Button") + + ColumnLayout { + anchors.left: parent.left + anchors.right: parent.right + + Button { + id: button1 + text: "Button1" + Layout.fillWidth: true + onClicked: { + console.log("Clicked on button1") + } + } + Button{ + id: button2 + text : "Button2" + Layout.fillWidth: true + onClicked: { + console.log("Clicked on button2") + } + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/main.cpp new file mode 100644 index 0000000..4da105b --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/2-Button/main.cpp @@ -0,0 +1,28 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + + //Load our style + QQuickStyle::setStyle("Material"); + //QQuickStyle::setStyle("Universal"); + //QQuickStyle::setStyle("Fusion"); + //QQuickStyle::setStyle("Imagine"); + //QQuickStyle::setStyle("Default"); + + + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-Button", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/CMakeLists.txt new file mode 100644 index 0000000..40ff723 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(20-Drawer VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app20-Drawer + main.cpp resource.qrc +) + +qt_add_qml_module(app20-Drawer + URI 20-Drawer + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app20-Drawer PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app20-Drawer + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app20-Drawer + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/Main.qml new file mode 100644 index 0000000..ec8be75 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/Main.qml @@ -0,0 +1,122 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id : rootId + visible: true + width: 360 + height: 520 + title: qsTr("Drawer") + + header: ToolBar{ + height: 50 + background: Rectangle{ + color: "mintcream" + } + + RowLayout { + spacing: 20 + anchors.fill: parent + + ToolButton{ + background: Rectangle{ + color: "mintcream" + } + + icon.source: "qrc:/images/drawer.png" + + onClicked: { + console.log("Toolbutton clicked") + //Open Drawer + drawerId.open() + } + + } + + Label { + id: titleLabel + text: "Drawer App" + font.pixelSize: 20 + elide: Label.ElideRight + horizontalAlignment: Qt.AlignHCenter + verticalAlignment: Qt.AlignVCenter + Layout.fillWidth: true + + + + } + } + } + + Drawer { + id: drawerId + width: Math.min(rootId.width,rootId.height) * (2/3) + height: rootId.height + interactive: true + + ColumnLayout{ + spacing: 0 + width: parent.width + + Button{ + width: parent.width + height: 50 + text : "Item1" + font.pointSize: 20 + background: Rectangle{ + color: "beige" + } + Layout.fillWidth: true + + onClicked: { + console.log("Clicked on item1 ") + contentRectId.color = "red" + drawerId.close() + } + } + Button{ + width: parent.width + height: 50 + text : "Item2" + font.pointSize: 20 + background: Rectangle{ + color: "yellowgreen" + } + Layout.fillWidth: true + + onClicked: { + console.log("Clicked on item2 ") + contentRectId.color = "green" + drawerId.close() + } + } + Button{ + width: parent.width + height: 50 + text : "Item3" + font.pointSize: 20 + background: Rectangle{ + color: "dodgerblue" + } + Layout.fillWidth: true + + onClicked: { + console.log("Clicked on item3 ") + contentRectId.color = "blue" + drawerId.close() + } + } + } + + } + + Rectangle{ + id : contentRectId + anchors.fill: parent + color: "gray" + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/images/drawer.png b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/images/drawer.png new file mode 100644 index 0000000..1e974ef Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/images/drawer.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/main.cpp new file mode 100644 index 0000000..2132471 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Fusion"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("20-Drawer", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/resource.qrc b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/resource.qrc new file mode 100644 index 0000000..07b42ed --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/20-Drawer/resource.qrc @@ -0,0 +1,5 @@ + + + images/drawer.png + + diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/CMakeLists.txt new file mode 100644 index 0000000..f07312c --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(21-ApplicationWindow VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app21-ApplicationWindow + main.cpp resource.qrc +) + +qt_add_qml_module(app21-ApplicationWindow + URI 21-ApplicationWindow + VERSION 1.0 + QML_FILES Main.qml Page1.qml Page2.qml Page3.qml +) + +set_target_properties(app21-ApplicationWindow PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app21-ApplicationWindow + PRIVATE Qt6::Quick +) + +install(TARGETS app21-ApplicationWindow + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Main.qml new file mode 100644 index 0000000..668a47d --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Main.qml @@ -0,0 +1,131 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +ApplicationWindow { + visible: true + width: 640 + height: 480 + title: qsTr("ApplicationWindow Demo") + + menuBar: MenuBar { + Menu { + title: qsTr("&File") + Action { + id: newActionId + text: qsTr("&New") + icon.source: "qrc:/images/newFileIcon.png" + onTriggered: { + console.log("Clicked on new") + } + } + + + Action { + id: openActionId + text: qsTr("&Open...") + icon.source: "qrc:/images/openIcon.png" + + } + Action { + id: saveActionId + text: qsTr("&Save") + icon.source: "qrc:/images/saveIcon.png" + } + Action { + id: saveAsActionId + text: qsTr("Save &As...") + icon.source: "qrc:/images/saveAsIcon.png" + } + + MenuSeparator{} + Action { + id: quitActionId + text: qsTr("Quit") + icon.source: "qrc:/images/quitIcon.png" + onTriggered: Qt.quit() + + } + } + + Menu { + title: qsTr("&Edit") + Action {id: cutMenuId; icon.source: "qrc:/images/cutIcon.png"; text: qsTr("Cut") } + Action { + text: qsTr("Copy") + icon.source: "qrc:/images/copyIcon.png" + } + Action { text: qsTr("Paste") ; icon.source: "qrc:/images/pasteIcon.png"} + MenuSeparator { } + Action { text: qsTr("Undo"); icon.source: "qrc:/images/undoIcon.png" } + Action { text: qsTr("Redo") ; icon.source: "qrc:/images/redoIcon.png"} + } + Menu { + id: helpMenu + title: qsTr("&Help") + Action { + text: qsTr("&About") + icon.source: "qrc:/images/info.png" + } + } + } + + header: ToolBar { + Row { + anchors.fill: parent + ToolButton{ + action: newActionId + } + ToolButton{ + action: saveActionId + } + ToolButton{ + action: saveAsActionId + } + ToolButton{ + action: quitActionId + } + } + } + + footer: TabBar { + id: mTabBar + width: parent.width + + TabButton { + text : qsTr("Page1") + onClicked: { + mStackId.pop() + mStackId.push("Page1.qml") + console.log("Number of items : " + mStackId.depth) + } + } + TabButton { + text : qsTr("Page2") + onClicked: { + mStackId.pop() + mStackId.push("Page2.qml") + console.log("Number of items : " + mStackId.depth) + } + } + TabButton { + text : qsTr("Page3") + onClicked: { + mStackId.pop() + mStackId.push("Page3.qml") + console.log("Number of items : " + mStackId.depth) + } + } + } + + //Main Content + StackView { + id : mStackId + anchors.fill: parent + initialItem: Page1{ + + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page1.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page1.qml new file mode 100644 index 0000000..c06fbff --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page1.qml @@ -0,0 +1,8 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Rectangle { + color: "red" +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page2.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page2.qml new file mode 100644 index 0000000..e68110f --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page2.qml @@ -0,0 +1,8 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Rectangle { + color: "green" +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page3.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page3.qml new file mode 100644 index 0000000..312342d --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/Page3.qml @@ -0,0 +1,9 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick + +Rectangle { + color: "blue" + +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/copyIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/copyIcon.png new file mode 100644 index 0000000..85be05e Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/copyIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/cutIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/cutIcon.png new file mode 100644 index 0000000..1ce21dc Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/cutIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/info.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/info.png new file mode 100644 index 0000000..c2208f9 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/info.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/newFileIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/newFileIcon.png new file mode 100644 index 0000000..5489e70 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/newFileIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/openIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/openIcon.png new file mode 100644 index 0000000..da36b27 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/openIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/pasteIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/pasteIcon.png new file mode 100644 index 0000000..f7751bb Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/pasteIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/quitIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/quitIcon.png new file mode 100644 index 0000000..dadea01 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/quitIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/redoIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/redoIcon.png new file mode 100644 index 0000000..54cb39e Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/redoIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/saveAsIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/saveAsIcon.png new file mode 100644 index 0000000..1fb050b Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/saveAsIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/saveIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/saveIcon.png new file mode 100644 index 0000000..ed02cad Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/saveIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/undoIcon.png b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/undoIcon.png new file mode 100644 index 0000000..67c7b63 Binary files /dev/null and b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/images/undoIcon.png differ diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/main.cpp new file mode 100644 index 0000000..45c51b5 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("21-ApplicationWindow", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/resource.qrc b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/resource.qrc new file mode 100644 index 0000000..f9f71ce --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/21-ApplicationWindow/resource.qrc @@ -0,0 +1,15 @@ + + + images/copyIcon.png + images/cutIcon.png + images/info.png + images/newFileIcon.png + images/openIcon.png + images/pasteIcon.png + images/quitIcon.png + images/redoIcon.png + images/saveAsIcon.png + images/saveIcon.png + images/undoIcon.png + + diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/CMakeLists.txt new file mode 100644 index 0000000..39a8933 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-BusyIndicator VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-BusyIndicator + main.cpp +) + +qt_add_qml_module(app3-BusyIndicator + URI 3-BusyIndicator + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-BusyIndicator PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-BusyIndicator + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app3-BusyIndicator + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/Main.qml new file mode 100644 index 0000000..1d998e9 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/Main.qml @@ -0,0 +1,61 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("BusyIndicator") + + ColumnLayout { + width: parent.width + //height: parent.height + + BusyIndicator{ + id: busyIndicatorId + Layout.alignment: Qt.AlignHCenter + running: false + //visible: false + } + + ColumnLayout { + Button{ + id: button1 + text: "Running" + Layout.fillWidth: true + onClicked: { + busyIndicatorId.running = true + //busyIndicatorId.visible = true + + } + } + + Button { + id: button2 + text: "Not Running" + Layout.fillWidth: true + onClicked: { + busyIndicatorId.running = false + //busyIndicatorId.visible = false + + } + } + } + + /* + Item { + Layout.fillHeight: true + Layout.fillWidth: true + Rectangle { + anchors.fill: parent + color: "red" + } + } + */ + + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/main.cpp new file mode 100644 index 0000000..a512938 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/3-BusyIndicator/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-BusyIndicator", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/CMakeLists.txt new file mode 100644 index 0000000..545f011 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-CheckBox VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-CheckBox + main.cpp +) + +qt_add_qml_module(app4-CheckBox + URI 4-CheckBox + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-CheckBox PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-CheckBox + PRIVATE Qt6::Quick +) + +install(TARGETS app4-CheckBox + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/Main.qml new file mode 100644 index 0000000..0eabd81 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/Main.qml @@ -0,0 +1,39 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("CheckBox") + + Column { + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + + CheckBox { + text: "Option1" + checked: true + onCheckStateChanged: { + if (checked) + { + console.log("Option1 is checked") + }else{ + console.log("Option1 is unchecked") + } + } + } + CheckBox { + text: "Option2" + } + CheckBox { + text: "Option3" + checked: false + enabled: false + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/main.cpp new file mode 100644 index 0000000..62e4364 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/4-CheckBox/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-CheckBox", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/CMakeLists.txt new file mode 100644 index 0000000..cf79cfd --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-ComboBox VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-ComboBox + main.cpp +) + +qt_add_qml_module(app5-ComboBox + URI 5-ComboBox + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-ComboBox PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-ComboBox + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app5-ComboBox + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/Main.qml new file mode 100644 index 0000000..0ddfe8e --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/Main.qml @@ -0,0 +1,90 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("ComboBox") + + ColumnLayout{ + width: parent.width + height:parent.height + + //Non Editable ComboBox + + Label { + text: "Non Editable Combo" + wrapMode: Label.Wrap + //horizontalAlignment: Qt.AlignHCenter + //width: parent.width + Layout.fillWidth: true + } + + ComboBox { + id: nonEditableComboId + model: ["One", "Two", "Three", "Four"] + //anchors.horizontalCenter: parent.horizontalCenter + onActivated: { + console.log("[" + currentIndex +"] " + currentText + " is activated") + } + Layout.fillWidth: true + + } + + + + //Editable ComboBox + Label { + text: "Editable Combo" + wrapMode: Label.Wrap + Layout.fillWidth: true + } + + ComboBox { + id: editableComboId + editable: true + textRole : "text" + Layout.fillWidth: true + model: ListModel { + id : model + ListElement { text: "Dog"; location:"Kigali" } + ListElement { text: "Chicken"; location : "Beijing" } + ListElement { text: "Cat" ; location : "Mumbai" } + ListElement { text: "Meerkat" ; location : "Paris" } + } + + + onActivated: { + console.log("[" + currentIndex +"] " + currentText + " is activated") + } + + onAccepted: { + if ( find(editText) === -1) + { + model.append({text : editText , location : "US"}) + } + } + } + + + + Button{ + text : "Capture current element" + Layout.fillWidth: true + onClicked: { + console.log("[" + model.get(editableComboId.currentIndex).text +"]: " + + model.get(editableComboId.currentIndex).location) + } + } + + Item{ + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/main.cpp new file mode 100644 index 0000000..9c5e85a --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/5-ComboBox/main.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-ComboBox", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/CMakeLists.txt new file mode 100644 index 0000000..5b5e458 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-DelayButton VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-DelayButton + main.cpp +) + +qt_add_qml_module(app6-DelayButton + URI 6-DelayButton + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app6-DelayButton PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-DelayButton + PRIVATE Qt6::Quick +) + +install(TARGETS app6-DelayButton + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/Main.qml new file mode 100644 index 0000000..45af566 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/Main.qml @@ -0,0 +1,51 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("DelayButton") + + ColumnLayout { + width: parent.width + spacing: 40 + + Label { + width: parent.width + wrapMode: Label.Wrap + Layout.fillWidth: true + text: "Delayed Button. Use it when you want to prevent accidental clicks" + font.pointSize: 15 + } + + DelayButton { + property bool activated: false + text: "DelayButton" + Layout.fillWidth: true + delay: 1000 + + onPressed: { + if(activated === true) + { + console.log("Button is Clicked. Carrying out the task") + activated = false; + } + } + + onActivated: { + console.log("Button Activated") + activated = true + } + + onProgressChanged:{ + console.log(progress) + } + } + + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/main.cpp new file mode 100644 index 0000000..7d8b771 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/6-DelayButton/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-DelayButton", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/CMakeLists.txt new file mode 100644 index 0000000..22ef7dd --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(7-Dial VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app7-Dial + main.cpp +) + +qt_add_qml_module(app7-Dial + URI 7-Dial + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app7-Dial PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-Dial + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app7-Dial + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/Main.qml new file mode 100644 index 0000000..b0fc9b1 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/Main.qml @@ -0,0 +1,39 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Dial") + + Column { + width: parent.width + spacing: 40 + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A Knob used to let the user choose a value from a range" + font.pointSize: 15 + } + + Dial{ + anchors.horizontalCenter: parent.horizontalCenter + from: 1 + to: 100 + value: 50 + wrap: true + + onValueChanged: { + console.log(" Current value: " + Math.ceil(value)) + } + + } + + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/main.cpp new file mode 100644 index 0000000..a4a718a --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/7-Dial/main.cpp @@ -0,0 +1,23 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + //Load our style + QQuickStyle::setStyle("Material"); + + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("7-Dial", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/CMakeLists.txt new file mode 100644 index 0000000..ffa7f71 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(8-Frame VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app8-Frame + main.cpp +) + +qt_add_qml_module(app8-Frame + URI 8-Frame + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app8-Frame PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app8-Frame + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app8-Frame + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/Main.qml new file mode 100644 index 0000000..c3af49b --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/Main.qml @@ -0,0 +1,31 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Frame") + + Frame { + anchors.centerIn: parent + + ColumnLayout { + + Button { + text: "Button1" + } + Button { + text: "Button2" + } + Button { + text: "Button3" + } + + } + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/main.cpp new file mode 100644 index 0000000..171aac7 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/8-Frame/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Universal"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("8-Frame", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/CMakeLists.txt b/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/CMakeLists.txt new file mode 100644 index 0000000..af0aa30 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(9-GroupBoxRadioCheckButton VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app9-GroupBoxRadioCheckButton + main.cpp +) + +qt_add_qml_module(app9-GroupBoxRadioCheckButton + URI 9-GroupBoxRadioCheckButton + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app9-GroupBoxRadioCheckButton PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app9-GroupBoxRadioCheckButton + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app9-GroupBoxRadioCheckButton + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/Main.qml b/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/Main.qml new file mode 100644 index 0000000..5a6a21b --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/Main.qml @@ -0,0 +1,83 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("GroupBox") + + Column{ + spacing: 10 + anchors.fill: parent + + //RadioButton controls + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A GroupBox wrapping around RadioButtons." + } + + GroupBox{ + title: "Choose bonus" + anchors.horizontalCenter: parent.horizontalCenter + Column{ + + RadioButton{ + text: "Coke" + onCheckedChanged: { + if( checked){ + console.log("Coke button checked") + }else{ + console.log("Coke button is NOT checked") + } + } + } + RadioButton{ + text: "Green Tea" + } + RadioButton{ + text: "Ice Cream" + } + } + } + + //CheckBox Controls + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "A GroupBox wrapping around CheckBoxes." + } + + + GroupBox{ + title: "Choose Qt supported Desktop Platform" + anchors.horizontalCenter: parent.horizontalCenter + Column{ + + CheckBox{ + text: "Windows" + onCheckedChanged: { + if( checked){ + console.log("Windows button checked") + }else{ + console.log("Windows button is NOT checked") + } + } + } + CheckBox{ + text: "Mac" + } + CheckBox{ + text: "Linux" + } + } + } + + } +} diff --git a/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/main.cpp b/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/main.cpp new file mode 100644 index 0000000..96b05c0 --- /dev/null +++ b/Qt6QMLBeginnersCode/8-QtQuickControls/9-GroupBoxRadioCheckButton/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Universal"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("9-GroupBoxRadioCheckButton", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/CMakeLists.txt b/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/CMakeLists.txt new file mode 100644 index 0000000..9f1f6cf --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(2-ColorDialog VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app2-ColorDialog + main.cpp +) + +qt_add_qml_module(app2-ColorDialog + URI 2-ColorDialog + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app2-ColorDialog PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app2-ColorDialog + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app2-ColorDialog + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/Main.qml b/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/Main.qml new file mode 100644 index 0000000..cef7f61 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/Main.qml @@ -0,0 +1,48 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + + +import QtQuick +import QtQuick.Dialogs +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("ColorDialog") + + Column { + spacing: 20 + anchors.centerIn: parent + + Button{ + text : "Choose Color" + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + colorDialogId.open() + } + } + Rectangle{ + width: 200 + height: 200 + id : rectangleId + border.color: "black" + border.width: 8 + anchors.horizontalCenter: parent.horizontalCenter + } + + ColorDialog{ + id: colorDialogId + title: "Please choose a color" + onAccepted: { + console.log("User chose color: "+ selectedColor) + rectangleId.color = selectedColor + + } + onRejected: { + console.log("User rejected dialog") + } + } + } +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/main.cpp b/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/main.cpp new file mode 100644 index 0000000..b37b78a --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/2-ColorDialog/main.cpp @@ -0,0 +1,21 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Fusion"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("2-ColorDialog", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/CMakeLists.txt b/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/CMakeLists.txt new file mode 100644 index 0000000..ffd7271 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(3-FileDialog VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app3-FileDialog + main.cpp +) + +qt_add_qml_module(app3-FileDialog + URI 3-FileDialog + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app3-FileDialog PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app3-FileDialog + PRIVATE Qt6::Quick +) + +install(TARGETS app3-FileDialog + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/Main.qml b/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/Main.qml new file mode 100644 index 0000000..7ba7595 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/Main.qml @@ -0,0 +1,70 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Dialogs + + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("FileDialog") + + Column { + spacing: 20 + anchors.centerIn: parent + + Button{ + text: "Choose File" + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + fileDialogId.open() + } + } + + Text { + id: textId + text: "Use hasn't chosen yet" + wrapMode: Text.Wrap + } + + FileDialog{ + id: fileDialogId + title: "Choose File" + nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)", "Images (*.jpg *.png)"] + + onAccepted: { + textId.text = selectedFile + } + + onRejected: { + textId.text = "Dialog rejected" + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/main.cpp b/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/main.cpp new file mode 100644 index 0000000..3df30cb --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/3-FileDialog/main.cpp @@ -0,0 +1,20 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("3-FileDialog", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/CMakeLists.txt b/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/CMakeLists.txt new file mode 100644 index 0000000..2abb8c6 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(4-FolderDialog VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app4-FolderDialog + main.cpp +) + +qt_add_qml_module(app4-FolderDialog + URI 4-FolderDialog + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app4-FolderDialog PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app4-FolderDialog + PRIVATE Qt6::Quick +) + +install(TARGETS app4-FolderDialog + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/Main.qml b/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/Main.qml new file mode 100644 index 0000000..06bc043 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/Main.qml @@ -0,0 +1,70 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Dialogs + + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("FolderDialog") + + Column { + spacing: 20 + anchors.centerIn: parent + + Button{ + text: "Choose Folder" + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + folderDialogId.open() + } + } + + Text { + id: textId + text : "Use hasn't chosen yet" + wrapMode: Text.Wrap + } + + FolderDialog{ + id: folderDialogId + title: "Choose Folder" + + onAccepted: { + textId.text = selectedFolder + + } + + onRejected: { + textId.text = "Dialog rejected" + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/main.cpp b/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/main.cpp new file mode 100644 index 0000000..c16e6b3 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/4-FolderDialog/main.cpp @@ -0,0 +1,19 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("4-FolderDialog", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/CMakeLists.txt b/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/CMakeLists.txt new file mode 100644 index 0000000..e74680f --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(5-FontDialog VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app5-FontDialog + main.cpp +) + +qt_add_qml_module(app5-FontDialog + URI 5-FontDialog + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app5-FontDialog PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app5-FontDialog + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app5-FontDialog + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/Main.qml b/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/Main.qml new file mode 100644 index 0000000..eb71adc --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/Main.qml @@ -0,0 +1,76 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtQuick.Dialogs +import QtQuick.Controls + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("FontDialog Demo") + + Column { + spacing: 20 + anchors.centerIn: parent + + Button{ + text: "Change Font" + anchors.horizontalCenter: parent.horizontalCenter + onClicked: { + fontDialogId.open() + } + } + + Text { + id: textId + text: "Hello World" + } + + FontDialog{ + id: fontDialogId + title: "Choose Font" + currentFont: Qt.font({ family: "Arial", pointSize: 24, weight: Font.Normal }) + + onAccepted: { + console.log("Chose font: "+selectedFont) + textId.font = fontDialogId.selectedFont + } + onRejected: { + console.log("Dialog rejected") + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/main.cpp b/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/main.cpp new file mode 100644 index 0000000..0b1df7e --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/5-FontDialog/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Fusion"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("5-FontDialog", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/CMakeLists.txt b/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/CMakeLists.txt new file mode 100644 index 0000000..50390da --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(6-MessageDialog VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app6-MessageDialog + main.cpp +) + +qt_add_qml_module(app6-MessageDialog + URI 6-MessageDialog + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app6-MessageDialog PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app6-MessageDialog + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app6-MessageDialog + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/Main.qml b/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/Main.qml new file mode 100644 index 0000000..8d33e2f --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/Main.qml @@ -0,0 +1,34 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Dialogs + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("MessageDialog ") + + Button{ + text: "Push Me" + onClicked: { + messageDialog.open() + } + } + + MessageDialog { + id: messageDialog + title: "Message" + text: "Lie down and watch the sky." + buttons: MessageDialog.Ok | MessageDialog.Close + onAccepted: { + console.log("Dialog accepted.") + } + onRejected: { + console.log("Dialog rejected") + } + } +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/main.cpp b/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/main.cpp new file mode 100644 index 0000000..fb91c11 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/6-MessageDialog/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Fusion"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("6-MessageDialog", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/CMakeLists.txt b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/CMakeLists.txt new file mode 100644 index 0000000..882aecf --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) Daniel Gakwaya. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.16) + +project(7-CustomDialog VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_AUTORCC ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Qt6 6.5 REQUIRED COMPONENTS Quick QuickControls2) + +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(app7-CustomDialog + main.cpp resource.qrc +) + +qt_add_qml_module(app7-CustomDialog + URI 7-CustomDialog + VERSION 1.0 + QML_FILES Main.qml +) + +set_target_properties(app7-CustomDialog PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + MACOSX_BUNDLE TRUE + WIN32_EXECUTABLE TRUE +) + +target_link_libraries(app7-CustomDialog + PRIVATE Qt6::Quick Qt6::QuickControls2 +) + +install(TARGETS app7-CustomDialog + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/Main.qml b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/Main.qml new file mode 100644 index 0000000..8414d49 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/Main.qml @@ -0,0 +1,196 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +import QtQuick +import QtQuick.Window +import QtQuick.Controls +import QtQuick.Layouts + +Window { + visible: true + width: 640 + height: 480 + title: qsTr("Custom Dialogs") + + readonly property int buttonWidth: 300 + + + Column { + spacing: 20 + width:parent.width + + + Label { + width: parent.width + wrapMode: Label.Wrap + horizontalAlignment: Qt.AlignHCenter + text: "Dialog is a popup that is mostly used for short-term tasks " + + "and brief communications with the user." + } + + Button { + text: "Message" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: messageDialog.open() + + Dialog { + id: messageDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + + title: "Message" + + Label { + text: "Lorem ipsum dolor sit amet..." + } + } + } + + + + + Button { + id: button + text: "Confirmation" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: confirmationDialog.open() + + Dialog { + id: confirmationDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + modal: true + title: "Confirmation" + standardButtons: Dialog.Yes | Dialog.No + + Column { + spacing: 20 + anchors.fill: parent + Label { + text: "The document has been modified.\nDo you want to save your changes?" + } + CheckBox { + text: "Do not ask again" + anchors.right: parent.right + } + } + } + } + + + + + Button { + text: "Content" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: contentDialog.open() + + Dialog { + id: contentDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + width: Math.min(parent.width, parent.height) / 3 * 2 + //contentHeight: logo.height * 2 // This causes a binding loop + contentHeight: parent.height/2 // This doesn't cause the binding loop. + parent: Overlay.overlay + + modal: true + title: "Content" + standardButtons: Dialog.Close + + Flickable { + id: flickable + clip: true + anchors.fill: parent + contentHeight: column.height + + Column { + id: column + spacing: 20 + width: parent.width + + Image { + id: logo + width: parent.width / 2 + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + source: "qrc:/images/LearnQtLogo.png" + } + + Label { + width: parent.width + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc finibus " + + "in est quis laoreet. Interdum et malesuada fames ac ante ipsum primis " + + "in faucibus. Curabitur eget justo sollicitudin enim faucibus bibendum. " + + "Suspendisse potenti. Vestibulum cursus consequat mauris id sollicitudin. " + + "Duis facilisis hendrerit consectetur. Curabitur sapien tortor, efficitur " + + "id auctor nec, efficitur et nisl. Ut venenatis eros in nunc placerat, " + + "eu aliquam enim suscipit." + wrapMode: Label.Wrap + } + } + + ScrollIndicator.vertical: ScrollIndicator { + parent: contentDialog.contentItem + anchors.top: flickable.top + anchors.bottom: flickable.bottom + anchors.right: parent.right + anchors.rightMargin: -contentDialog.rightPadding + 1 + } + } + } + } + + + + + Button { + text: "Input" + anchors.horizontalCenter: parent.horizontalCenter + width: buttonWidth + onClicked: inputDialog.open() + + Dialog { + id: inputDialog + + x: (parent.width - width) / 2 + y: (parent.height - height) / 2 + parent: Overlay.overlay + + focus: true + modal: true + title: "Input" + standardButtons: Dialog.Ok | Dialog.Cancel + + ColumnLayout { + spacing: 20 + anchors.fill: parent + Label { + elide: Label.ElideRight + text: "Please enter the credentials:" + Layout.fillWidth: true + } + TextField { + focus: true + placeholderText: "Username" + Layout.fillWidth: true + } + TextField { + placeholderText: "Password" + echoMode: TextField.PasswordEchoOnEdit + Layout.fillWidth: true + } + } + } + } + + } +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/images/LearnQtLogo.png b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/images/LearnQtLogo.png new file mode 100644 index 0000000..3a83bd2 Binary files /dev/null and b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/images/LearnQtLogo.png differ diff --git a/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/main.cpp b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/main.cpp new file mode 100644 index 0000000..d78da17 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/main.cpp @@ -0,0 +1,22 @@ +// Copyright (c) Daniel Gakwaya. +// SPDX-License-Identifier: MIT + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + QQuickStyle::setStyle("Material"); + QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, + &app, []() { QCoreApplication::exit(-1); }, + Qt::QueuedConnection); + engine.loadFromModule("7-CustomDialog", "Main"); + + return app.exec(); +} diff --git a/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/resource.qrc b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/resource.qrc new file mode 100644 index 0000000..7b43603 --- /dev/null +++ b/Qt6QMLBeginnersCode/9-Dialogs/7-CustomDialog/resource.qrc @@ -0,0 +1,5 @@ + + + images/LearnQtLogo.png + + diff --git a/Qt6QMLBeginnersCode/LICENSE.txt b/Qt6QMLBeginnersCode/LICENSE.txt new file mode 100644 index 0000000..dc3efb8 --- /dev/null +++ b/Qt6QMLBeginnersCode/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Daniel Gakwaya + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Qt6QMLBeginnersCode/README.md b/Qt6QMLBeginnersCode/README.md new file mode 100644 index 0000000..65b2fef Binary files /dev/null and b/Qt6QMLBeginnersCode/README.md differ diff --git a/Qt6QMLBeginnersCode/errata.md b/Qt6QMLBeginnersCode/errata.md new file mode 100644 index 0000000..2ab9d8f --- /dev/null +++ b/Qt6QMLBeginnersCode/errata.md @@ -0,0 +1,13 @@ +# Errata + +This file describes inaccuracies, typos, errors in Qt6 QML For Beginners, by Daniel Gakwaya. + +Please specify the chapter and page where you spotted the issue, following the format shown below. You can clone the repo and add the issue to this file and then send us a pull request. The other option is to submit your errata info as a github issue. Our team will then reproduce the information in this file for you. Thanks for helping us make this book better. + +### Page 41, Chapter 2. +* Description: This is just an example of an issue +* PROBLEM: The text says ...create a qt creator project... +* CORRECTION: It should say ... create a Qt Creator project... +* You can use markdown to format code if it's needed. + +