From e5bb24ba35bb8df011542203e42f362aa196e56b Mon Sep 17 00:00:00 2001
From: tobiglaser <76131623+tobiglaser@users.noreply.github.com>
Date: Tue, 14 Jun 2022 21:33:57 +0200
Subject: [PATCH] add ModelViewList example

---
 CMakeLists.txt               |  5 ++-
 ModelViewList/CMakeLists.txt | 63 ++++++++++++++++++++++++++++++++++++
 ModelViewList/control.cpp    | 36 +++++++++++++++++++++
 ModelViewList/control.h      | 28 ++++++++++++++++
 ModelViewList/main.cpp       | 17 ++++++++++
 ModelViewList/mainwindow.cpp | 30 +++++++++++++++++
 ModelViewList/mainwindow.h   | 22 +++++++++++++
 ModelViewList/model.cpp      | 19 +++++++++++
 ModelViewList/model.h        | 26 +++++++++++++++
 ModelViewList/myListItem.h   | 16 +++++++++
 10 files changed, 261 insertions(+), 1 deletion(-)
 create mode 100644 ModelViewList/CMakeLists.txt
 create mode 100644 ModelViewList/control.cpp
 create mode 100644 ModelViewList/control.h
 create mode 100644 ModelViewList/main.cpp
 create mode 100644 ModelViewList/mainwindow.cpp
 create mode 100644 ModelViewList/mainwindow.h
 create mode 100644 ModelViewList/model.cpp
 create mode 100644 ModelViewList/model.h
 create mode 100644 ModelViewList/myListItem.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c85bf1..2253d46 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,7 @@
 cmake_minimum_required(VERSION 3.5)
 
+project(qt-examples)
+
 add_subdirectory(Counter)
