Графический интерфейс на PyQt

1. Основная структура проекта

project/
│
├── main.py                   # Главное окно
├── window_dog.py             # Окно просмотра питомцев
├── window_order.py           # Окно просмотра заказов
├── window_form.py            # Окно оформления заказа
├── dog_int.py                # Сгенерированный UI для просмотра питомцев
├── ord_int.py                # Сгенерированный UI для оформления заказа
├── conn.py                   # Подключение к БД

2. Подключение к БД (conn.py)


import mysql.connector
from mysql.connector import Error

def connect_to_db():
    try:
        conn = mysql.connector.connect(
            user='root',
            password='root',
            host='localhost',
            database='test_kwalik_dogs'
        )
        if conn.is_connected():
            print("С БД все ок")
        return conn
    except Error as e:
        print(f"Ошибка подключения: {e}")
        return None
        

3. Главное окно (main.py)


import sys
from PyQt5.QtWidgets import QApplication, QWidget
from main_int import Ui_Form  # Сгенерированный UI главного окна
from window_dog import ViewDog
from window_order import ViewOrder
from window_form import ViewForm

class MainWindow(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.show_dogs)  # Кнопка "Просмотр питомцев"
        self.pushButton_2.clicked.connect(self.show_form)  # Кнопка "Оформить заказ"
        self.pushButton_3.clicked.connect(self.show_orders)  # Кнопка "Просмотр заказов"

    def show_dogs(self):
        self.close()
        self.dog_window = ViewDog()
        self.dog_window.show()

    def show_orders(self):
        self.close()
        self.order_window = ViewOrder()
        self.order_window.show()

    def show_form(self):
        self.close()
        self.form_window = ViewForm()
        self.form_window.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())
        

4. Окно просмотра питомцев (window_dog.py)


from PyQt5.QtWidgets import QWidget, QTableWidgetItem, QMessageBox
from dog_int import Ui_Form  # Сгенерированный UI
from conn import connect_to_db

