|
@@ -0,0 +1,250 @@
|
|
|
|
+**["Задание на автомат"]()**
|
|
|
|
+***
|
|
|
|
+**Python (Kivy/KivyMD)**
|
|
|
|
+***
|
|
|
|
+**main.py**
|
|
|
|
+***
|
|
|
|
+```
|
|
|
|
+from kivy.app import App
|
|
|
|
+from kivymd.app import MDApp # Импорт главного окна приложения
|
|
|
|
+from kivy.uix.boxlayout import BoxLayout # Импорт бокслояута для добавления в него виджетов
|
|
|
|
+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.button import MDIconButton # Импорт для иконок кнопок
|
|
|
|
+from kivy.uix.image import Image # Импорт для изображения
|
|
|
|
+
|
|
|
|
+import json
|
|
|
|
+
|
|
|
|
+class SearchBoxLayout(BoxLayout):
|
|
|
|
+ def __init__(self, **kwargs):
|
|
|
|
+ super().__init__(**kwargs)
|
|
|
|
+ self.orientation = 'vertical'
|
|
|
|
+ self.padding = [50, 0, 50, 50]
|
|
|
|
+
|
|
|
|
+ # Импорт фотографии
|
|
|
|
+ self.image = Image(
|
|
|
|
+ source='net.jpg',
|
|
|
|
+ size_hint_y=0.3
|
|
|
|
+ )
|
|
|
|
+ self.add_widget(self.image)
|
|
|
|
+
|
|
|
|
+ # Панель поиска и фильтрации
|
|
|
|
+ search_filter_bar = BoxLayout(size_hint_y=None, height=dp(40), spacing=10)
|
|
|
|
+ self.add_widget(search_filter_bar)
|
|
|
|
+
|
|
|
|
+ # Строка поиска
|
|
|
|
+ self.search_field = MDTextField(
|
|
|
|
+ hint_text="Search...",
|
|
|
|
+ size_hint_x=0.7
|
|
|
|
+ )
|
|
|
|
+ self.search_field.bind(text=self.filter_table)
|
|
|
|
+ search_filter_bar.add_widget(self.search_field)
|
|
|
|
+
|
|
|
|
+ # Кнопки фильтрации
|
|
|
|
+ self.asc_button = MDIconButton(icon="arrow-up-drop-circle")
|
|
|
|
+ self.asc_button.bind(on_release=self.sort_ascending)
|
|
|
|
+ search_filter_bar.add_widget(self.asc_button)
|
|
|
|
+
|
|
|
|
+ self.desc_button = MDIconButton(icon="arrow-down-drop-circle")
|
|
|
|
+ self.desc_button.bind(on_release=self.sort_descending)
|
|
|
|
+ search_filter_bar.add_widget(self.desc_button)
|
|
|
|
+
|
|
|
|
+ # Выпадающий список для выбора машины
|
|
|
|
+ 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'),
|
|
|
|
+ size_hint=(None, None),
|
|
|
|
+ size=(dp(200), dp(44)),
|
|
|
|
+ pos_hint={'center_x': 0.5}
|
|
|
|
+ )
|
|
|
|
+ self.spinner_car.bind(text=self.filter_table_by_name)
|
|
|
|
+ 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}
|
|
|
|
+ )
|
|
|
|
+ self.spinner_price.bind(text=self.filter_table_by_price)
|
|
|
|
+ search_filter_bar.add_widget(self.spinner_price)
|
|
|
|
+
|
|
|
|
+ # Прокрутка для таблицы
|
|
|
|
+ self.scrollview = ScrollView(size_hint_y=0.7)
|
|
|
|
+ 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
|
|
|
|
+
|
|
|
|
+ def sort_ascending(self, instance):
|
|
|
|
+ # Сортировка таблицы по цене в порядке возрастания
|
|
|
|
+ self.data_table.row_data = sorted(self.original_row_data, key=lambda row: int(row[2]))
|
|
|
|
+
|
|
|
|
+ def sort_descending(self, instance):
|
|
|
|
+ # Сортировка таблицы по цене в порядке убывания
|
|
|
|
+ self.data_table.row_data = sorted(self.original_row_data, key=lambda row: int(row[2]), reverse=True)
|
|
|
|
+
|
|
|
|
+class MyApp(MDApp):
|
|
|
|
+ def build(self):
|
|
|
|
+ return SearchBoxLayout()
|
|
|
|
+
|
|
|
|
+if __name__ == '__main__':
|
|
|
|
+ MyApp().run()
|
|
|
|
+```
|
|
|
|
+***
|
|
|
|
+**json**
|
|
|
|
+***
|
|
|
|
+```
|
|
|
|
+[
|
|
|
|
+ {
|
|
|
|
+ "Название": "Toyota Trueno AE86",
|
|
|
|
+ "Год": 1995,
|
|
|
|
+ "Цена": 15000,
|
|
|
|
+ "Цвет": "white",
|
|
|
|
+ "Повреждения": "True",
|
|
|
|
+ "Дата СТО": "19/04/2024",
|
|
|
|
+ "image": "tru.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Toyota Supra A80",
|
|
|
|
+ "Год": 1996,
|
|
|
|
+ "Цена": 30000,
|
|
|
|
+ "Цвет": "black",
|
|
|
|
+ "Повреждения": "False",
|
|
|
|
+ "Дата СТО": "09/02/2024",
|
|
|
|
+ "image": "su.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Nissan Skyline R34",
|
|
|
|
+ "Год": 1996,
|
|
|
|
+ "Цена": 25000,
|
|
|
|
+ "Цвет": "orange",
|
|
|
|
+ "Повреждения": "False",
|
|
|
|
+ "Дата СТО": "10/07/2024",
|
|
|
|
+ "image": "sk.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Nissan Silvia S15Nissan Silvia S15",
|
|
|
|
+ "Год": 1999,
|
|
|
|
+ "Цена": 20000,
|
|
|
|
+ "Цвет": "gray",
|
|
|
|
+ "Повреждения": "False",
|
|
|
|
+ "Дата СТО": "20/03/20244",
|
|
|
|
+ "image": "sil.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Toyota Camry 3.5",
|
|
|
|
+ "Год": 2020,
|
|
|
|
+ "Цена": 20000,
|
|
|
|
+ "Цвет": "blue",
|
|
|
|
+ "Повреждения": "False",
|
|
|
|
+ "Дата СТО": "19/04/2024",
|
|
|
|
+ "image": "ca.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Audi RS 6",
|
|
|
|
+ "Год": 2016,
|
|
|
|
+ "Цена": 30000,
|
|
|
|
+ "Цвет": "lightblue",
|
|
|
|
+ "Повреждения": "True",
|
|
|
|
+ "Дата СТО": "10/07/2024",
|
|
|
|
+ "image": "au.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Трактор LOVOL TE354 HT",
|
|
|
|
+ "Год": 2024,
|
|
|
|
+ "Цена": 66666,
|
|
|
|
+ "Цвет": "brown",
|
|
|
|
+ "Повреждения": "False",
|
|
|
|
+ "Дата СТО": "19/04/2024",
|
|
|
|
+ "image": "tr.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "BMW M5 F90",
|
|
|
|
+ "Год": 2019,
|
|
|
|
+ "Цена": 30000,
|
|
|
|
+ "Цвет": "black",
|
|
|
|
+ "Повреждения": "True",
|
|
|
|
+ "Дата СТО": "20/03/20244",
|
|
|
|
+ "image": "b.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "BMW E36",
|
|
|
|
+ "Год": 2006,
|
|
|
|
+ "Цена": 35000,
|
|
|
|
+ "Цвет": "red",
|
|
|
|
+ "Повреждения": "False",
|
|
|
|
+ "Дата СТО": "19/04/2024",
|
|
|
|
+ "image": "bm.jpg"
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "Название": "Daewoo Matiz",
|
|
|
|
+ "Год": 2010,
|
|
|
|
+ "Цена": 20000,
|
|
|
|
+ "Цвет": "pink",
|
|
|
|
+ "Повреждения": "True",
|
|
|
|
+ "Дата СТО": "10/07/2024",
|
|
|
|
+ "image": "ma.jpg"
|
|
|
|
+ }
|
|
|
|
+]
|
|
|
|
+```
|
|
|
|
+![](./img/1.png)
|
|
|
|
+![](./img/2.png)
|
|
|
|
+![](./img/3.png)
|
|
|
|
+![](./img/4.png)
|
|
|
|
+![](./img/5.png)
|