You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy中点击按钮关闭Popup报错的技术求助

Kivy登录弹窗关闭报错解决方案

问题描述

使用Kivy开发登录界面,当用户输入密码不一致时弹出Popup提示,但点击弹窗内的"understood"按钮尝试关闭时,出现以下错误:

TypeError: PopupWindow.understood() missing 1 required positional argument: 'popup'

错误原因

  1. PopupWindow错误继承了Screen类:它作为弹窗的内容控件,不需要是Screen,应该继承布局类(如FloatLayout)。
  2. understood方法定义冗余参数:创建弹窗时已经将popupwindow对象赋值给了show.popup,不需要再传popup参数。
  3. 弹窗关闭逻辑错误:原代码中popup.manager.current.dismiss()写法完全错误,关闭弹窗直接调用popup.dismiss()即可。
  4. 不必要的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:05:31