This commit is contained in:
Daniel Haus 2026-01-23 09:41:20 +03:00
commit 95c854f215
9 changed files with 287 additions and 0 deletions

203
windows.py Normal file
View file

@ -0,0 +1,203 @@
from PyQt6.QtWidgets import (
QLabel, QLineEdit, QComboBox, QPushButton,
QMessageBox, QHBoxLayout, QVBoxLayout, QFormLayout, QTableWidget,
QTableWidgetItem, QSpinBox, QGroupBox, QFrame
)
from PyQt6.QtCore import Qt
from base import BaseWindow
from data import USERS, PRODUCTS, ORDERS, STATUS_OPTIONS
class LoginWindow(BaseWindow):
def _setup_ui(self):
layout = QVBoxLayout()
form = QFormLayout()
self.login_edit = QLineEdit()
self.pass_edit = QLineEdit()
self.pass_edit.setEchoMode(QLineEdit.EchoMode.Password)
self.role_combo = QComboBox()
self.role_combo.addItems(['Покупатель', 'Кассир'])
form.addRow('Логин:', self.login_edit)
form.addRow('Пароль:', self.pass_edit)
form.addRow('Роль:', self.role_combo)
self.login_btn = QPushButton('Войти в систему')
self.login_btn.clicked.connect(self.try_login)
layout.addLayout(form)
layout.addWidget(self.login_btn)
self.setLayout(layout)
def try_login(self):
username = self.login_edit.text().strip()
password = self.pass_edit.text()
role = self.role_combo.currentText()
if username not in USERS:
QMessageBox.critical(self, 'Ошибка', 'Пользователь не найден')
return
user = USERS[username]
if password != user['password']:
QMessageBox.critical(self, 'Ошибка', 'Неправильный пароль')
return
if role != user['role']:
QMessageBox.critical(self, 'Ошибка',
'Выбранная роль не совпадает с ролью пользователя')
return
if role == 'Покупатель':
self._composer.render_request.emit("Покупатель")
else:
self._composer.render_request.emit("Кассир")
class CustomerWindow(BaseWindow):
def _setup_ui(self):
main_layout = QVBoxLayout()
top_layout = QHBoxLayout()
left_box = QVBoxLayout()
self.table = QTableWidget(len(PRODUCTS), 3)
self.table.setHorizontalHeaderLabels([
'Товар', 'Тип животного', 'Цена'
])
self.table.setSelectionBehavior(
self.table.SelectionBehavior.SelectRows
)
self.table.setEditTriggers(self.table.EditTrigger.NoEditTriggers)
for row, p in enumerate(PRODUCTS):
self.table.setItem(row, 0, QTableWidgetItem(p['name']))
self.table.setItem(row, 1, QTableWidgetItem(p['animal']))
self.table.setItem(row, 2, QTableWidgetItem(f"{p['price']} р."))
left_box.addWidget(self.table)
self.select_btn = QPushButton('Выбрать товар')
self.select_btn.clicked.connect(self.select_product)
left_box.addWidget(self.select_btn)
top_layout.addLayout(left_box, 2)
# Правая колонка: расчёт стоимости
right_group = QGroupBox('Расчёт стоимости')
right_layout = QFormLayout()
self.price_edit = QLineEdit()
self.price_edit.setReadOnly(True)
self.quantity_spin = QSpinBox()
self.quantity_spin.setRange(1, 1000)
self.quantity_spin.setValue(1)
self.calc_btn = QPushButton('Рассчитать стоимость')
self.calc_btn.setStyleSheet('background-color: #4CAF50; color: white;')
self.calc_btn.clicked.connect(self.calculate_sum)
self.sum_label = QLabel('0 р.')
self.sum_label.setFrameShape(QFrame.Shape.Box)
self.sum_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.add_btn = QPushButton('Добавить в заказ')
self.add_btn.setStyleSheet('background-color: #4CAF50; color: white;')
self.add_btn.clicked.connect(self.add_to_order)
right_layout.addRow('Цена за единицу:', self.price_edit)
right_layout.addRow('Количество:', self.quantity_spin)
right_layout.addRow(self.calc_btn)
right_layout.addRow('Сумма:', self.sum_label)
right_layout.addRow(self.add_btn)
right_group.setLayout(right_layout)
top_layout.addWidget(right_group, 1)
main_layout.addLayout(top_layout)
# Внизу: закрыть
self.close_btn = QPushButton('Закрыть')
self.close_btn.clicked.connect(self.close)
main_layout.addWidget(self.close_btn,
alignment=Qt.AlignmentFlag.AlignRight)
self.setLayout(main_layout)
# Внутренний список заказа (простой)
self.current_order = []
def select_product(self):
selected = self.table.currentRow()
if selected < 0:
QMessageBox.warning(self, 'Ошибка', 'Не выбран товар')
return
price_item = self.table.item(selected, 2).text()
# Из строки "500 р." выделим число
price_number = ''.join(ch for ch in price_item if ch.isdigit())
self.price_edit.setText(price_number)
def calculate_sum(self):
price_text = self.price_edit.text().strip()
if not price_text.isdigit():
QMessageBox.warning(self, 'Ошибка', 'Сначала выберите товар')
return
price = int(price_text)
qty = self.quantity_spin.value()
total = price * qty
self.sum_label.setText(f"{total} р.")
def add_to_order(self):
sum_text = self.sum_label.text()
if sum_text.startswith('0') or sum_text == '0 р.':
QMessageBox.warning(self, 'Ошибка',
'Нужно рассчитать сумму перед добавлением')
return
# Для простоты — добавляем запись в список и показываем сообщение
self.current_order.append({'sum': sum_text})
QMessageBox.information(self, 'Добавлено',
f'Добавлено в заказ: {sum_text}')
class CashierWindow(BaseWindow):
def _setup_ui(self):
main_layout = QVBoxLayout()
self.orders_table = QTableWidget(len(ORDERS), 4)
self.orders_table.setHorizontalHeaderLabels([
'№ заказа', 'Покупатель', 'Сумма', 'Статус'
])
self.orders_table.setSelectionBehavior(
self.orders_table.SelectionBehavior.SelectRows
)
self.orders_table.setEditTriggers(
self.orders_table.EditTrigger.NoEditTriggers
)
for row, o in enumerate(ORDERS):
self.orders_table.setItem(row, 0, QTableWidgetItem(o['id']))
self.orders_table.setItem(row, 1, QTableWidgetItem(o['customer']))
self.orders_table.setItem(row, 2, QTableWidgetItem(o['sum']))
self.orders_table.setItem(row, 3, QTableWidgetItem(o['status']))
main_layout.addWidget(self.orders_table)
ctrl_layout = QHBoxLayout()
self.status_combo = QComboBox()
self.status_combo.addItems(STATUS_OPTIONS)
self.change_btn = QPushButton('Изменить статус')
self.change_btn.clicked.connect(self.change_status)
ctrl_layout.addWidget(QLabel('Новый статус:'))
ctrl_layout.addWidget(self.status_combo)
ctrl_layout.addWidget(self.change_btn)
main_layout.addLayout(ctrl_layout)
self.setLayout(main_layout)
self.setFixedSize(450, 200)
def change_status(self):
selected = self.orders_table.currentRow()
if selected < 0:
QMessageBox.critical(self, 'Ошибка', 'Не выбрана строка')
return
new_status = self.status_combo.currentText()
self.orders_table.setItem(selected, 3, QTableWidgetItem(new_status))
QMessageBox.information(self, 'Готово', 'Статус обновлён')