Compare commits

..

20 commits

Author SHA1 Message Date
Steru fdd653c665 fix. 2024-08-26 11:19:38 +02:00
Orangerot d0df3af583 fix(EventInfoPage): show comptitor statistics 2024-08-26 11:19:38 +02:00
Steru b672b4698c Compacted competitors into one object, deleted API class (now in sportmodel). 2024-08-26 11:19:38 +02:00
Steru cd69d72271 Integrated Sport class into SportModel class. 2024-08-26 11:19:38 +02:00
Steru fe6a2c883d Added missing pictograms.# 2024-08-26 11:19:38 +02:00
Steru 37b47b9374 Fixed iteration over QList. 2024-08-26 11:19:38 +02:00
Steru d40fcd9017 Fixed constructors. 2024-08-26 11:19:38 +02:00
Steru b6c86f02ff Made Competitor a QObject and tidied up some code. 2024-08-26 11:19:38 +02:00
Steru db2d0c21c4 Added pragma once to headers and notify to Q Params. 2024-08-26 11:19:38 +02:00
Steru df2cd32539 Reworked Sport class to work with QObjects instead of JSON objects. 2024-08-26 11:19:38 +02:00
Steru 87e9d4aa8b Added Q Object macros. 2024-08-26 11:19:38 +02:00
Orangerot 2aea4f96f5 feat(README): explaination 2024-08-26 11:19:38 +02:00
Orangerot cbdd9391df fix(README): add image captions 2024-08-26 11:19:38 +02:00
Orangerot 335ccb8018 feat(README): screenshot galery 2024-08-26 11:19:38 +02:00
Orangerot b496b7df24 fix(CMakeLists): spellng mstke (its a challange) 2024-08-26 11:19:38 +02:00
Orangerot 58e390d3a0 feat(README): UML Diagram 2024-08-26 11:19:38 +02:00
Orangerot cfc9aa8a44 feat(README): documentation 2024-08-26 11:19:31 +02:00
Orangerot d97283a380 fix(EventsPage): set default discipline to Archerie on start 2024-08-16 18:13:50 +02:00
Orangerot 4c5cd95b85 feat(SportFilter): search/filter events from TextField 2024-08-16 18:03:26 +02:00
Orangerot f87bc73c3f fix(Sport): disciplineChanged notification 2024-08-16 16:17:16 +02:00
12 changed files with 216 additions and 25 deletions

