Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Created February 20, 2026 13:14
Show Gist options
  • Select an option

  • Save sunmeat/baaf2670a2874d17f00cefbbcb4d55d0 to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/baaf2670a2874d17f00cefbbcb4d55d0 to your computer and use it in GitHub Desktop.
MVT (pyside6)
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