Как получить доступ к виджету / идентификатору из класса с помощью всплывающего виджета (кнопки) в KIvy

#python #class #popup #kivy #screen

#python #класс #всплывающее окно #kivy #экран

Вопрос:

У меня возникли проблемы с доступом к идентификатору виджета из класса ( здесь SecondWindow ). В этом классе есть кнопка с идентификатором name_btn , которая запускает всплывающее окно, в котором есть TextInput виджет с идентификатором my_field . Я хочу изменить text значение кнопки на SecondWindow то, что пользователь пишет в textinput… Как я могу это сделать.

Я попытался получить доступ к тексту кнопки с помощью self.parent.ids.name_btn.text, но он выдает сообщение об ошибке AttributeError: 'super' object has no attribute '__getattr__' . Любая помощь доступна, мои коды приведены ниже>>

main.py

 import kivy
import kivymd
kivy.require('1.10.1')
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager , Screen
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.floatlayout import FloatLayout


class Main(Screen):
    pass

class SecondWindow(Screen):
    name_btn = ObjectProperty(None)
    def pop_(self):
        pop_up()


class WindowManager(ScreenManager):
    pass  

class time_intrvl(FloatLayout): 
    
    my_field = ObjectProperty(None)
    
    def yeah(self):
        self.parent.ids.name_btn.text = self.my_field.text


class ExamPortal(MDApp):

    def build(self):
        kv = Builder.load_file('my.kv')        
        return kv
        
def pop_up():
    pop_window = time_intrvl()
    PopUpWindow = Popup(title = 'Enter Time' ,content = pop_window,size_hint = (0.5,0.3))
    PopUpWindow.open()         
            

if __name__ == "__main__":
    ExamPortal().run()
  

и my.kv

         
<time_intrvl>:

    my_field : my_field

    TextInput:
        id : my_field
        multiline : False
        pos_hint : {'x':0.1 , 'top': 0.74}
        size_hint : None,None
        size : 200,60
        font_size : 26
        

        
    Button:
        size_hint : None , None
        text : 'Done'
        size : 80,26
        font_size : 14    
        pos_hint : {'x':0.8,'top':0.18}
        on_release:
            root.yeah()
            
WindowManager:
    Main:
    SecondWindow:
              
<Main>:
    name : 'main'
    GridLayout:
        cols : 1
        Button:
            
            text : 'Go to SecondWindow'
            on_release:
                app.root.current = 'sec_wind'
<SecondWindow>
    name : 'sec_wind'
    name_btn : name_btn
    
    GridLayout:
        cols : 1
        Button:
            id : name_btn
            text:'Enter Text'
            on_release:
                root.pop_()                
  

`

Ответ №1:

Несколько небольших изменений, чтобы заставить работать то, что вы хотите. Измените pop_up() , чтобы вернуть PopUpWindow , чтобы он мог быть доступен для закрытия:

 def pop_up():
    pop_window = time_intrvl()
    PopUpWindow = Popup(title = 'Enter Time' ,content = pop_window,size_hint = (0.5,0.3))
    PopUpWindow.open()
    return PopUpWindow
  

Затем измените SecondWindow , чтобы сохранить ссылку на PopUpWindow :

 class SecondWindow(Screen):
    name_btn = ObjectProperty(None)
    def pop_(self):
        self.popup = pop_up()
  

И, наконец, измените time_intrvl , чтобы изменить текст кнопки и отклонить PopUpWindow :

 class time_intrvl(FloatLayout):

    my_field = ObjectProperty(None)

    def yeah(self):
        second_window = MDApp.get_running_app().root.get_screen('sec_wind')
        second_window.name_btn.text = self.my_field.text
        second_window.popup.dismiss()
  

Приведенный выше код используется MDApp.get_running_app() для получения ссылки на App , затем получает root из App , который является WindowManager . Затем он использует get_screen() метод для получения ссылки на SecondWindow . С помощью этой ссылки мы можем затем изменить текст кнопки и отклонить PopUpWindow .

Комментарии:

1. спасибо, брат, однако я не могу понять, как WindowManager стал корнем приложения.

2. и, брат, еще больше сомнений в том, как возможно, что мы напрямую обращаемся к переменной, которая находится внутри функции, как будто мы не сделали эту переменную глобальной переменной. здесь я имею в self.popup виду то, что находится pop_ во втором окне

3. WindowManager Файл, в kv котором WindowManager правило отображается как корневая строка без окружения, имеет значение root <> .

4. Это self.popup не глобальная переменная, но это переменная экземпляра the SecondWindow , которая позволяет получить к ней доступ с помощью self. конструкции.

5. Брат sry беспокоит, но еще одно сомнение, как я могу получить доступ к виджетам здесь TextInput <my_field> , которые принадлежат всплывающему, а не экрану. Я хочу получить доступ к текстовому вводу из класса SecondWndow screen