Загрузка данных


import psycopg2, os
from dotenv import load_dotenv

load_dotenv()

class QwerSql:
    PAGE_SIZE = 5

    def __init__(self):
        try:
            self.conn = psycopg2.connect(
                host=os.getenv('DB_HOST'),
                user=os.getenv('DB_USER'),
                password=os.getenv('DB_PASSWORD'),
                dbname=os.getenv('DB_NAME')
            )

            self.cursor = self.conn.cursor()
            print("успешно")
        except Exception as ex:
            print(ex)
            print("ошибка")

    def count_rugs(self):
        self.cursor.execute("SELECT COUNT(*) FROM rugs")
        return self.cursor.fetchone()[0]

    def show_rugs(self, page=0):
        offset = page * self.PAGE_SIZE
        sql = "select * from v_rugs_full order by id limit %s offset %s;"
        self.cursor.execute(sql, (self.PAGE_SIZE, offset))
        return self.cursor.fetchall()


    def total_pages(self):
        total = self.count_rugs()
        return(total + self.PAGE_SIZE - 1) // self.PAGE_SIZE

    def close(self):
        self.cursor.close()
        self.conn.close()








from PyQt6 import QtCore
from PyQt6.QtWidgets import *


class MainWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.scroll_stack = QWidget()
        self.scroll_stack_layout = QVBoxLayout(self.scroll_stack)
        self.scroll_stack_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)

        self.scroll_area = QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setWidget(self.scroll_stack)

        self.main_layout = QVBoxLayout(self)
        self.main_layout.addWidget(self.scroll_area)

    def clear_cards(self):

        while self.scroll_stack_layout.count():
            item = self.scroll_stack_layout.takeAt(0)
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()






from PyQt6 import QtGui
from PyQt6.QtWidgets import *


class NextWin(QWidget):
    def __init__(self, data: dict):
        super().__init__()
        self.resize(320, 260)
        self.setWindowTitle("Просмотр деталей")
        self.setWindowIcon(QtGui.QIcon("resources/icons/ico4.jpg"))

        layout = QVBoxLayout(self)

        lbl_img = QLabel()
        pix = QtGui.QPixmap(data["img"]).scaled(150, 150)
        lbl_img.setPixmap(pix)
        layout.addWidget(lbl_img)

        text = (
            f"Название: {data['name']}\n"
            f"Категория: {data['category']}\n"
            f"Тип: {data['type']}\n"
            f"Производитель: {data['manufacturing']}\n"
            f"Материал: {data['cloth']}\n"
            f"Количество: {data['quantity']} шт.\n"
            f"Цена: {data['price']} руб.\n"
            f"Скидка: {data['discount']}%"
        )
        lbl_text = QLabel(text)
        lbl_text.setWordWrap(True)
        layout.addWidget(lbl_text)







import os
from PyQt6 import QtCore, QtGui
from PyQt6.QtWidgets import *

from db_units.qwer_sql import QwerSql
from ui_units.main_widget import MainWidget
from ui_units.next_win import NextWin


class MyWin(QMainWindow):
    def __init__(self, user_id=0):
        super().__init__()
        self.user_id = user_id
        self.current_page = 0

        self.setWindowTitle("Shop")
        self.setWindowIcon(QtGui.QIcon("resources/icons/ico4.jpg"))
        self.resize(800, 500)


        self.db = QwerSql()
        self.total_pages = self.db.total_pages()


        central = QWidget()
        self.setCentralWidget(central)
        main_layout = QVBoxLayout(central)


        top_bar = QHBoxLayout()
        top_bar.addStretch()
        self.btn_login = QPushButton("Войти")
        self.btn_login.clicked.connect(self.on_login)
        top_bar.addWidget(self.btn_login)
        main_layout.addLayout(top_bar)


        self.main_widget = MainWidget()
        main_layout.addWidget(self.main_widget, 1)

        bottom_bar = QHBoxLayout()
        self.btn_prev = QPushButton("<<<")
        self.btn_next = QPushButton(">>>")
        self.btn_prev.clicked.connect(self.prev_page)
        self.btn_next.clicked.connect(self.next_page)

        bottom_bar.addWidget(self.btn_prev)
        bottom_bar.addStretch()
        bottom_bar.addWidget(self.btn_next)
        main_layout.addLayout(bottom_bar)


        self.render_page()


    def prev_page(self):
        if self.current_page > 0:
            self.current_page -= 1
            self.render_page()

    def next_page(self):
        if self.current_page < self.total_pages - 1:
            self.current_page += 1
            self.render_page()


    def render_page(self):
        self.main_widget.clear_cards()

        rows = self.db.show_rugs(self.current_page)

        if not rows:
            self.main_widget.scroll_stack_layout.addWidget(QLabel("Ковров нет"))
            return

        for row in rows:
            (rug_id, name, category, type_, manufacturing,
             cloth, quantity, price) = row


            discount = 15 if category = "напольный" else 5


            img_path = f"resources/images/rug{rug_id}.png"
            if not os.path.exists(img_path):
                img_path = "resources/icons/ico1.jpeg"

            data = {
                "img": img_path,
                "name": name,
                "category": category or "-",
                "type": type_ or "-",
                "manufacturing": manufacturing or "-",
                "cloth": cloth or "-",
                "quantity": quantity,
                "price": price,
                "discount": discount,
            }
            self.add_card(data)

    def add_card(self, data: dict):
        card = QWidget()
        card_layout = QHBoxLayout(card)


        lb_img = QLabel()
        lb_img.setPixmap(QtGui.QPixmap(data["img"]).scaled(100, 100))
        lb_img.setFrameStyle(QFrame.Shape.Box)


        lb_text = QLabel(
            f"{data['name']} | {data['category']} | "
            f"{data['manufacturing']} | {data['cloth']} | "
            f"{data['price']} руб."
        )
        lb_text.setFrameStyle(QFrame.Shape.Box)
        lb_text.setWordWrap(True)

        lb_text.mousePressEvent = lambda e, d=data: self.open_details(d)
        lb_text.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)


        lb_discount = QLabel(f"{data['discount']}%")
        lb_discount.setFrameStyle(QFrame.Shape.Box)

        card_layout.addWidget(lb_img)
        card_layout.addWidget(lb_text, 5)
        card_layout.addWidget(lb_discount)

        self.main_widget.scroll_stack_layout.addWidget(card)

    def open_details(self, data: dict):
        self.next_win = NextWin(data)
        self.next_win.show()

    def on_login(self):
        QMessageBox.information(self, "Вход", "Здесь можно открыть окно авторизации")