This commit is contained in:
2025-09-28 17:05:51 +08:00
parent 8eb80ab66d
commit d97fa3e0fe
398 changed files with 18737 additions and 0 deletions

View File

@@ -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}
)

View File

@@ -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
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
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();
*/
}

View File

@@ -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}
)

View File

@@ -0,0 +1,18 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -0,0 +1,8 @@
import QtQuick
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
}

View File

@@ -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}
)

View File

@@ -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()
}
}
}
}

View File

@@ -0,0 +1,22 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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
}
}
}

View File

@@ -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}
)

View File

@@ -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.")
}
}

View File

@@ -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()
}
}
}
}

View File

@@ -0,0 +1,22 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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
}
}
}

View File

@@ -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}
)

View File

@@ -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.")
}
}

View File

@@ -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()
}
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -0,0 +1,22 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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
}
}
}

View File

@@ -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}
)

View File

@@ -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()
}
}
}

View File

@@ -0,0 +1,19 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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"))
}
}
}

View File

@@ -0,0 +1,21 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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}
)

View File

@@ -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)))
}
}
}

View File

@@ -0,0 +1,24 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
#include "tablemodel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<TableModel>("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();
}

View File

@@ -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<int, QByteArray> TableModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[TableDataRole] = "tabledata";
return roles;
}
QVariant TableModel::get_display_data(const QModelIndex &index){
return data(index,TableDataRole );
}

View File

@@ -0,0 +1,31 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QObject>
#include <QAbstractTableModel>
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<int, QByteArray> roleNames() const override;
Q_INVOKABLE
QVariant get_display_data(const QModelIndex& index);
private:
QVector<QVector<QString>> table;
};
#endif // TABLEMODEL_H

View File

@@ -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"

View File

@@ -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}
)

View File

@@ -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
}
}
}

View File

@@ -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()
}
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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()
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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)
}
}

View File

@@ -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()
}
}
}
}

View File

@@ -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}
)

View File

@@ -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)
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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)
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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
}
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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)
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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)
}
}
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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)
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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}
)

View File

@@ -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
}
}
}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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)
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
// Copyright (c) Daniel Gakwaya.
// SPDX-License-Identifier: MIT
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>xml/employees.xml</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,30 @@
<!-- Copyright (c) Daniel Gakwaya. -->
<!-- SPDX-License-Identifier: MIT -->
<?xml version="1.0" encoding="utf-8"?>
<courses>
<course>
<instructor>Matt Kabwe</instructor>
<year>2002</year>
<coursename hot ="true">Operating Systems</coursename >
</course>
<course>
<instructor>Daniel Gwo</instructor>
<year>2010</year>
<coursename hot = "false">Object Oriented Programming (Java)</coursename >
</course>
<course>
<instructor>Nathan Mepp</instructor>
<year>2011</year>
<coursename hot = "false">Embedded Systems</coursename >
</course>
<course >
<instructor>Lilian Gwiza</instructor>
<year>2015</year>
<coursename hot = "false">IT Project Management</coursename >
</course>
<course>
<instructor>John Wiks</instructor>
<year>2023</year>
<coursename hot = "true">C is Still King</coursename >
</course>
</courses>

View File

@@ -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}
)

View File

@@ -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}
}
}
}

View File

@@ -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)
}
}
}
}

View File

@@ -0,0 +1,19 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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()
}
}
}
}

View File

@@ -0,0 +1,19 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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
}
}
}
}

View File

@@ -0,0 +1,19 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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")
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

View File

@@ -0,0 +1,19 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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}
)

View File

@@ -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")
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

View File

@@ -0,0 +1,19 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

View File

@@ -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

View File

@@ -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}
)

View File

@@ -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
}
}
}

View File

@@ -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()
}
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -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()
}
}
}
}
}

View File

@@ -0,0 +1,22 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
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();
}

View File

@@ -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)
}
}

View File

@@ -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()
}
}
}
}

View File

@@ -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}
)

View File

@@ -0,0 +1,12 @@
import QtQuick
Rectangle{
id: rootId
signal clicked
MouseArea{
anchors.fill: parent
onClicked: function(){
rootId.clicked()
}
}
}

View File

@@ -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
}
}
}

View File

@@ -0,0 +1,19 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
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();
}

Some files were not shown because too many files have changed in this diff Show More