View file

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.28)
project(itat_challange_olympics)
project(itat_challenge_olympics)
find_package(Qt6 6.2 COMPONENTS Core Quick Quick REQUIRED)
@ -8,12 +8,12 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
qt_add_executable(itat_challange_olympics src/main/main.cpp
qt_add_executable(itat_challenge_olympics src/main/main.cpp
application.qrc
)
qt_add_qml_module(itat_challange_olympics
qt_add_qml_module(itat_challenge_olympics
URI itat
QML_FILES
res/gui/application.qml
@ -25,6 +25,8 @@ qt_add_qml_module(itat_challange_olympics
src/model/Competitor.h
src/model/EventInfo.cpp
src/model/EventInfo.h
src/model/FilterModel.cpp
src/model/FilterModel.h
src/model/SportModel.cpp
src/model/SportModel.h
@ -80,6 +82,6 @@ qt_add_qml_module(itat_challange_olympics
res/pictograms/WRG_small.svg
)
target_link_libraries(itat_challange_olympics PRIVATE Qt6::Core Qt6::Quick Qt6::Network)
target_link_libraries(itat_challenge_olympics PRIVATE Qt6::Core Qt6::Quick Qt6::Network)
# target_link_libraries(itat_challange_olympics PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib dxguid.lib)
# target_link_libraries(itat_challenge_olympics PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib dxguid.lib)

170
README.md Normal file
View file

@ -0,0 +1,170 @@
# Olympia 2024 Events
> View updated Events with its Competitors and Rankings of all Disciplines
*Olympia 2024 Events* always displays up to date information of the 2024
Olympics in Paris. It achieves this by fetching the `olympics.com` API.
We use the Model-View-Delegate pattern to synchronize the API data in C++ with
the UI-Widgets defined in QML. For this we implement the API data as a Model
which can be seen and interacted with by QML Components.
All code, qml definitions and images, etc are compiled into a single binary that
is not dependent on any resources on relative paths anymore.
On startup the default discipline *Archery* will be fetched and shown on the
EventsPage. From here the user has three options. You can change the discipline
from the Dropdown-Menu (Combobox) in the top left (also note the changing
pictograms of the discipline); Filter the EventNames with the Search field in
the top right; or click on an Event.
When clicking on an Event, the user is redirected to the EventInfoPage. Here you
can see Information about all Competitors that took part in the Event. When you
are done, you can go back to the EventsPage with the button in the top left.
## Galery
<table>
<tr>
<td><img src="doc/events_page_combobox.png"/></td>
<td><img src="doc/events_page_textfield.png"/></td>
<td><img src="doc/event_info.png"/></td>
</tr>
<tr>
<td>Select discipline</td>
<td>Filter by Event</td>
<td>View Competitor</td>
</tr>
</table>
## Getting Started
### Dependencies
- Qt6
### Installation
```sh
git clone git@gitlab.kit.edu:ugmgt/itat_challenge_2024.git
# or download release
cd itat_challenge_2024
cmake -B build
cmake --build build
./build/itat_challenge_olympics
```
## Code Structure
### UML Diagram
```plantuml
@startuml
allowmixing
set namespaceSeparator none
skinparam ranksep 10
package C++ <<Frame>> {
class Application {
QGuiApplication app
QmlComponent component
SportModel model
FilterModel<SportModel> filter
}
class SportModel {
String discipline
<EventInfo> model
request(String discipline)
parseData()
}
class FilterModel {
void setFilterFixedString(String)
}
class EventInfo {
String eventName
List<Competitor> competitors
}
class Competitor {
String name
String code
String noc
}
}
package QML <<Frame>> {
component EventInfoPage {
component [Page] as EIPage {
component [ToolBar] as EIToolBar
component [ListView] as EILisView
}
}
EIToolBar -[hidden]- EILisView
component EventsPage {
component [Page] as EPage {
component [ToolBar] as EToolBar
component [Column] as EColumn {
component [Row] as ERow {
component [ComboBox] as EComboBox
component [TextField] as ETextField
}
component [ListView] as EListView
}
}
}
EToolBar -[hidden]- EColumn
ERow -[hidden]- EListView
component application.qml {
component ApplicationWindow {
component StackView
}
}
}
'application.qml -u- a
'Application -r- a
Application *-- "1" SportModel
Application *-- "1" FilterModel
FilterModel "1" o-- "1" SportModel
SportModel *-- "0..*" EventInfo
EventInfo *-- "0..*" Competitor
Application <.l. application.qml
StackView <.. EventInfoPage
StackView <.. EventsPage
EComboBox "request()" .> SportModel
EComboBox -[hidden]u- ETextField
SportModel "View" .> EListView
FilterModel "View" .> EListView
ETextField "Control" .r.> FilterModel
EILisView <. "View" Competitor
cloud api.olympics.com
() REST
REST - api.olympics.com
SportModel -( REST
application.qml -[hidden]u- Application
@enduml
```
## Authors
- **Silas Stulz** - *Initial Work*
- **Gero Beckmann** - *Initial Work*

BIN
doc/event_info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View file

@ -26,10 +26,10 @@ Page {
ComboBox {
width: 200
width: 300
height: 50
displayText: "Disziplin: " + currentText
displayText: "Discipline: " + currentText
model: myListModel
textRole: "text"
@ -228,7 +228,7 @@ Page {
api: "WRG"
}
}
Component.onCompleted: currentIndex = 5;
onActivated: {
if (currentIndex >= 0) {
console.log(currentValue.api);
@ -236,22 +236,11 @@ Page {
}
}
}
ComboBox {
width: 200
TextField {
height: 50
displayText: "Sort by: " + currentText
model: ["hu", "hi"]
}
ComboBox {
width: 200
height: 50
displayText: "Filter: " + currentText
model: ["hu", "hi"]
placeholderText: "Search"
onTextChanged: filter.setFilterFixedString(text)
}
}
@ -262,7 +251,7 @@ Page {
height: parent.height
width: parent.width
spacing: 20
model: sports
model: filter
delegate: ItemDelegate {
required property string eventName
required property list<QtObject> competitors

View file

@ -20,6 +20,7 @@
// console output
#include <QDebug>
// #include <iostream>
#include "../model/FilterModel.h"
#include "../model/SportModel.h"
int main(int argc, char *argv[])
@ -31,7 +32,10 @@ int main(int argc, char *argv[])
SportModel model;
model.request("ARC");
FilterModel filter;
filter.setSourceModel(&model);
objectContext->setContextProperty("sports", &model);
objectContext->setContextProperty("filter", &filter);
QQmlComponent component(&engine, "qrc:/qt/qml/itat/res/gui/application.qml");
QObject *object = component.create(objectContext);

View file

@ -0,0 +1,8 @@
#include "FilterModel.h"
#include "SportModel.h"
FilterModel::FilterModel(QObject *parent)
: QSortFilterProxyModel(parent) {
setFilterRole(SportModel::Role::EventName);
}

14
src/model/FilterModel.h Normal file
View file

@ -0,0 +1,14 @@
#include <QSortFilterProxyModel>
#pragma once
class FilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
FilterModel(QObject *parent = nullptr);
private:
};

0
src/model/Sport.h Normal file
View file

View file

@ -63,11 +63,12 @@ QString SportModel::discipline() const {
void SportModel::setDiscipline(const QString &discipline) {
m_discipline = discipline;
disciplineChanged();
}
void SportModel::request(QString discipline) {
m_discipline = discipline;
setDiscipline(discipline);
m_reply = m_networkManager.get(QNetworkRequest( k_requestUrl + m_discipline));
qDebug() << m_reply;
connect(m_reply, &QNetworkReply::finished, this, &SportModel::parseData);

View file

@ -17,7 +17,7 @@ class SportModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QString discipline READ discipline WRITE setDiscipline);
Q_PROPERTY(QString discipline READ discipline WRITE setDiscipline NOTIFY disciplineChanged);
public:
enum Role
@ -62,6 +62,9 @@ public slots:
void request(QString discipline);
void parseData();
signals:
void disciplineChanged();
private:
QList<EventInfo *> m_sportList;
QString m_discipline;