从“on_enter”内部调用时 Kivy 弹出错误行为
Posted
技术标签:
【中文标题】从“on_enter”内部调用时 Kivy 弹出错误行为【英文标题】:Kivy Popup misbehaviour when called from inside 'on_enter' 【发布时间】:2020-12-22 16:30:15 【问题描述】:我正在尝试显示一个弹出窗口,以防今天是 DB 上的日期。
问题是弹出窗口,但它似乎是在主屏幕后面构建的。 我想这是由于在“on_enter”方法上被调用,但无法解决这个问题。
请注意,此“设置”按钮是从主屏幕呈现的,而不是从弹出窗口本身呈现的。
这是我的 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, 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()
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,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,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,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()
这很奇怪,我想不通。
感谢您的帮助。干杯!
【问题讨论】:
【参考方案1】:问题是on_enter()
事件被触发得太早,所以Popup
在Main
Screen
之前被绘制。您可以通过在显示Popup
之前添加一个非常短的延迟来解决此问题。我改变了:
Factory.DiaDeRevisao().open()
到:
Clock.schedule_once(lambda dt: Factory.DiaDeRevisao().open())
将提供该延迟并允许Popup
显示在Screen
之上。
【讨论】:
太棒了!绝对正确。我知道时间有问题,但完全忘记了时钟的事情......谢谢,伙计!以上是关于从“on_enter”内部调用时 Kivy 弹出错误行为的主要内容,如果未能解决你的问题,请参考以下文章