Created
February 20, 2026 13:14
-
-
Save sunmeat/baaf2670a2874d17f00cefbbcb4d55d0 to your computer and use it in GitHub Desktop.
MVT (pyside6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sys | |
| import ctypes | |
| if sys.platform == "win32": | |
| console = ctypes.windll.kernel32.GetConsoleWindow() | |
| if console: | |
| ctypes.windll.user32.ShowWindow(console, 0) | |
| from PySide6.QtWidgets import ( | |
| QApplication, QMainWindow, QWidget, | |
| QVBoxLayout, QHBoxLayout, | |
| QPushButton, QLabel, QLineEdit, | |
| QTextEdit, QMessageBox | |
| ) | |
| from PySide6.QtCore import Qt | |
| # ──────────────────────────────────────────────── | |
| # model — дані та бізнес-логіка | |
| # ──────────────────────────────────────────────── | |
| class ShoppingModel: | |
| # ініціалізація списку | |
| def __init__(self): | |
| self.items = [] | |
| # додавання товару | |
| def add_item(self, name, qty, price): | |
| self.items.append({ | |
| "name": name, | |
| "quantity": qty, | |
| "price": price | |
| }) | |
| # очищення списку | |
| def clear(self): | |
| self.items.clear() | |
| # отримання копії списку | |
| def get_items(self): | |
| return self.items.copy() | |
| # підрахунок суми | |
| def total(self): | |
| return sum(i["quantity"] * i["price"] for i in self.items) | |
| # ──────────────────────────────────────────────── | |
| # template — форматування відображення | |
| # ──────────────────────────────────────────────── | |
| class ShoppingTemplate: | |
| # формат одного рядка | |
| @staticmethod | |
| def format_item(index, item): | |
| subtotal = item["quantity"] * item["price"] | |
| return ( | |
| f"{index:>2}. {item['name']:<20}" | |
| f"{item['quantity']:>3} × {item['price']:>7.2f} = {subtotal:>8.2f} ₴" | |
| ) | |
| # формат всього списку | |
| @staticmethod | |
| def format_list(items, total): | |
| if not items: | |
| return "список порожній" | |
| lines = [ | |
| ShoppingTemplate.format_item(i + 1, item) | |
| for i, item in enumerate(items) | |
| ] | |
| lines.append("\n" + "─" * 40) | |
| lines.append(f"разом: {total:.2f} ₴") | |
| return "\n".join(lines) | |
| # ──────────────────────────────────────────────── | |
| # view — інтерфейс та взаємодія з користувачем | |
| # ──────────────────────────────────────────────── | |
| class MainWindow(QMainWindow): | |
| def __init__(self, model): | |
| super().__init__() | |
| self.model = model | |
| self.dark = True | |
| self.setWindowTitle("список покупок") | |
| self.resize(720, 550) | |
| self.build_ui() | |
| self.apply_theme() | |
| # побудова інтерфейсу | |
| def build_ui(self): | |
| central = QWidget() | |
| self.setCentralWidget(central) | |
| layout = QVBoxLayout(central) | |
| layout.setSpacing(10) | |
| title = QLabel("список покупок") | |
| title.setAlignment(Qt.AlignCenter) | |
| title.setStyleSheet("font-size:22px; font-weight:bold;") | |
| layout.addWidget(title) | |
| # поля вводу | |
| self.name = QLineEdit() | |
| self.name.setPlaceholderText("назва товару") | |
| self.qty = QLineEdit() | |
| self.qty.setPlaceholderText("кількість") | |
| self.price = QLineEdit() | |
| self.price.setPlaceholderText("ціна") | |
| layout.addWidget(self.name) | |
| layout.addWidget(self.qty) | |
| layout.addWidget(self.price) | |
| # кнопки | |
| btn_row = QHBoxLayout() | |
| self.add_btn = QPushButton("додати") | |
| self.clear_btn = QPushButton("очистити") | |
| self.theme_btn = QPushButton("тема (t)") | |
| self.quit_btn = QPushButton("вихід") | |
| for b in (self.add_btn, self.clear_btn, self.theme_btn, self.quit_btn): | |
| b.setMinimumHeight(42) | |
| btn_row.addWidget(b) | |
| layout.addLayout(btn_row) | |
| # список | |
| self.list_box = QTextEdit() | |
| self.list_box.setReadOnly(True) | |
| self.list_box.setMinimumHeight(320) | |
| layout.addWidget(self.list_box) | |
| # події | |
| self.add_btn.clicked.connect(self.add_item) | |
| self.clear_btn.clicked.connect(self.clear_items) | |
| self.theme_btn.clicked.connect(self.toggle_theme) | |
| self.quit_btn.clicked.connect(self.close) | |
| # додавання товару | |
| def add_item(self): | |
| name = self.name.text().strip() | |
| qty_str = self.qty.text().strip() | |
| price_str = self.price.text().strip() | |
| if not name or not qty_str or not price_str: | |
| QMessageBox.warning(self, "помилка", "заповніть всі поля") | |
| return | |
| try: | |
| qty = int(qty_str) | |
| price = float(price_str) | |
| except ValueError: | |
| QMessageBox.warning(self, "помилка", "невірний формат числа") | |
| return | |
| if qty < 1 or price <= 0: | |
| QMessageBox.warning(self, "помилка", "некоректні значення") | |
| return | |
| self.model.add_item(name, qty, price) | |
| self.name.clear() | |
| self.qty.clear() | |
| self.price.clear() | |
| self.refresh() | |
| # очищення списку | |
| def clear_items(self): | |
| self.model.clear() | |
| self.refresh() | |
| # оновлення відображення (через template) | |
| def refresh(self): | |
| items = self.model.get_items() | |
| total = self.model.total() | |
| text = ShoppingTemplate.format_list(items, total) | |
| self.list_box.setText(text) | |
| # перемикання теми | |
| def toggle_theme(self): | |
| self.dark = not self.dark | |
| self.apply_theme() | |
| # застосування стилю | |
| def apply_theme(self): | |
| if self.dark: | |
| self.setStyleSheet(""" | |
| QWidget { background:#121226; color:#e0e0ff; } | |
| QLineEdit, QTextEdit { | |
| background:#0d0d1f; | |
| border:1px solid #4444aa; | |
| } | |
| QPushButton { | |
| background:#2d2d8f; | |
| border:1px solid #6666ff; | |
| padding:6px; | |
| } | |
| QPushButton:hover { background:#3a3aaa; } | |
| """) | |
| else: | |
| self.setStyleSheet(""" | |
| QWidget { background:#f2f2f2; color:#111; } | |
| QLineEdit, QTextEdit { | |
| background:white; | |
| border:1px solid #aaa; | |
| } | |
| QPushButton { | |
| background:#dddddd; | |
| border:1px solid #888; | |
| padding:6px; | |
| } | |
| QPushButton:hover { background:#cccccc; } | |
| """) | |
| # гаряча клавіша t | |
| def keyPressEvent(self, event): | |
| if event.key() == Qt.Key_T: | |
| self.toggle_theme() | |
| else: | |
| super().keyPressEvent(event) | |
| # ──────────────────────────────────────────────── | |
| # запуск програми | |
| # ──────────────────────────────────────────────── | |
| if __name__ == "__main__": | |
| app = QApplication(sys.argv) | |
| model = ShoppingModel() # створення model | |
| window = MainWindow(model) # передача model у view | |
| window.show() | |
| sys.exit(app.exec()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment