Final Update: second variant complete

This commit is contained in:
Daniel 2025-11-26 12:56:14 +03:00
parent 703adc3326
commit b92a91ab37
8 changed files with 2939 additions and 62 deletions

View file

@ -5,10 +5,10 @@ from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QTabWidget, QTableWidget, QTableWidgetItem,
QPushButton, QLabel, QLineEdit, QComboBox, QDateEdit,
QTextEdit, QMessageBox, QHeaderView, QGroupBox,
QFormLayout, QSpinBox, QCheckBox, QTimeEdit)
from PyQt6.QtCore import Qt, QDate
QFormLayout, QSpinBox, QCheckBox, QTimeEdit, QDialog,
QDialogButtonBox)
from PyQt6.QtCore import Qt, QDate, QTime
from PyQt6.QtGui import QFont, QPalette, QColor
from PyQt6.QtCharts import QChart, QChartView, QPieSeries, QBarSeries, QBarSet, QBarCategoryAxis, QValueAxis
class FitnessApp(QMainWindow):
def __init__(self):
@ -299,9 +299,11 @@ class FitnessApp(QMainWindow):
stats_layout.addLayout(stats_form)
# Правая часть - диаграмма
self.stats_chart = QChartView()
stats_layout.addWidget(self.stats_chart)
# Правая часть - таблица для статистики
self.stats_table = QTableWidget()
self.stats_table.setColumnCount(2)
self.stats_table.setHorizontalHeaderLabels(['Зона', 'Количество посещений'])
stats_layout.addWidget(self.stats_table)
stats_group.setLayout(stats_layout)
layout.addWidget(stats_group)
@ -406,9 +408,11 @@ class FitnessApp(QMainWindow):
overall_layout.addLayout(metrics_layout)
# Правая часть - диаграмма доходов
self.revenue_chart = QChartView()
overall_layout.addWidget(self.revenue_chart)
# Правая часть - таблица доходов по типам абонементов
self.revenue_table = QTableWidget()
self.revenue_table.setColumnCount(2)
self.revenue_table.setHorizontalHeaderLabels(['Тип абонемента', 'Доход'])
overall_layout.addWidget(self.revenue_table)
overall_stats_group.setLayout(overall_layout)
layout.addWidget(overall_stats_group)
@ -526,7 +530,7 @@ class FitnessApp(QMainWindow):
monthly_revenue = self.cursor.fetchone()[0] or 0
self.monthly_revenue_label.setText(f"{monthly_revenue:.2f} руб.")
# Диаграмма доходов
# Таблица доходов по типам абонементов
self.cursor.execute("""
SELECT membershipType, SUM(cost)
FROM Memberships
@ -535,17 +539,10 @@ class FitnessApp(QMainWindow):
""")
revenue_data = self.cursor.fetchall()
series = QPieSeries()
for membership_type, revenue in revenue_data:
series.append(membership_type, revenue)
chart = QChart()
chart.addSeries(series)
chart.setTitle("Доходы по типам абонементов")
chart.legend().setVisible(True)
chart.legend().setAlignment(Qt.AlignmentFlag.AlignBottom)
self.revenue_chart.setChart(chart)
self.revenue_table.setRowCount(len(revenue_data))
for row, (membership_type, revenue) in enumerate(revenue_data):
self.revenue_table.setItem(row, 0, QTableWidgetItem(membership_type))
self.revenue_table.setItem(row, 1, QTableWidgetItem(f"{revenue:.2f} руб."))
# Данные по тренерам
self.cursor.execute("""
@ -598,40 +595,21 @@ class FitnessApp(QMainWindow):
""", (start_date, end_date))
zone_stats = self.cursor.fetchall()
series = QBarSeries()
bar_set = QBarSet("Посещения по зонам")
categories = []
visits = []
for zone, count in zone_stats:
categories.append(zone)
visits.append(count)
bar_set.append(visits)
series.append(bar_set)
chart = QChart()
chart.addSeries(series)
chart.setTitle(f"Посещаемость по зонам ({start_date} - {end_date})")
axis_x = QBarCategoryAxis()
axis_x.append(categories)
chart.addAxis(axis_x, Qt.AlignmentFlag.AlignBottom)
series.attachAxis(axis_x)
axis_y = QValueAxis()
chart.addAxis(axis_y, Qt.AlignmentFlag.AlignLeft)
series.attachAxis(axis_y)
self.stats_chart.setChart(chart)
self.stats_table.setRowCount(len(zone_stats))
for row, (zone, count) in enumerate(zone_stats):
self.stats_table.setItem(row, 0, QTableWidgetItem(zone))
self.stats_table.setItem(row, 1, QTableWidgetItem(str(count)))
class AddClassDialog(QMessageBox):
class AddClassDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Добавить групповое занятие")
self.setModal(True)
layout = QVBoxLayout()
form_layout = QFormLayout()
self.class_name = QLineEdit()
self.trainer = QComboBox()
self.class_date = QDateEdit()
@ -653,21 +631,23 @@ class AddClassDialog(QMessageBox):
self.hall.addItems(['Зал 1', 'Зал 2', 'Зал 3', 'Бассейн'])
layout = QFormLayout()
layout.addRow("Название:", self.class_name)
layout.addRow("Тренер:", self.trainer)
layout.addRow("Дата:", self.class_date)
layout.addRow("Время начала:", self.start_time)
layout.addRow("Время окончания:", self.end_time)
layout.addRow("Зал:", self.hall)
layout.addRow("Макс. участников:", self.max_participants)
form_layout.addRow("Название:", self.class_name)
form_layout.addRow("Тренер:", self.trainer)
form_layout.addRow("Дата:", self.class_date)
form_layout.addRow("Время начала:", self.start_time)
form_layout.addRow("Время окончания:", self.end_time)
form_layout.addRow("Зал:", self.hall)
form_layout.addRow("Макс. участников:", self.max_participants)
widget = QWidget()
widget.setLayout(layout)
self.layout().addWidget(widget, 0, 0, 1, self.layout().columnCount())
layout.addLayout(form_layout)
self.addButton(QPushButton("Добавить"), QMessageBox.ButtonRole.AcceptRole)
self.addButton(QPushButton("Отмена"), QMessageBox.ButtonRole.RejectRole)
# Кнопки
button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
layout.addWidget(button_box)
self.setLayout(layout)
def get_data(self):
"""Получение данных из формы"""