从“ on_enter”内部调用时出现Kivy Popup行为异常

问题描述

如果今天是数据库上的日期,我想显示一个弹出窗口。

问题是弹出窗口弹出,但是它似乎内置在主屏幕后面。 我想这是由于要在“ on_enter”方法调用,但无法解决此问题。

enter image description here

请注意,此“设置”按钮是从主屏幕而不是弹出窗口本身呈现的。

这是我的main.py:

from kivy.uix.Boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen,ScreenManager
from datetime import date,datetime
from calendar import weekday
from kivymd.toast import toast
from kivymd.uix.list import TwoLineIconListItem
from kivymd.uix.picker import MDDatePicker,MDTimePicker
from datahelper import CreateTable,InsertEstudo,DeletStudy,ReadStudy,UpdateStudy
from kivy.factory import Factory


class Gerenciador(ScreenManager):
    pass


class Main(Screen):
    # def verificar_estudos(self):
    def on_enter(self,*args):
        ler_dbestudos = ReadStudy()
        resultado = ler_dbestudos.ler_estudos()
        for s in resultado:
            dia = s[2].split("-")[-1]
            mes = s[2].split("-")[-2]
            ano = s[2].split("-")[0]
            print(f"{dia}/{mes}/{ano}")
        dia_hoje = date.today().day
        mes_hoje = date.today().month
        ano_hoje = date.today().year

        if int(dia) == dia_hoje:
            print('Hoje é dia de revisão de matéria')
            tudo = self.children
            Factory.DiaDeRevisao().open()
        if int(dia) + 14 == dia_hoje:
            print('Hoje é dia de revisão de matéria')
            Factory.DiaDeRevisao().open()
        if int(mes)+1 == mes_hoje:
            print('Hoje é dia de revisão de matéria')
            Factory.DiaDeRevisao().open()


class Revisao(Screen):
    def ver_estudos(self,*args):
        read_studies = ReadStudy()
        studies = read_studies.ler_estudos()
        for s in studies:
            self.ids.scrollviewid.add_widget(TwoLineIconListItem(text=s[1],secondary_text=s[2]))

    def ver_lista(self,*args):
        for r in range(20):
            self.ids.scrollviewid.add_widget(TwoLineIconListItem(text='Azul',secondary_text="Texto Secundário"))


class AddStudy(Screen):
    def open_calendar(self):
        date_dialog = MDDatePicker(callback=self.get_date)
        if self.ids.dtinist.focused == True:
            date_dialog.open()

    def get_date(self,*args):
        '''
          :type date: <class 'datetime.date'>
          '''
        print(args[0])
        print(type(args[0]))
        self.ids.dtinist.focused = False
        self.ids.dtinist.text = str(args[0])
        self.ids.dtinist.focused = False
        return args[0]

    def open_clock(self):
        time_dialog = MDTimePicker()
        time_dialog.bind(time=self.get_time)
        if self.ids.tminist.focused == True:
            time_dialog.open()

    def get_time(self,*args):
        self.ids.tminist.focused = False
        self.ids.tminist.text = str(args[1])
        self.ids.tminist.focused = False
        return args[1]

    def selected(self,path,selection):
        tipo = selection[0].split(".")[-1]
        print(tipo)
        if tipo == 'mp3':
            toast('Arquivo MP3 selecionado')
            with open(selection[0],'rb') as f:
                barq = f.read()
                insert = InsertEstudo()
                insert.criar_novo_estudo()

    def confirm_new(self):
        materia = self.ids.materia_estudo.text
        data_estudo = self.ids.dtinist.text
        hora_estudo = self.ids.tminist.text
        insert_new_study = InsertEstudo()

        if insert_new_study.criar_novo_estudo(materia,data_estudo,hora_estudo):
            toast('Estudo adicionado com sucesso')
        else:
            toast('Algo deu muito errado. O estudo não foi adicionado. Tente novamente mais tarde')


class SettingsScreen(Screen):

    def select_path(self,path):
        print(path)
        '''It will be called when you click on the file name
        or the catalog selection button.

        :type path: str;
        :param path: path to the selected directory or file;
        '''

        self.exit_manager()
        toast(path)

    def open_file_manager(self):
        self.file_manager.show('/')  # output manager to the screen
        self.manager_open = True

    def exit_manager(self):
        self.manager_open = False
        self.file_manager.close()


class SelectAlarm(Screen):
    def selected(self,'rb') as f:
                barq = f.read()
                insert = InsertEstudo()
                insert.criar_novo_estudo()
        else:
            toast('Por favor,seleecione um arquivo mp3')


class BoraEstudarapp(MDApp):

    def on_pause(self):
        return True

    def build(self):
        data_hoje = f"{date.today().year}-{date.today().month}-{date.today().day}"
        sm = Gerenciador()
        sm.add_widget(Main(name='Principal'))
        sm.add_widget(SettingsScreen(name='Preferencias'))
        sm.add_widget(AddStudy(name='NovaMateria'))
        sm.add_widget(Revisao(name='Revisoes'))
        sm.add_widget(SelectAlarm(name='Selecionaralarme'))

        return sm


