Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
Python
SQL
Shell
Markdown
YAML
JSON
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
TypeScript
Perl
Lua
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
from kivy.config import Config Config.set('graphics', 'width', '360') Config.set('graphics', 'height', '640') Config.set('graphics', 'resizable', '0') from kivy.app import App from kivy.lang import Builder from kivy.animation import Animation from kivy.core.window import Window from kivy.metrics import dp from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.widget import Widget from kivy.uix.behaviors import ButtonBehavior from kivy.uix.label import Label from kivy.uix.modalview import ModalView from kivy.properties import StringProperty from kivy.utils import platform from kivy.clock import Clock Builder.load_string('''
: canvas: Color: rgba: 0, 0, 0, 0 Rectangle: pos: self.pos size: self.size
: orientation: 'horizontal' size_hint_y: None height: dp(50) spacing: dp(5) padding: dp(5) canvas.before: Color: rgba: 0.4, 0.4, 0.6, 1 Rectangle: pos: self.pos size: self.size Label: id: title_label text: root.item_title size_hint_x: 0.8 halign: 'left' valign: 'middle' text_size: self.width, None color: 1, 1, 1, 1 font_size: dp(16) bold: True Button: id: info_button text: 'i' size_hint_x: 0.2 size_hint_y: 1 background_normal: '' background_color: 0.8, 0.8, 0.2, 1 font_size: dp(14) bold: True on_press: root.show_info()
: size_hint: (0.8, 0.5) auto_dismiss: True BoxLayout: orientation: 'vertical' padding: dp(20) spacing: dp(10) canvas.before: Color: rgba: 0.3, 0.3, 0.5, 1 Rectangle: pos: self.pos size: self.size Label: text: root.title font_size: dp(20) bold: True color: 1, 1, 1, 1 size_hint_y: 0.3 Label: text: root.description font_size: dp(16) color: 1, 1, 1, 1 text_size: self.width, None valign: 'top' halign: 'left' size_hint_y: 0.7 Button: text: 'Close' size_hint_y: 0.2 background_normal: '' background_color: 0.8, 0.3, 0.3, 1 on_press: root.dismiss()
: orientation: 'vertical' spacing: dp(5) # Results notification panel BoxLayout: id: notification_panel size_hint_y: None height: 0 opacity: 0 canvas.before: Color: rgba: 0.2, 0.8, 0.4, 0.9 Rectangle: pos: self.pos size: self.size Label: id: notification_label text: '' color: 1, 1, 1, 1 font_size: dp(18) bold: True halign: 'center' padding: [dp(10), dp(5)] # Main content area with scrollable items ScrollView: id: content_scroll size_hint_y: 1 do_scroll_y: True BoxLayout: id: items_container orientation: 'vertical' size_hint_y: None height: self.minimum_height spacing: dp(5) padding: [dp(10), dp(0)] # Search panel (fixed at the bottom) BoxLayout: id: search_controls size_hint_y: None height: dp(60) padding: dp(10) spacing: dp(5) TextInput: id: search_field hint_text: 'Enter search query...' multiline: False size_hint_x: 0.8 padding: [dp(10), (self.height - self.line_height)/2] font_size: dp(16) on_focus: root.on_search_focus_changed(*args) on_text_validate: root.perform_search() Button: id: action_btn text: 'Add' size_hint_x: 0.2 font_size: dp(13) bold: True background_normal: '' background_color: (0.4, 0.6, 0.4, 1) on_press: root.toggle_notification_panel() # Invisible overlay for keyboard dismissal ClickableOverlay: id: keyboard_dismiss_area size_hint_y: None height: 0 on_press: root.hide_virtual_keyboard() ''') class ClickableOverlay(ButtonBehavior, Widget): """Transparent overlay for handling keyboard dismissal clicks""" pass class InfoDialog(ModalView): """Custom dialog for displaying item information""" title = StringProperty('') description = StringProperty('') class ContentItem(ButtonBehavior, BoxLayout): """Interactive content item with title and information button""" item_title = StringProperty('') item_description = StringProperty('') def __init__(self, item_title="", item_description="", **kwargs): super().__init__(**kwargs) self.item_title = item_title self.item_description = item_description def on_press(self): app = App.get_running_app() app.root.ids.notification_label.text = f"Selected: {self.item_title}" if app.root.ids.notification_panel.height == 0: app.root.show_notification_panel() def show_info(self): """Display information dialog for this item""" dialog = InfoDialog(title=self.item_title, description=self.item_description) dialog.open() class SearchApplicationUI(BoxLayout): """Main application interface with search functionality""" def __init__(self, **kwargs): super().__init__(**kwargs) # 1. Инициализация переменной с высотой по умолчанию self.keyboard_height = dp(0) # Значение по умолчанию # 2. Запоминаем исходную высоту окна self.original_window_height = Window.height # 3. Настройка внешнего вида Window.clearcolor = (0.4, 0.4, 0.4, 1) # 4. Инициализация контента self.initialize_content() # 5. Привязка обработчиков событий Window.bind(on_keyboard=self.handle_keyboard_event) Window.bind(on_resize=self.handle_window_resize) # 6. Запуск измерения клавиатуры с небольшой задержкой Clock.schedule_once(lambda dt: self.measure_keyboard_height(), 1) def handle_window_resize(self, window, width, height): """Обработчик изменения размера окна""" # Здесь можно добавить логику реагирования на изменение размера окна pass def measure_keyboard_height(self): """Временный показ клавиатуры для определения её высоты""" if not hasattr(self, '_measurement_done'): # Устанавливаем фокус в текстовое поле, чтобы вызвать клавиатуру self.ids.search_field.focus = True # Исправлено с search_input на search_field # Запланировать замер через 0.5 секунды, когда клавиатура точно появится Clock.schedule_once(self._finish_measurement, 0.5) def _finish_measurement(self, dt): """Завершение процесса измерения высоты клавиатуры""" # Сравниваем текущую высоту окна с исходной if Window.height < self.original_window_height: # Разница в высоте и есть высота клавиатуры self.keyboard_height = self.original_window_height - Window.height print(f"Keyboard height measured: {self.keyboard_height}dp") # Убираем фокус и скрываем клавиатуру self.ids.search_field.focus = False self._measurement_done = True def handle_keyboard_event(self, window, key, *args): """Handle hardware back button press""" if key == 27: # ESC key if self.ids.search_field.focus: self.hide_virtual_keyboard() return True return False def hide_virtual_keyboard(self): """Dismiss the virtual keyboard""" self.ids.search_field.focus = False def initialize_content(self): """Populate the content area with sample items""" for i in range(1, 21): item = ContentItem( item_title=f'Item {i}', item_description=f'Detailed description for item {i}. ' f'This contains all relevant information about the item.' ) self.ids.items_container.add_widget(item) def on_search_focus_changed(self, instance, has_focus): """Handle search field focus changes""" self.ids.keyboard_dismiss_area.height = self.keyboard_height if has_focus else 0 def on_search_focus_changed(self, instance, has_focus): """Handle search field focus changes""" self.ids.keyboard_dismiss_area.height = self.keyboard_height if has_focus else 0 def toggle_notification_panel(self): """Toggle the notification panel visibility""" if self.ids.notification_panel.height == 0: query = self.ids.search_field.text.strip() if query: self.ids.notification_label.text = f"Added: {query}" self.show_notification_panel() else: self.hide_notification_panel() def show_notification_panel(self): """Animate notification panel appearance""" Animation(height=dp(50), opacity=1, duration=0.3).start(self.ids.notification_panel) self.ids.action_btn.text = "Remove" self.ids.action_btn.background_color = (0.8, 0.3, 0.3, 1) def hide_notification_panel(self): """Animate notification panel disappearance""" Animation(height=0, opacity=0, duration=0.3).start(self.ids.notification_panel) self.ids.action_btn.text = "Add" self.ids.action_btn.background_color = (0.4, 0.6, 0.4, 1) def perform_search(self): """Execute search operation""" query = self.ids.search_field.text.strip() if query: self.ids.notification_label.text = f"Found: {query}" if self.ids.notification_panel.height == 0: self.show_notification_panel() class SearchApplication(App): """Main application class""" def build(self): return SearchApplicationUI() if __name__ == '__main__': SearchApplication().run()
Mark as private
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year