|
@@ -2,22 +2,48 @@
|
|
|
***
|
|
|
**Python (Kivy/KivyMD)**
|
|
|
***
|
|
|
-**main.py**
|
|
|
+**main2.py**
|
|
|
***
|
|
|
```
|
|
|
from kivy.app import App
|
|
|
from kivymd.app import MDApp # Импорт главного окна приложения
|
|
|
from kivy.uix.boxlayout import BoxLayout # Импорт бокслояута для добавления в него виджетов
|
|
|
+from kivy.uix.gridlayout import GridLayout # Импорт гридлояута для добавления элементов в виде сетки
|
|
|
from kivy.uix.spinner import Spinner # Импорт для выпадающего списка
|
|
|
-from kivymd.uix.datatables import MDDataTable # Импорт для таблицы
|
|
|
-from kivy.metrics import dp # Импорт для изменения размера
|
|
|
-from kivy.uix.scrollview import ScrollView # Импорт для прокрутки таблицы
|
|
|
-from kivymd.uix.textfield import MDTextField # Импорт для строки ввода
|
|
|
+from kivymd.uix.textfield import MDTextField # Импорт для таблицы
|
|
|
from kivymd.uix.button import MDIconButton # Импорт для иконок кнопок
|
|
|
-from kivy.uix.image import Image # Импорт для изображения
|
|
|
+from kivy.uix.image import Image # Импорт для изменения размера
|
|
|
+from kivy.uix.label import Label # Импорт Label для отображения текста
|
|
|
+from kivy.uix.scrollview import ScrollView # Импорт для прокрутки таблицы
|
|
|
+from kivy.metrics import dp # Импорт для изменения размера
|
|
|
+from kivy.utils import get_color_from_hex # Импорт для использования шестнадцатеричных цветовых кодов
|
|
|
|
|
|
import json
|
|
|
|
|
|
+class CarItem(BoxLayout):
|
|
|
+ def __init__(self, car_data, **kwargs):
|
|
|
+ super().__init__(**kwargs)
|
|
|
+ self.orientation = 'horizontal'
|
|
|
+ self.size_hint_y = None
|
|
|
+ self.height = dp(100)
|
|
|
+ self.padding = [10, 10, 10, 10]
|
|
|
+
|
|
|
+ self.image = Image(
|
|
|
+ source=car_data.get('image'),
|
|
|
+ size_hint_x=0.3,
|
|
|
+ allow_stretch=True
|
|
|
+ )
|
|
|
+ self.add_widget(self.image)
|
|
|
+
|
|
|
+ info_layout = BoxLayout(orientation='vertical')
|
|
|
+ self.add_widget(info_layout)
|
|
|
+
|
|
|
+ self.name_label = Label(text=car_data['Название'], font_size=18, color=get_color_from_hex('#000000'))
|
|
|
+ info_layout.add_widget(self.name_label)
|
|
|
+
|
|
|
+ self.price_label = Label(text=f"{car_data['Цена']} руб.", font_size=16, color=get_color_from_hex('#000000'))
|
|
|
+ info_layout.add_widget(self.price_label)
|
|
|
+
|
|
|
class SearchBoxLayout(BoxLayout):
|
|
|
def __init__(self, **kwargs):
|
|
|
super().__init__(**kwargs)
|
|
@@ -38,9 +64,9 @@ class SearchBoxLayout(BoxLayout):
|
|
|
# Строка поиска
|
|
|
self.search_field = MDTextField(
|
|
|
hint_text="Search...",
|
|
|
- size_hint_x=0.7
|
|
|
+ size_hint_x=0.5
|
|
|
)
|
|
|
- self.search_field.bind(text=self.filter_table)
|
|
|
+ self.search_field.bind(text=self.filter_items)
|
|
|
search_filter_bar.add_widget(self.search_field)
|
|
|
|
|
|
# Кнопки фильтрации
|
|
@@ -55,89 +81,78 @@ class SearchBoxLayout(BoxLayout):
|
|
|
# Выпадающий список для выбора машины
|
|
|
self.spinner_car = Spinner(
|
|
|
text='Выберите машину',
|
|
|
- values=('Toyota Trueno AE86', 'Toyota Supra A80', 'Nissan Skyline R34', 'Nissan Silvia S15', 'Toyota Camry 3.5', 'Audi RS 6', 'Трактор LOVOL TE354 HT', 'BMW M5 F90', 'BMW E36', 'Daewoo Matiz'),
|
|
|
+ values=[],
|
|
|
size_hint=(None, None),
|
|
|
- size=(dp(200), dp(44)),
|
|
|
- pos_hint={'center_x': 0.5}
|
|
|
+ size=(dp(200), dp(44))
|
|
|
)
|
|
|
- self.spinner_car.bind(text=self.filter_table_by_name)
|
|
|
+ self.spinner_car.bind(text=self.filter_items)
|
|
|
search_filter_bar.add_widget(self.spinner_car)
|
|
|
-
|
|
|
# Выпадающий список для выбора ценового диапазона
|
|
|
self.spinner_price = Spinner(
|
|
|
text='Выберите цену',
|
|
|
values=('10000 - 20000', '21000 - 30000', '31000 - 70000'),
|
|
|
size_hint=(None, None),
|
|
|
- size=(dp(200), dp(44)),
|
|
|
- pos_hint={'center_x': 0.5}
|
|
|
+ size=(dp(200), dp(44))
|
|
|
)
|
|
|
- self.spinner_price.bind(text=self.filter_table_by_price)
|
|
|
+ self.spinner_price.bind(text=self.filter_items)
|
|
|
search_filter_bar.add_widget(self.spinner_price)
|
|
|
|
|
|
# Прокрутка для таблицы
|
|
|
- self.scrollview = ScrollView(size_hint_y=0.7)
|
|
|
+ self.scrollview = ScrollView()
|
|
|
self.add_widget(self.scrollview)
|
|
|
|
|
|
- # Создание таблицы
|
|
|
- self.data_table = MDDataTable(
|
|
|
- size_hint=(1, 1),
|
|
|
- use_pagination=True,
|
|
|
- rows_num=10,
|
|
|
- column_data=[
|
|
|
- ("Название", dp(30)),
|
|
|
- ("Год", dp(15)),
|
|
|
- ("Цена", dp(15)),
|
|
|
- ("Цвет", dp(15)),
|
|
|
- ("Повреждения", dp(25)),
|
|
|
- ("Дата СТО", dp(30))
|
|
|
- ],
|
|
|
- # Инициализируем row_data пустым списком, данные будут загружены из JSON
|
|
|
- row_data=[]
|
|
|
- )
|
|
|
- self.scrollview.add_widget(self.data_table)
|
|
|
-
|
|
|
- # Загрузка данных из JSON файла
|
|
|
- self.load_data_from_json('package.json')
|
|
|
-
|
|
|
- def load_data_from_json(self, json_path):
|
|
|
- # Загрузка данных из JSON файла и обновление таблицы
|
|
|
- with open(json_path, 'r', encoding='utf-8') as json_file:
|
|
|
- data = json.load(json_file)
|
|
|
- # Предполагаем, что данные в JSON файле имеют формат списка словарей
|
|
|
- row_data = [(d['Название'], d['Год'], d['Цена'], d['Цвет'], d['Повреждения'], d['Дата СТО']) for d in data]
|
|
|
- self.data_table.row_data = row_data
|
|
|
- self.original_row_data = row_data
|
|
|
- self.original_row_data = self.data_table.row_data
|
|
|
-
|
|
|
- def filter_table(self, instance, text):
|
|
|
- # Фильтрация таблицы по поиску
|
|
|
- filtered_data = []
|
|
|
- for row in self.original_row_data:
|
|
|
- if text.lower() in row[0].lower():
|
|
|
- filtered_data.append(row)
|
|
|
- self.data_table.row_data = filtered_data
|
|
|
-
|
|
|
- def filter_table_by_name(self, spinner, text):
|
|
|
- # Фильтрация таблицы по названию машины
|
|
|
- if text != 'Выберите машину':
|
|
|
- filtered_data = [row for row in self.original_row_data if row[0] == text]
|
|
|
- self.data_table.row_data = filtered_data
|
|
|
-
|
|
|
- def filter_table_by_price(self, spinner, text):
|
|
|
- # Фильтрация таблицы по ценовому диапазону
|
|
|
- if text != 'Выберите цену':
|
|
|
- price_range = text.split(' - ')
|
|
|
- min_price, max_price = int(price_range[0]), int(price_range[1])
|
|
|
- filtered_data = [row for row in self.original_row_data if min_price <= int(row[2]) <= max_price]
|
|
|
- self.data_table.row_data = filtered_data
|
|
|
+ # Сетчатая разметка для хранения элементов автомобиля
|
|
|
+ self.car_grid = GridLayout(cols=1, spacing=10, size_hint_y=None)
|
|
|
+ self.car_grid.bind(minimum_height=self.car_grid.setter('height'))
|
|
|
+ self.scrollview.add_widget(self.car_grid)
|
|
|
+
|
|
|
+ # Загрузка данных из JSON
|
|
|
+ self.car_data = self.load_data_from_json('package.json')
|
|
|
+ self.original_car_data = self.car_data.copy()
|
|
|
+ self.populate_car_grid()
|
|
|
+
|
|
|
+ self.spinner_car.values = list({car['Название'] for car in self.car_data})
|
|
|
+
|
|
|
+ def load_data_from_json(self, filename):
|
|
|
+ with open(filename, 'r', encoding='utf-8') as f:
|
|
|
+ data = json.load(f)
|
|
|
+ return data
|
|
|
+
|
|
|
+ def populate_car_grid(self):
|
|
|
+ # Заполнение сетки виджетов
|
|
|
+ self.car_grid.clear_widgets()
|
|
|
+ for car in self.car_data:
|
|
|
+ car_item = CarItem(car)
|
|
|
+ self.car_grid.add_widget(car_item)
|
|
|
+
|
|
|
+ def filter_items(self, instance, *args):
|
|
|
+ # Сортировка по названию и цене
|
|
|
+ filtered_data = self.original_car_data.copy()
|
|
|
+
|
|
|
+ search_text = self.search_field.text.lower()
|
|
|
+ filtered_data = [car for car in filtered_data if search_text in car['Название'].lower()]
|
|
|
+
|
|
|
+ selected_car = self.spinner_car.text
|
|
|
+ if selected_car != 'Выберите машину':
|
|
|
+ filtered_data = [car for car in filtered_data if car['Название'] == selected_car]
|
|
|
+
|
|
|
+ price_range = self.spinner_price.text
|
|
|
+ if price_range != 'Выберите цену':
|
|
|
+ min_price, max_price = map(int, price_range.split(' - '))
|
|
|
+ filtered_data = [car for car in filtered_data if min_price <= int(car['Цена']) <= max_price]
|
|
|
+
|
|
|
+ self.car_data = filtered_data
|
|
|
+ self.populate_car_grid()
|
|
|
|
|
|
def sort_ascending(self, instance):
|
|
|
# Сортировка таблицы по цене в порядке возрастания
|
|
|
- self.data_table.row_data = sorted(self.original_row_data, key=lambda row: int(row[2]))
|
|
|
+ self.car_data = sorted(self.car_data, key=lambda x: int(x['Цена']))
|
|
|
+ self.populate_car_grid()
|
|
|
|
|
|
def sort_descending(self, instance):
|
|
|
# Сортировка таблицы по цене в порядке убывания
|
|
|
- self.data_table.row_data = sorted(self.original_row_data, key=lambda row: int(row[2]), reverse=True)
|
|
|
+ self.car_data = sorted(self.car_data, key=lambda x: int(x['Цена']), reverse=True)
|
|
|
+ self.populate_car_grid()
|
|
|
|
|
|
class MyApp(MDApp):
|
|
|
def build(self):
|
|
@@ -243,8 +258,4 @@ if __name__ == '__main__':
|
|
|
}
|
|
|
]
|
|
|
```
|
|
|
-![](./img/1.png)
|
|
|
-![](./img/2.png)
|
|
|
-![](./img/3.png)
|
|
|
-![](./img/4.png)
|
|
|
-![](./img/5.png)
|
|
|
+![](./img/7.png)
|