-add_subdirectory(Text2Console)
\ No newline at end of file
+add_subdirectory(Text2Console)
+add_subdirectory(ModelViewList)
\ No newline at end of file
diff --git a/ModelViewList/CMakeLists.txt b/ModelViewList/CMakeLists.txt
new file mode 100644
index 0000000..6bcc62e
--- /dev/null
+++ b/ModelViewList/CMakeLists.txt
@@ -0,0 +1,63 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(ModelViewList VERSION 0.1 LANGUAGES CXX)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
+find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
+
+set(PROJECT_SOURCES
+        main.cpp
+        mainwindow.cpp
+        mainwindow.h
+        model.h
+        model.cpp
+        control.h
+        control.cpp
+        myListItem.h
+)
+
+if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
+    qt_add_executable(ModelViewList
+        MANUAL_FINALIZATION
+        ${PROJECT_SOURCES}
+    )
+# Define target properties for Android with Qt 6 as:
+#    set_property(TARGET Text2Console APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
+# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
+else()
+    if(ANDROID)
+        add_library(ModelViewList SHARED
+            ${PROJECT_SOURCES}
+        )
+# Define properties for Android with Qt 5 after find_package() calls as:
+#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
+    else()
+        add_executable(ModelViewList
+            ${PROJECT_SOURCES}
+        )
+    endif()
+endif()
+
+target_link_libraries(ModelViewList PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
+
+set_target_properties(ModelViewList 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
+)
+
+if(QT_VERSION_MAJOR EQUAL 6)
+    qt_finalize_executable(ModelViewList)
+endif()
diff --git a/ModelViewList/control.cpp b/ModelViewList/control.cpp
new file mode 100644
index 0000000..9a92dd3
--- /dev/null
+++ b/ModelViewList/control.cpp
@@ -0,0 +1,36 @@
+#include "control.h"
+#include "myListItem.h"
+
+Control::Control(Model &model, MainWindow &view) : model(model), view(view)
+{
+    connect(view.qAddButton, SIGNAL(clicked()), this, SLOT(onAddButton()));
+    connect(view.qLineEdit, SIGNAL(returnPressed()), this, SLOT(onAddButton()));
+    connect(view.qRemButton, SIGNAL(clicked()), this, SLOT(onRemButton()));
+
+    connect(&model, SIGNAL(listChanged()), this, SLOT(onListChange()));
+}
+
+void Control::onAddButton()
+{
+    std::string s = view.qLineEdit->text().toStdString();
+    view.qLineEdit->clear();
+    if (!s.empty())
+        model.addNewItem(s);
+}
+
+void Control::onRemButton()
+{
+    uint index = view.qList->currentRow();
+    model.removeItem(index);
+}
+
+void Control::onListChange()
+{
+    auto vec = model.getVec();
+    view.qList->clear(); // This could use some more precision, but whatever.
+    for (auto &&i : vec)
+    {
+        myListItem *li = new myListItem(i);
+        view.qList->addItem(li);
+    }
+}
\ No newline at end of file
diff --git a/ModelViewList/control.h b/ModelViewList/control.h
new file mode 100644
index 0000000..356e179
--- /dev/null
+++ b/ModelViewList/control.h
@@ -0,0 +1,28 @@
+#ifndef CONTROL_H
+#define CONTROL_H
+
+#include <QObject>
+#include "model.h"
+#include "mainwindow.h"
+
+
+class Control : public QObject
+{
+    Q_OBJECT
+
+private:
+    MainWindow &view;
+    Model &model;
+
+
+public:
+    Control(Model &model, MainWindow &view);
+
+public slots:
+    void onAddButton();
+    void onRemButton();
+
+    void onListChange();
+};
+
+#endif //CONTROL_H
\ No newline at end of file
diff --git a/ModelViewList/main.cpp b/ModelViewList/main.cpp
new file mode 100644
index 0000000..828e7dd
--- /dev/null
+++ b/ModelViewList/main.cpp
@@ -0,0 +1,17 @@
+#include <QApplication>
+
+#include "mainwindow.h"
+#include "model.h"
+#include "control.h"
+
+
+int main(int argc, char *argv[])
+{
+    QApplication a(argc, argv);
+    Model model;
+    MainWindow view;
+    Control control(model, view);
+
+    view.show();
+    return a.exec();
+}
\ No newline at end of file
diff --git a/ModelViewList/mainwindow.cpp b/ModelViewList/mainwindow.cpp
new file mode 100644
index 0000000..44088c8
--- /dev/null
+++ b/ModelViewList/mainwindow.cpp
@@ -0,0 +1,30 @@
+#include <QBoxLayout>
+#include <QListWidget>
+#include "mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+{
+    //general
+    setWindowTitle("ModelViewList");
+
+    // Layout
+    QBoxLayout *layout = new QBoxLayout(QBoxLayout::Direction::TopToBottom);
+    QWidget *widget = new QWidget;
+    widget->setLayout(layout);
+    setCentralWidget(widget); // special for MainWindow
+
+    //TextField
+    qLineEdit = new QLineEdit();
+    layout->addWidget(qLineEdit);
+
+    // Buttons
+    qAddButton = new QPushButton("Add");
+    layout->addWidget(qAddButton);
+    qRemButton = new QPushButton("Remove");
+    layout->addWidget(qRemButton);
+
+    // List
+    qList = new QListWidget();
+    layout->addWidget(qList);
+}
\ No newline at end of file
diff --git a/ModelViewList/mainwindow.h b/ModelViewList/mainwindow.h
new file mode 100644
index 0000000..a59541d
--- /dev/null
+++ b/ModelViewList/mainwindow.h
@@ -0,0 +1,22 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QListWidget>
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    QLineEdit   *qLineEdit;
+    QPushButton *qAddButton;
+    QPushButton *qRemButton;
+    QListWidget *qList;
+
+    MainWindow(QWidget *parent = nullptr);
+};
+
+#endif // MAINWINDOW_H
diff --git a/ModelViewList/model.cpp b/ModelViewList/model.cpp
new file mode 100644
index 0000000..6a62359
--- /dev/null
+++ b/ModelViewList/model.cpp
@@ -0,0 +1,19 @@
+#include "model.h"
+
+
+void Model::addNewItem(std::string s)
+{
+    vec.emplace_back(s);
+    emit(listChanged());
+}
+
+void Model::removeItem(uint index)
+{
+    if (index < vec.size())
+    {
+        std::vector<std::string>::iterator it = vec.begin();
+        std::advance(it, index);
+        vec.erase(it);
+        emit(listChanged());
+    }
+}
\ No newline at end of file
diff --git a/ModelViewList/model.h b/ModelViewList/model.h
new file mode 100644
index 0000000..5948850
--- /dev/null
+++ b/ModelViewList/model.h
@@ -0,0 +1,26 @@
+#ifndef MODEL_H
+#define MODEL_H
+
+#include <vector>
+#include <iterator> 
+#include <string>
+#include <QObject>
+
+class Model : public QObject
+{
+    Q_OBJECT
+
+private:
+    std::vector<std::string> vec;
+
+public:
+    std::vector<std::string> getVec() { return vec; }
+
+    void addNewItem(std::string);
+    void removeItem(uint);
+
+signals:
+    void listChanged();
+};
+
+#endif //MODEL_H
\ No newline at end of file
diff --git a/ModelViewList/myListItem.h b/ModelViewList/myListItem.h
new file mode 100644
index 0000000..f1650c2
--- /dev/null
+++ b/ModelViewList/myListItem.h
@@ -0,0 +1,16 @@
+#ifndef MYLISTITEM_H
+#define MYLISTITEM_H
+
+#include <QListWidgetItem>
+#include <string>
+
+class myListItem : public QListWidgetItem
+{
+public:
+    myListItem(std::string &text)
+    {
+        setText(text.c_str());
+    };
+};
+
+#endif //MYLISTITEM_H
\ No newline at end of file
-- 
GitLab