From 1b10d2841f0ff8a229cce5c44f9062f0a2142d67 Mon Sep 17 00:00:00 2001 From: Poleric Date: Fri, 5 Jun 2026 01:33:51 +0800 Subject: [PATCH] feat: add leaderboard --- .../gui/InventoryWars/IdleView.qml | 82 ++++++++++++++----- src/inventory_wars/gui/InventoryWars/Main.qml | 14 +++- src/inventory_wars/gui/app.py | 29 ++++++- 3 files changed, 99 insertions(+), 26 deletions(-) diff --git a/src/inventory_wars/gui/InventoryWars/IdleView.qml b/src/inventory_wars/gui/InventoryWars/IdleView.qml index 2036ef9..fcb2346 100644 --- a/src/inventory_wars/gui/InventoryWars/IdleView.qml +++ b/src/inventory_wars/gui/InventoryWars/IdleView.qml @@ -13,6 +13,7 @@ Rectangle { color: UIStyle.background + required property SqlLeaderboardModel leaderboard required property ListModel rounds property QtObject selectedRound @@ -66,41 +67,80 @@ Rectangle { } } - TableView { + Label { + Layout.alignment: Qt.AlignHCenter + + font.pixelSize: UIStyle.fontSizeL + color: UIStyle.titletextColor + + text: "Leaderboard" + } + + ColumnLayout { Layout.fillHeight: true + Layout.fillWidth: true + spacing: -1 - columnSpacing: 1 - rowSpacing: 1 + HorizontalHeaderView { + Layout.fillWidth: true + syncView: tableView + clip: true + columnSpacing: -1 + rowSpacing: -1 + boundsBehavior: Flickable.StopAtBounds - delegate: Rectangle { - border.width: 1 - implicitHeight: 50 - implicitWidth: 100 + rowHeightProvider: function (row) { + return 35 + } - Text { - anchors.centerIn: parent - text: display + delegate: Rectangle { + border.width: 1 + color: "#f1f1f1" + + Text { + anchors.centerIn: parent + font.bold: true + text: display + } } } - model: TableModel { - rows: [ - { - User: "me", - Score: "1" - } - ] + TableView { + id: tableView - TableModelColumn { - display: "User" + Layout.fillHeight: true + Layout.fillWidth: true + clip: true + columnSpacing: -1 + rowSpacing: -1 + boundsBehavior: Flickable.StopAtBounds + + model: leaderboard + + columnWidthProvider: function (column) { + if (column === 0) + return tableView.width * 0.6 + return tableView.width * 0.4 + } + rowHeightProvider: function (row) { + return 35 } - TableModelColumn { - display: "Score" + onWidthChanged: tableView.forceLayout() + + delegate: Rectangle { + border.width: 1 + + Text { + anchors.centerIn: parent + text: display + } } } } + + Item { Layout.fillHeight: true } } } diff --git a/src/inventory_wars/gui/InventoryWars/Main.qml b/src/inventory_wars/gui/InventoryWars/Main.qml index 4c80814..d30ed44 100644 --- a/src/inventory_wars/gui/InventoryWars/Main.qml +++ b/src/inventory_wars/gui/InventoryWars/Main.qml @@ -18,11 +18,11 @@ ApplicationWindow { ListElement { name: "Round 1" - mode: GameService.GameScoring.FirstGuess - item_id: 100 - item_name: "Item 1" + mode: GameService.GameScoring.FirstGuessThenHighestAmount + item_id: 1061153 + item_name: "Dreamweave Silk Selection Gift Box" item_image: "" - clue: "Clue 1" + clue: "Dreamweave Silk Selection Gift Box" } ListElement { name: "Round 2" @@ -50,11 +50,16 @@ ApplicationWindow { } } + SqlLeaderboardModel { + id: leaderboard + } + IdleView { id: idleView anchors.fill: parent + leaderboard: leaderboard rounds: rounds selectedRound: rounds.get(0) onRoundSelected: { @@ -75,6 +80,7 @@ ApplicationWindow { onClose: { idleView.visible = true ongoingView.visible = false + leaderboard.select() } } diff --git a/src/inventory_wars/gui/app.py b/src/inventory_wars/gui/app.py index c8af7b1..38554de 100644 --- a/src/inventory_wars/gui/app.py +++ b/src/inventory_wars/gui/app.py @@ -3,9 +3,10 @@ import sys from datetime import datetime from enum import Enum -from PySide6.QtCore import QObject, Signal, Slot, Property, QEnum +from PySide6.QtCore import QObject, Signal, Slot, Property, QEnum, Qt, QCoreApplication from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QQmlApplicationEngine, QmlElement +from PySide6.QtSql import QSqlTableModel, QSqlDatabase from sqlalchemy import create_engine from sqlalchemy.orm import Session from star_resonance_tracer.proto.enum_chit_chat_channel_type_pb2 import ChitChatChannelType @@ -145,14 +146,40 @@ class GameService(QObject): return 0 +@QmlElement +class SqlLeaderboardModel(QSqlTableModel): + def __init__(self, parent=None): + super().__init__(parent) + + self.setTable("v_score") + self.setSort(2, Qt.SortOrder.DescendingOrder) + self.setHeaderData(0, Qt.Orientation.Horizontal, "User") + self.setHeaderData(1, Qt.Orientation.Horizontal, "Score") + + self.select() + + +logger = logging.getLogger(__name__) + if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) app = QGuiApplication(sys.argv) + QCoreApplication.setApplicationName("Inventory Wars") + + database = QSqlDatabase.addDatabase("QSQLITE") + if not database.isValid(): + logger.error("Failed to load SQLITE drivers") + sys.exit(1) + database.setDatabaseName("/home/dizzynight/Code/Python/inventory-wars/app.db") + if not database.open(): + logger.error("Failed to open the sqlite database") + sys.exit(1) engine = QQmlApplicationEngine() engine.addImportPath(sys.path[1]) engine.loadFromModule("InventoryWars", "Main") + if not engine.rootObjects(): sys.exit(-1)