Это статья для краткого и быстрого начала имменно в ПОНИМАНИЕ КОДА, а не полноценный тутор по разработке.
ПРИМЕЧАНИЕ
Для скачивания сторонней библиотеки используется следующаяя команда
pip install (название библиотеки) в данном случае
Для удаления: pip unstall (название библиотеки)
· Ссылка на скачивание Python: https://www.python.org/ftp/python/3.13.2/python-3.13.2-amd64.exe
· Ссылка на скачку PyCharm: https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=windows&code=PCC
· Import – импортирует библиотеку
· from {название библиотеки} import {название модуля/функции/переменной/ т.д.} – импортирует определённую функцию из библиотеки, но можно и целый список функций или переменных
· def {любое название} – это оператор для того чтоб Python понимал, что перед ним начала какой- либо функции
· Для иницилизации(вызова данного метода) в коде используются такая конструкция : {название функции}() – скобочки обезательно!!
· conn.cursor() – создание виртуального курсора для работой с БД
· * - В SQL означает всё/ все данные
· скрипт – кусочек кода
РАБОТА С БД
Подключение встроенной библиотеки для работой с SQL – запросами
sql_create_{название таблицы}_table – реализация SQL – запросов для создания таблицы, после = """ идёт чистый SQL
В данном скрипте, создаётся соединение с БД «warehouse.bd», далее подключение к таблицам из данной БД
cur.execute("SELECT * FROM warehouses") – Данный скрипт основан на SQL, тут происходит выбор ВСЕХ данных из таблици warehouses
("SELECT * FROM warehouses") = ("ВЫБОР ВСЕГО ИЗ {НАЗВАНИЕ ТАБЛИЦЫ}")
ОСНОВНЫЕ КОМАНДЫ И БИБЛЕОТЕКА PYQT5
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QLabel, QLineEdit, QPushButton, QVBoxLayout, QWidget, QTableWidget, QTableWidgetItem,
QTabWidget, QComboBox, QMessageBox, QHBoxLayout, QGridLayout, QHeaderView
)
Приведены самые часто используемые модули из библеотеки PyQt5. Для лучшей читаемости они выведены в скобках.
self.setWindowTitle("Система контроля товаров")
self.setGeometry(100, 100, 800, 600)
setWindowTitle("Система контроля товаров") – команда для создания названия окна, это просто создаёт заголовок окна
setGeometry(100, 100, х, у) – настройка размера окна, х – ширина, у – высота.
Работа с UI
self.tabs = QTabWidget()
self.setCentralWidget(self.tabs)
Данные команды иницилируют доступ к созданию вкладок, в данном случае она создаёт невидимую таблицу в которой будут вкладки. Данная команда должна быть раньше вызова самих вкладок
self.stocks_tab = QWidget()
self.setup_stocks_tab()
self.tabs.addTab(self.stocks_tab, "Запасы")
stocks_tab = QWidget() – Назване таблици, с которой он будет взаимодействовать и объявление её как виджете
stocks_tab = QWidget() = {название таблицы}_tab = QWidget()
setup_stocks_tab() – название функции/метода которое будет вызываться нажатием на эту вкладку, главное условие чтоб он был в коде
tabs.addTab(self.stocks_tab, "Запасы") – Добавление название ко вкладке
ДАЛЬНЕЙШИЕ ВКЛАДКИ ПО АНАЛОГИИ
def setup_stocks_tab(self):
layout = QVBoxLayout()
self.stock_product_label = QLabel("Товар:")
self.stock_product_combo = QComboBox()
self.update_stock_product_combo()
self.stock_quantity_label = QLabel("Количество:")
self.stock_quantity_input = QLineEdit()
def setup_stocks_tab(self): - объявление метода в котором будет происходить различные операции, он может быть вызван из разных мест.
self.stock_product_label = QLabel("Товар:")
self.stock_product_combo = QComboBox()
Данныйе сторики выводит поле для ввода с название «Товары» в которм будет всплывающий список, а за него отвечает QComboBox()
self.update_stock_product_combo() – вызывает другую функцию для данного поля.
self.stock_quantity_label = QLabel("Количество:")
self.stock_quantity_input = QLineEdit()
QLabel("Количество:") – создание однострочного поля с текстом КОЛЛИЧЕСТВО, а QLineEdit() создаёт поле для ввода данных
self.add_stock_button = QPushButton("Добавить запас")
self.view_stocks_button = QPushButton("Просмотреть запасы")
Создаёт кнопок add_stock_button – название кнопки для иницилизации событий принажание на эту кнопку, QPushButton("Добавить запас") создание самой кнопки и добавление названия кнопки.
self.stocks_table = QTableWidget()
layout.addWidget(self.stocks_table)
Выводит данные из таблици stoсks для показа их
self.add_stock_button.clicked.connect(self.add_stock)
self.view_stocks_button.clicked.connect(self.view_stocks)
Подключение событий к кнопкам connect(self.add_stock) данную строку можно расшифровать как ПОДКЛЮЧЕНИЕ К МЕТОДУ(НАЗВАНИЕ МЕТОДА)
ПОЛНЫЙ КОД ПРОГРАММЫ
import sys
import sqlite3
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QLabel, QLineEdit, QPushButton, QVBoxLayout, QWidget, QTableWidget, QTableWidgetItem,
QTabWidget, QComboBox, QMessageBox, QHBoxLayout, QGridLayout, QHeaderView
)
# Создание базы данных SQLite
def create_connection(db_file):
conn = None
try:
conn = sqlite3.connect(db_file)
return conn
except sqlite3.Error as e:
print(e)
return conn
def create_tables(conn):
sql_create_products_table = """
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
category TEXT,
subcategory TEXT,
price REAL NOT NULL,
state TEXT,
characteristics TEXT
);
"""
sql_create_warehouses_table = """
CREATE TABLE IF NOT EXISTS warehouses (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
address TEXT,
type TEXT
);
"""
sql_create_stocks_table = """
CREATE TABLE IF NOT EXISTS stocks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id INTEGER,
warehouse_id INTEGER,
current_quantity INTEGER,
min_level INTEGER,
optimal_level INTEGER,
max_level INTEGER,
FOREIGN KEY (product_id) REFERENCES products (id),
FOREIGN KEY (warehouse_id) REFERENCES warehouses (id)
);
"""
sql_create_suppliers_table = """
CREATE TABLE IF NOT EXISTS suppliers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
contact_info TEXT
);
"""
sql_create_shipments_table = """
CREATE TABLE IF NOT EXISTS shipments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
product_id INTEGER,
supplier_id INTEGER,
quantity INTEGER,
shipment_date TEXT,
FOREIGN KEY (product_id) REFERENCES products (id),
FOREIGN KEY (supplier_id) REFERENCES suppliers (id)
);
"""
try:
c = conn.cursor()
c.execute(sql_create_products_table)
c.execute(sql_create_warehouses_table)
c.execute(sql_create_stocks_table)
c.execute(sql_create_suppliers_table)
c.execute(sql_create_shipments_table)
except sqlite3.Error as e:
print(e)
class WarehouseApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Система контроля товаров")
self.setGeometry(100, 100, 800, 600)
# Подключение к БД
self.conn = create_connection('warehouse.db')
create_tables(self.conn)
# Вкладки
self.tabs = QTabWidget()
self.setCentralWidget(self.tabs)
# Главный экран
self.main_screen = QWidget()
self.setup_main_screen()
self.tabs.addTab(self.main_screen, "Главный экран")
# Экран товаров
self.products_tab = QWidget()
self.setup_products_tab()
self.tabs.addTab(self.products_tab, "Товары")
# Экран складов
self.warehouses_tab = QWidget()
self.setup_warehouses_tab()
self.tabs.addTab(self.warehouses_tab, "Склады")
# Экран запасов
self.stocks_tab = QWidget()
self.setup_stocks_tab()
self.tabs.addTab(self.stocks_tab, "Запасы")
# Экран поставщиков
self.suppliers_tab = QWidget()
self.setup_suppliers_tab()
self.tabs.addTab(self.suppliers_tab, "Поставщики")
def setup_main_screen(self):
layout = QVBoxLayout()
self.quick_add_product_button = QPushButton("Добавить товар")
self.quick_add_warehouse_button = QPushButton("Добавить склад")
layout.addWidget(self.quick_add_product_button)
layout.addWidget(self.quick_add_warehouse_button)
self.main_screen.setLayout(layout)
self.quick_add_product_button.clicked.connect(lambda: self.tabs.setCurrentIndex(1))
self.quick_add_warehouse_button.clicked.connect(lambda: self.tabs.setCurrentIndex(2))
def setup_products_tab(self):
layout = QVBoxLayout()
# Форма добавления товара
self.product_name_label = QLabel("Название:")
self.product_name_input = QLineEdit()
self.product_description_label = QLabel("Описание:")
self.product_description_input = QLineEdit()
self.product_category_label = QLabel("Категория:")
self.product_category_input = QLineEdit()
self.product_price_label = QLabel("Цена:")
self.product_price_input = QLineEdit()
self.product_state_label = QLabel("Состояние:")
self.product_state_input = QLineEdit()
self.product_characteristics_label = QLabel("Характеристики:")
self.product_characteristics_input = QLineEdit()
self.add_product_button = QPushButton("Добавить товар")
self.view_products_button = QPushButton("Просмотреть товары")
layout.addWidget(self.product_name_label)
layout.addWidget(self.product_name_input)
layout.addWidget(self.product_description_label)
layout.addWidget(self.product_description_input)
layout.addWidget(self.product_category_label)
layout.addWidget(self.product_category_input)
layout.addWidget(self.product_price_label)
layout.addWidget(self.product_price_input)
layout.addWidget(self.product_state_label)
layout.addWidget(self.product_state_input)
layout.addWidget(self.product_characteristics_label)
layout.addWidget(self.product_characteristics_input)
layout.addWidget(self.add_product_button)
layout.addWidget(self.view_products_button)
# Таблица товаров
self.products_table = QTableWidget()
layout.addWidget(self.products_table)
self.products_tab.setLayout(layout)
self.add_product_button.clicked.connect(self.add_product)
self.view_products_button.clicked.connect(self.view_products)
def add_product(self):
name = self.product_name_input.text()
description = self.product_description_input.text()
category = self.product_category_input.text()
price = self.product_price_input.text()
state = self.product_state_input.text()
characteristics = self.product_characteristics_input.text()
if name and description and category and price:
sql = ''' INSERT INTO products(name, description, category, price, state, characteristics)
VALUES(?,?,?,?,?,?) '''
cur = self.conn.cursor()
cur.execute(sql, (name, description, category, float(price), state, characteristics))
self.conn.commit()
self.product_name_input.clear()
self.product_description_input.clear()
self.product_category_input.clear()
self.product_price_input.clear()
self.product_state_input.clear()
self.product_characteristics_input.clear()
def view_products(self):
cur = self.conn.cursor()
cur.execute("SELECT * FROM products")
rows = cur.fetchall()
self.products_table.setRowCount(len(rows))
self.products_table.setColumnCount(7)
self.products_table.setHorizontalHeaderLabels(
['ID', 'Название', 'Описание', 'Категория', 'Цена', 'Состояние', 'Характеристики'])
for row_num, row_data in enumerate(rows):
for col_num, col_data in enumerate(row_data):
self.products_table.setItem(row_num, col_num, QTableWidgetItem(str(col_data)))
def setup_warehouses_tab(self):
layout = QVBoxLayout()
self.warehouse_name_label = QLabel("Название:")
self.warehouse_name_input = QLineEdit()
self.warehouse_address_label = QLabel("Адрес:")
self.warehouse_address_input = QLineEdit()
self.warehouse_type_label = QLabel("Тип:")
self.warehouse_type_input = QLineEdit()
self.add_warehouse_button = QPushButton("Добавить склад")
self.view_warehouses_button = QPushButton("Просмотреть склады")
layout.addWidget(self.warehouse_name_label)
layout.addWidget(self.warehouse_name_input)
layout.addWidget(self.warehouse_address_label)
layout.addWidget(self.warehouse_address_input)
layout.addWidget(self.warehouse_type_label)
layout.addWidget(self.warehouse_type_input)
layout.addWidget(self.add_warehouse_button)
layout.addWidget(self.view_warehouses_button)
self.warehouses_table = QTableWidget()
layout.addWidget(self.warehouses_table)
self.warehouses_tab.setLayout(layout)
self.add_warehouse_button.clicked.connect(self.add_warehouse)
self.view_warehouses_button.clicked.connect(self.view_warehouses)
def add_warehouse(self):
name = self.warehouse_name_input.text()
address = self.warehouse_address_input.text()
warehouse_type = self.warehouse_type_input.text()
if name and address and warehouse_type:
sql = ''' INSERT INTO warehouses(name, address, type)
VALUES(?,?,?) '''
cur = self.conn.cursor()
cur.execute(sql, (name, address, warehouse_type))
self.conn.commit()
self.warehouse_name_input.clear()
self.warehouse_address_input.clear()
self.warehouse_type_input.clear()
def view_warehouses(self):
cur = self.conn.cursor()
cur.execute("SELECT * FROM warehouses")
rows = cur.fetchall()
self.warehouses_table.setRowCount(len(rows))
self.warehouses_table.setColumnCount(4)
self.warehouses_table.setHorizontalHeaderLabels(['ID', 'Название', 'Адрес', 'Тип'])
for row_num, row_data in enumerate(rows):
for col_num, col_data in enumerate(row_data):
self.warehouses_table.setItem(row_num, col_num, QTableWidgetItem(str(col_data)))
def setup_stocks_tab(self):
layout = QVBoxLayout()
self.stock_product_label = QLabel("Товар:")
self.stock_product_combo = QComboBox()
self.update_stock_product_combo()
self.stock_warehouse_label = QLabel("Склад:")
self.stock_warehouse_combo = QComboBox()
self.update_stock_warehouse_combo()
self.stock_quantity_label = QLabel("Количество:")
self.stock_quantity_input = QLineEdit()
self.stock_min_label = QLabel("Мин. уровень:")
self.stock_min_input = QLineEdit()
self.stock_optimal_label = QLabel("Оптимальный уровень:")
self.stock_optimal_input = QLineEdit()
self.stock_max_label = QLabel("Макс. уровень:")
self.stock_max_input = QLineEdit()
self.add_stock_button = QPushButton("Добавить запас")
self.view_stocks_button = QPushButton("Просмотреть запасы")
layout.addWidget(self.stock_product_label)
layout.addWidget(self.stock_product_combo)
layout.addWidget(self.stock_warehouse_label)
layout.addWidget(self.stock_warehouse_combo)
layout.addWidget(self.stock_quantity_label)
layout.addWidget(self.stock_quantity_input)
layout.addWidget(self.stock_min_label)
layout.addWidget(self.stock_min_input)
layout.addWidget(self.stock_optimal_label)
layout.addWidget(self.stock_optimal_input)
layout.addWidget(self.stock_max_label)
layout.addWidget(self.stock_max_input)
layout.addWidget(self.add_stock_button)
layout.addWidget(self.view_stocks_button)
self.stocks_table = QTableWidget()
layout.addWidget(self.stocks_table)
self.stocks_tab.setLayout(layout)
self.add_stock_button.clicked.connect(self.add_stock)
self.view_stocks_button.clicked.connect(self.view_stocks)
def update_stock_product_combo(self):
cur = self.conn.cursor()
cur.execute("SELECT id, name FROM products")
rows = cur.fetchall()
self.stock_product_combo.clear()
for row in rows:
self.stock_product_combo.addItem(f"{row[1]} (ID: {row[0]})", row[0])
def update_stock_warehouse_combo(self):
cur = self.conn.cursor()
cur.execute("SELECT id, name FROM warehouses")
rows = cur.fetchall()
self.stock_warehouse_combo.clear()
for row in rows:
self.stock_warehouse_combo.addItem(f"{row[1]} (ID: {row[0]})", row[0])
def add_stock(self):
product_id = self.stock_product_combo.currentData()
warehouse_id = self.stock_warehouse_combo.currentData()
quantity = self.stock_quantity_input.text()
min_level = self.stock_min_input.text()
optimal_level = self.stock_optimal_input.text()
max_level = self.stock_max_input.text()
if product_id and warehouse_id and quantity and min_level and optimal_level nd max_level:
sql = ''' INSERT INTO stocks(product_id, warehouse_id, current_quantity, in_level, optimal_level, max_level)
VALUES(?,?,?,?,?,?) '''
cur = self.conn.cursor()
cur.execute(sql,
(product_id, warehouse_id, int(quantity), int(min_level), nt(optimal_level), int(max_level)))
self.conn.commit()
self.stock_quantity_input.clear()
self.stock_min_input.clear()
self.stock_optimal_input.clear()
self.stock_max_input.clear()
QMessageBox.information(self, "Успех", "Запас успешно добавлен!")
def view_stocks(self):
cur = self.conn.cursor()
cur.execute("""
SELECT s.id, p.name, w.name, s.current_quantity, s.min_level, s.optimal_level, s.max_level
FROM stocks s
JOIN products p ON s.product_id = p.id
JOIN warehouses w ON s.warehouse_id = w.id
""")
rows = cur.fetchall()
self.stocks_table.setRowCount(len(rows))
self.stocks_table.setColumnCount(7)
self.stocks_table.setHorizontalHeaderLabels(
['ID', 'Товар', 'Склад', 'Текущее кол-во', 'Мин. уровень', 'Оптимальный уровень', 'Макс. уровень'])
for row_num, row_data in enumerate(rows):
for col_num, col_data in enumerate(row_data):
self.stocks_table.setItem(row_num, col_num, QTableWidgetItem(str(col_data)))
def setup_suppliers_tab(self):
layout = QVBoxLayout()
self.supplier_name_label = QLabel("Название:")
self.supplier_name_input = QLineEdit()
self.supplier_contact_label = QLabel("Контактная информация:")
self.supplier_contact_input = QLineEdit()
self.add_supplier_button = QPushButton("Добавить поставщика")
self.view_suppliers_button = QPushButton("Просмотреть поставщиков")
layout.addWidget(self.supplier_name_label)
layout.addWidget(self.supplier_name_input)
layout.addWidget(self.supplier_contact_label)
layout.addWidget(self.supplier_contact_input)
layout.addWidget(self.add_supplier_button)
layout.addWidget(self.view_suppliers_button)
self.suppliers_table = QTableWidget()
layout.addWidget(self.suppliers_table)
self.suppliers_tab.setLayout(layout)
self.add_supplier_button.clicked.connect(self.add_supplier)
self.view_suppliers_button.clicked.connect(self.view_suppliers)
def add_supplier(self):
name = self.supplier_name_input.text()
contact_info = self.supplier_contact_input.text()
if name and contact_info:
sql = ''' INSERT INTO suppliers(name, contact_info)
VALUES(?,?) '''
cur = self.conn.cursor()
cur.execute(sql, (name, contact_info))
self.conn.commit()
self.supplier_name_input.clear()
self.supplier_contact_input.clear()
def view_suppliers(self):
cur = self.conn.cursor()
cur.execute("SELECT * FROM suppliers")
rows = cur.fetchall()
self.suppliers_table.setRowCount(len(rows))
self.suppliers_table.setColumnCount(3)
self.suppliers_table.setHorizontalHeaderLabels(['ID', 'Название', 'Контактная информация'])
for row_num, row_data in enumerate(rows):
for col_num, col_data in enumerate(row_data):
self.suppliers_table.setItem(row_num, col_num, QTableWidgetItem(str(col_data)))
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = WarehouseApp()
ex.show()
sys.exit(app.exec_())