class ViewDog(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.load_data()
        self.back_btn.clicked.connect(self.back_to_main)
        self.show()

    def load_data(self):
        try:
            conn = connect_to_db()
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM is_here")  # Представление с непроданными питомцами
            data = cursor.fetchall()

            # Заполнение таблицы
            self.table.setRowCount(len(data))
            self.table.setColumnCount(7)
            self.table.setHorizontalHeaderLabels(["ID", "Категория", "Порода", "Имя", "Цена", "Возраст", "Цвет"])

            for row_idx, row_data in enumerate(data):
                for col_idx, value in enumerate(row_data):
                    self.table.setItem(row_idx, col_idx, QTableWidgetItem(str(value)))
        except Exception as e:
            QMessageBox.critical(self, "Ошибка", f"Не удалось загрузить данные: {str(e)}")
        finally:
            if conn.is_connected():
                cursor.close()
                conn.close()

    def back_to_main(self):
        self.close()
        from main import MainWindow
        self.main_window = MainWindow()
        self.main_window.show()
        

5. Окно просмотра заказов (window_order.py)


from PyQt5.QtWidgets import QWidget, QTableWidgetItem, QMessageBox
from dog_int import Ui_Form  # Используется тот же UI, что и для питомцев
from conn import connect_to_db

class ViewOrder(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.load_data()
        self.back_btn.clicked.connect(self.back_to_main)
        self.show()

    def load_data(self):
        try:
            conn = connect_to_db()
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM orders")  # Таблица заказов
            data = cursor.fetchall()

            # Заполнение таблицы
            self.table.setRowCount(len(data))
            self.table.setColumnCount(6)
            self.table.setHorizontalHeaderLabels(["ID заказа", "Дата", "Статус", "Цена", "ID питомца", "ID клиента"])

            for row_idx, row_data in enumerate(data):
                for col_idx, value in enumerate(row_data):
                    self.table.setItem(row_idx, col_idx, QTableWidgetItem(str(value)))
        except Exception as e:
            QMessageBox.critical(self, "Ошибка", f"Не удалось загрузить заказы: {str(e)}")
        finally:
            if conn.is_connected():
                cursor.close()
                conn.close()

    def back_to_main(self):
        self.close()
        from main import MainWindow
        self.main_window = MainWindow()
        self.main_window.show()
        

6. Окно оформления заказа (window_form.py)


from PyQt5.QtWidgets import QWidget, QMessageBox
from ord_int import Ui_Form  # Сгенерированный UI для формы
from conn import connect_to_db

class ViewForm(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.back_btn.clicked.connect(self.back_to_main)
        self.pushButton.clicked.connect(self.submit_order)
        self.show()

    def submit_order(self):
        try:
            conn = connect_to_db()
            cursor = conn.cursor()

            # Получение данных из полей ввода
            id_ord = self.lineEdit.text()
            id_dog = self.lineEdit_2.text()
            cost = self.lineEdit_3.text()
            id_cli = self.lineEdit_4.text()

            # Вызов процедуры
            cursor.callproc("оформить_продажу", [id_ord, id_dog, cost, id_cli])
            conn.commit()
            QMessageBox.information(self, "Успех", "Заказ успешно оформлен!")
            self.clear_fields()
        except Exception as e:
            QMessageBox.critical(self, "Ошибка", f"Не удалось оформить заказ: {str(e)}")
        finally:
            if conn.is_connected():
                cursor.close()
                conn.close()

    def clear_fields(self):
        self.lineEdit.clear()
        self.lineEdit_2.clear()
        self.lineEdit_3.clear()
        self.lineEdit_4.clear()

    def back_to_main(self):
        self.close()
        from main import MainWindow
        self.main_window = MainWindow()
        self.main_window.show()
        

7. Генерация .py из .ui

pyuic5 dog_int.ui -o dog_int.py  # Для окна с питомцами
pyuic5 ord_int.ui -o ord_int.py  # Для формы оформления заказа

8. Как создать интерфейс в Qt Designer

  1. Добавьте виджеты: QTableWidget, QPushButton, QLineEdit.
  2. Назовите виджеты в Qt Designer: back_btn, table, lineEdit и т.д.
  3. Сохраните как dog_int.ui и ord_int.ui.

9. Частые ошибки и решения

Ошибка Причина Решение
QMessageBox.critical показывает ошибку подключения Проблемы с conn.py Проверьте логин, пароль, хост, имя БД.
QTableWidget не отображает данные Неверные столбцы или строки Убедитесь, что setColumnCount и setRowCount соответствуют данным.
cursor.callproc не работает Неверные параметры процедуры Проверьте, что хранимая процедура принимает те же параметры.
QLineEdit не очищается Не вызван clear() Добавьте self.lineEdit.clear() после успешного вызова процедуры.

10. Пример для любого варианта (шаблон окна с таблицей)


# window_template.py
from PyQt5.QtWidgets import QWidget, QTableWidgetItem, QMessageBox
from generated_ui import Ui_Form  # Сгенерированный UI
from conn import connect_to_db

class DataView(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.load_data()
        self.back_btn.clicked.connect(self.back_to_main)
        self.show()

    def load_data(self):
        try:
            conn = connect_to_db()
            cursor = conn.cursor()
            cursor.execute("SELECT * FROM ваше_представление_или_таблица")
            data = cursor.fetchall()

            self.table.setRowCount(len(data))
            self.table.setColumnCount(кол-во_столбцов)
            self.table.setHorizontalHeaderLabels(["Заголовок1", "Заголовок2", ...])

            for row_idx, row_data in enumerate(data):
                for col_idx, value in enumerate(row_data):
                    self.table.setItem(row_idx, col_idx, QTableWidgetItem(str(value)))
        except Exception as e:
            QMessageBox.critical(self, "Ошибка", f"Не удалось загрузить данные: {str(e)}")
        finally:
            if conn.is_connected():
                cursor.close()
                conn.close()

    def back_to_main(self):
        self.close()
        from main import MainWindow
        self.main_window = MainWindow()
        self.main_window.show()
        
Создатель сайта не утверждает,
что данная шпаргалка действительно верная
Получить помощь