if __name__ == "__main__":
    boraestudar = BoraEstudarapp()
    boraestudar.run()

这是我的kv文件

#:import Factory kivy.factory.Factory
<ScreenManager>:


<DiaDeRevisao@Popup>:
    title: 'Atenção dia de revisão'
    auto_dismiss: False
    size_hint:0.7,0.7
    BoxLayout:
        canvas.before:
            Color:
                rgba:(1,1,1)
            Rectangle:
                size: self.size
                pos: self.pos
        BoxLayout:
            orientation:'vertical'
            MDLabel:
                text:'Hoje é dia de revisão'
            Button:
                text: 'OK'
                on_press: root.dismiss()

<FileChooserPop@Popup>:
    title:'Escolha o arquivo de audio MP3'
    BoxLayout:
        canvas.before:
            Color:
                rgba:(0,0.35)
            Rectangle:
                size: self.size
                pos: self.pos

        orientation: 'vertical'

        BoxLayout:
            size_hint_y: None
            height: sp(52)

            Button:
                text: 'Icon View'
                on_press: fc.view_mode = 'icon'
            Button:
                text: 'List View'
                on_press: fc.view_mode = 'list'

        FileChooser:
            id: fc
            FileChooserIconLayout
            FileChooserListLayout

        BoxLayout:
            size_hint_y: None
            MDTextButton:
                size_hint_x:0.4
                text: 'Voltar'
                on_press: root.dismiss()

            MDIconButton:
                halign:'center'
                icon:'content-save'
                on_press:root.selected(fc.path,fc.selection)
                on_release: root.manager.current = 'Principal'

<Main>:
    BoxLayout:
        orientation:"vertical"
        spacing:'50dp'
        padding:'70dp'
        BoxLayout:
            MDTextButton:
                text: 'Revisões'
                on_press: root.manager.current = 'Revisoes'
#                on_release:Factory.FileChooserPop().open()
        BoxLayout:
            Button:
                text: 'Settings'
                on_press: root.manager.current = 'Preferencias'
        BoxLayout:
            MDIconButton:
                icon: "plus"
                on_press: root.manager.current = 'NovaMateria'


<AddStudy>:
    BoxLayout:
        orientation:'vertical'
        spacing:'100sp'
        padding: '100dp'
        MDTextField:
            id:materia_estudo
            hint_text: 'Matéria'

        MDTextField:
            id: dtinist
            text: ''
            hint_text: 'data do Estudo'
            on_focus: root.open_calendar()

        MDTextField:
            id:tminist
            text:''
            hint_text: 'Hora do Estudo'
            on_focus: root.open_clock()

        BoxLayout:
            MDTextButton:
                text:'Voltar'
                on_press: root.manager.current = 'Principal'
            MDTextButton:
                text: 'Salvar'
                on_press: root.confirm_new()
<SettingsScreen>:
    BoxLayout:
        MDTextButton:
            text: 'Selecionar Alarme'
            on_press: root.manager.current = 'Selecionaralarme'


<SelectAlarm>:
    BoxLayout:
        canvas.before:
            Color:
                rgba:(0,0.35)
            Rectangle:
                size: self.size
                pos: self.pos

        orientation: 'vertical'

        BoxLayout:
            size_hint_y: None
            height: sp(52)

            Button:
                text: 'Icon View'
                on_press: fc.view_mode = 'icon'
            Button:
                text: 'List View'
                on_press: fc.view_mode = 'list'

        FileChooser:
            id: fc
            FileChooserIconLayout
            FileChooserListLayout

        BoxLayout:
            size_hint_y: None
            MDTextButton:
                size_hint_x:0.4
                text: 'Voltar'
                on_press: root.manager.current = 'Principal'

            MDIconButton:
                halign:'center'
                icon:'content-save'
                on_press:root.selected(fc.path,fc.selection)
                on_release: root.manager.current = 'Principal'

<Revisao>:
    BoxLayout:
        orientation:'vertical'
        BoxLayout:
            ScrollView:
                do_scroll_y: True
                size_hint_y: None
                height: '500dp'
                MDList:
                    id:scrollviewid
        BoxLayout:
            size_hint_y: 0.15
            MDTextButton:
                size_hint_x: None
                text:"Voltar"
                on_release: root.manager.current = 'Principal'
            MDTextButton:
                text:"Ver Lista"
                on_release: root.ver_estudos()


这很奇怪,我无法弄清楚。

感谢您的帮助。干杯!

解决方法

问题在于on_enter()事件触发得太早,因此PopupMain Screen之前被绘制。您可以通过在显示Popup之前添加很短的延迟来解决此问题。我更改了:

Factory.DiaDeRevisao().open()

收件人:

Clock.schedule_once(lambda dt: Factory.DiaDeRevisao().open())

将提供该延迟,并允许Popup显示在Screen上方。