Compare commits
10 commits
main
...
steru-back
Author | SHA1 | Date | |
---|---|---|---|
Orangerot | b93da90cae | ||
100e73ec28 | |||
b0063e9641 | |||
884280076a | |||
c6463514b9 | |||
3918de89ce | |||
66d5d8685f | |||
b49c066bd5 | |||
c527aec94d | |||
5f4431e19c |
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.28)
|
cmake_minimum_required(VERSION 3.28)
|
||||||
project(itat_challenge_olympics)
|
project(itat_challange_olympics)
|
||||||
|
|
||||||
find_package(Qt6 6.2 COMPONENTS Core Quick Quick REQUIRED)
|
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_AUTORCC ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
qt_add_executable(itat_challenge_olympics src/main/main.cpp
|
qt_add_executable(itat_challange_olympics src/main/main.cpp
|
||||||
application.qrc
|
application.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
qt_add_qml_module(itat_challenge_olympics
|
qt_add_qml_module(itat_challange_olympics
|
||||||
URI itat
|
URI itat
|
||||||
QML_FILES
|
QML_FILES
|
||||||
res/gui/application.qml
|
res/gui/application.qml
|
||||||
|
@ -25,8 +25,6 @@ qt_add_qml_module(itat_challenge_olympics
|
||||||
src/model/Competitor.h
|
src/model/Competitor.h
|
||||||
src/model/EventInfo.cpp
|
src/model/EventInfo.cpp
|
||||||
src/model/EventInfo.h
|
src/model/EventInfo.h
|
||||||
src/model/FilterModel.cpp
|
|
||||||
src/model/FilterModel.h
|
|
||||||
src/model/SportModel.cpp
|
src/model/SportModel.cpp
|
||||||
src/model/SportModel.h
|
src/model/SportModel.h
|
||||||
|
|
||||||
|
@ -82,6 +80,6 @@ qt_add_qml_module(itat_challenge_olympics
|
||||||
res/pictograms/WRG_small.svg
|
res/pictograms/WRG_small.svg
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(itat_challenge_olympics PRIVATE Qt6::Core Qt6::Quick Qt6::Network)
|
target_link_libraries(itat_challange_olympics PRIVATE Qt6::Core Qt6::Quick Qt6::Network)
|
||||||
|
|
||||||
# target_link_libraries(itat_challenge_olympics PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib dxguid.lib)
|
# target_link_libraries(itat_challange_olympics PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib dxguid.lib)
|
||||||
|
|
170
README.md
170
README.md
|
@ -1,170 +0,0 @@
|
||||||
# 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*
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 19 KiB |
Binary file not shown.
Before Width: | Height: | Size: 49 KiB |
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
|
@ -26,10 +26,10 @@ Page {
|
||||||
|
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
width: 300
|
width: 200
|
||||||
height: 50
|
height: 50
|
||||||
|
|
||||||
displayText: "Discipline: " + currentText
|
displayText: "Disziplin: " + currentText
|
||||||
model: myListModel
|
model: myListModel
|
||||||
textRole: "text"
|
textRole: "text"
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ Page {
|
||||||
api: "WRG"
|
api: "WRG"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component.onCompleted: currentIndex = 5;
|
|
||||||
onActivated: {
|
onActivated: {
|
||||||
if (currentIndex >= 0) {
|
if (currentIndex >= 0) {
|
||||||
console.log(currentValue.api);
|
console.log(currentValue.api);
|
||||||
|
@ -236,11 +236,22 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TextField {
|
ComboBox {
|
||||||
height: 50
|
|
||||||
width: 200
|
width: 200
|
||||||
placeholderText: "Search"
|
height: 50
|
||||||
onTextChanged: filter.setFilterFixedString(text)
|
|
||||||
|
displayText: "Sort by: " + currentText
|
||||||
|
model: ["hu", "hi"]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
width: 200
|
||||||
|
height: 50
|
||||||
|
|
||||||
|
displayText: "Filter: " + currentText
|
||||||
|
model: ["hu", "hi"]
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +262,7 @@ Page {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: 20
|
spacing: 20
|
||||||
model: filter
|
model: sports
|
||||||
delegate: ItemDelegate {
|
delegate: ItemDelegate {
|
||||||
required property string eventName
|
required property string eventName
|
||||||
required property list<QtObject> competitors
|
required property list<QtObject> competitors
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
// console output
|
// console output
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
// #include <iostream>
|
// #include <iostream>
|
||||||
#include "../model/FilterModel.h"
|
|
||||||
#include "../model/SportModel.h"
|
#include "../model/SportModel.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -32,10 +31,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
SportModel model;
|
SportModel model;
|
||||||
model.request("ARC");
|
model.request("ARC");
|
||||||
FilterModel filter;
|
|
||||||
filter.setSourceModel(&model);
|
|
||||||
objectContext->setContextProperty("sports", &model);
|
objectContext->setContextProperty("sports", &model);
|
||||||
objectContext->setContextProperty("filter", &filter);
|
|
||||||
|
|
||||||
QQmlComponent component(&engine, "qrc:/qt/qml/itat/res/gui/application.qml");
|
QQmlComponent component(&engine, "qrc:/qt/qml/itat/res/gui/application.qml");
|
||||||
QObject *object = component.create(objectContext);
|
QObject *object = component.create(objectContext);
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#include "FilterModel.h"
|
|
||||||
#include "SportModel.h"
|
|
||||||
|
|
||||||
FilterModel::FilterModel(QObject *parent)
|
|
||||||
: QSortFilterProxyModel(parent) {
|
|
||||||
setFilterRole(SportModel::Role::EventName);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class FilterModel : public QSortFilterProxyModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
FilterModel(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
|
@ -63,12 +63,11 @@ QString SportModel::discipline() const {
|
||||||
|
|
||||||
void SportModel::setDiscipline(const QString &discipline) {
|
void SportModel::setDiscipline(const QString &discipline) {
|
||||||
m_discipline = discipline;
|
m_discipline = discipline;
|
||||||
disciplineChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SportModel::request(QString discipline) {
|
void SportModel::request(QString discipline) {
|
||||||
setDiscipline(discipline);
|
m_discipline = discipline;
|
||||||
m_reply = m_networkManager.get(QNetworkRequest( k_requestUrl + m_discipline));
|
m_reply = m_networkManager.get(QNetworkRequest( k_requestUrl + m_discipline));
|
||||||
qDebug() << m_reply;
|
qDebug() << m_reply;
|
||||||
connect(m_reply, &QNetworkReply::finished, this, &SportModel::parseData);
|
connect(m_reply, &QNetworkReply::finished, this, &SportModel::parseData);
|
||||||
|
|
|
@ -17,7 +17,7 @@ class SportModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString discipline READ discipline WRITE setDiscipline NOTIFY disciplineChanged);
|
Q_PROPERTY(QString discipline READ discipline WRITE setDiscipline);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Role
|
enum Role
|
||||||
|
@ -62,9 +62,6 @@ public slots:
|
||||||
void request(QString discipline);
|
void request(QString discipline);
|
||||||
void parseData();
|
void parseData();
|
||||||
|
|
||||||
signals:
|
|
||||||
void disciplineChanged();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<EventInfo *> m_sportList;
|
QList<EventInfo *> m_sportList;
|
||||||
QString m_discipline;
|
QString m_discipline;
|
||||||
|
|
Loading…
Reference in a new issue