Kivy中点击按钮关闭Popup报错的技术求助
Kivy登录弹窗关闭报错解决方案
问题描述
使用Kivy开发登录界面,当用户输入密码不一致时弹出Popup提示,但点击弹窗内的"understood"按钮尝试关闭时,出现以下错误:
TypeError: PopupWindow.understood() missing 1 required positional argument: 'popup'
错误原因
PopupWindow错误继承了Screen类:它作为弹窗的内容控件,不需要是Screen,应该继承布局类(如FloatLayout)。understood方法定义冗余参数:创建弹窗时已经将popupwindow对象赋值给了show.popup,不需要再传popup参数。- 弹窗关闭逻辑错误:原代码中
popup.manager.current.dismiss()写法完全错误,关闭弹窗直接调用popup.dismiss()即可。 - 不必要的Screen注册:将
PopupWindow添加到WindowManager中是多余的,因为它不是一个独立页面。
修复步骤
1. 修改Python代码
import kivy from kivy.app import App from kivy.lang import Builder from kivy.properties import ObjectProperty from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.popup import Popup from kivy.uix.floatlayout import FloatLayout kivy.require('2.2.1') class FirstWindow(Screen): username = ObjectProperty(None) password = ObjectProperty(None) re_password = ObjectProperty(None) def PopupWindow(self): show = PopupWindow() popupwindow = Popup( title="Warning!", content=show, size_hint=(None, None), size=(400, 400) ) popupwindow.open() show.popup = popupwindow def log_in(self): if self.username.text.strip() and self.password.text.strip() == self.re_password.text.strip(): print("Greetings! ", self.username.text) print("your password is: ", self.password.text) self.manager.current = "second" elif self.password.text.strip() != self.re_password.text.strip(): print("please check your inputs: ") print("your input for password: ", self.password.text) print("your input for re_password: ", self.re_password.text) self.PopupWindow() else: if not self.username.text.strip(): print("Username is required!") if not self.password.text.strip(): print("Password is required!") if not self.re_password.text.strip(): print("Re-password is required!") def clear_input(self): self.username.text = "" self.password.text = "" self.re_password.text = "" print("cleared!") class SecondWindow(Screen): def back_button(self): self.manager.current = "create" class ThirdWindow(Screen): pass # 修改:继承FloatLayout而非Screen class PopupWindow(FloatLayout): # 修改:移除冗余的popup参数,直接使用已赋值的self.popup def understood(self): self.popup.dismiss() class WindowManager(ScreenManager): pass class MainApp(App): def build(self): kv = Builder.load_file("my.kv") return kv if __name__ == '__main__': MainApp().run()
2. 修改kv文件
WindowManager: FirstWindow: SecondWindow: ThirdWindow: # 移除:不再需要将PopupWindow注册为Screen <FirstWindow>: name: "create" username: username password: password re_password: re_password BoxLayout: orientation: "vertical" spacing: 5 padding: 50 cols: 1 Image: source: "447.png" size_hint_y: 0.1 Label: text: "User_Login" size_hint_y: 0.1 BoxLayout: orientation: "horizontal" size_hint_y: 0.1 padding: 15 Label: text: "User_Name: " TextInput: id: username multiline: False BoxLayout: orientation: "horizontal" size_hint_y: 0.1 padding: 15 Label: text: "Enter_Password: " TextInput: id: password multiline: False BoxLayout: orientation: "horizontal" size_hint_y: 0.1 padding: 15 Label: text: "Re_Enter_Password: " TextInput: id: re_password multiline: False BoxLayout: orientation: "horizontal" size_hint_y: 0.1 pos_hint: {'center_x': 0.5} spacing: 10 Button: text: "Clear" on_press: root.clear_input() Button: text: "Submit" on_press: root.log_in() <SecondWindow>: name: "second" BoxLayout: orientation: "vertical" spacing: 5 padding: 50 Label: text: "You just Logged in!" Button: text: "Back" on_press: root.back_button() <PopupWindow>: # 移除:不需要name属性,因为不是Screen BoxLayout: orientation: "vertical" Label: text: "please check your password" Button: text: "understood" on_release: root.understood()
额外优化点
- 原代码中
size_hint_y: "0.1dp"写法错误,size_hint是比例值,不需要加单位,改成size_hint_y: 0.1即可。 - 将
multiline: "False"改为multiline: False,因为该属性接受布尔值而非字符串。 log_in方法中的条件判断优化,用elif替代第二个if,避免逻辑分支冲突。
内容的提问来源于stack exchange,提问作者Jubibani
相关产品推荐
相关产品推荐

