V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
woshichuanqilz
V2EX  ›  问与答

pyqt 关闭事件的问题 AttributeError: 'RegisterWindow' object has no attribute 'closed'. Did you mean: 'close'?

  •  
  •   woshichuanqilz · 2023-04-23 12:00:38 +08:00 · 599 次点击
    这是一个创建于 571 天前的主题,其中的信息可能已经有所发展或是发生改变。

    self.registerWin.closed.connect(self.on_reg_window_closed) 这行代码运行的时候报错 AttributeError: 'RegisterWindow' object has no attribute 'closed'. Did you mean: 'close'?

    RegisterWindow 继承于 QWidget class RegisterWindow(QWidget):

    就是现在如果我想实现子窗口打开的时候主窗口隐藏, 反之显示, 所以这里需要用一个子窗口的关闭事件, 但是出现这个问题如何解决?

    # -*- coding: utf-8 -*-
    from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout
    from registerWindow import RegisterWindow
    from PyQt6 import QtCore, QtWidgets
    
    
    class LoginWindow(QWidget):
        def __init__(self):
            super().__init__()
    
            # 设置窗口大小
            self.setGeometry(200, 200, 400, 200)
    
            # 创建控件
            self.username_label = QLabel('用户名')
            self.username_input = QLineEdit()
            self.password_label = QLabel('密码')
            self.password_input = QLineEdit()
            self.login_button = QPushButton('登录')
            self.register_button = QPushButton('注册')
    
            # 创建布局
            layout = QVBoxLayout()
            layout.addWidget(self.username_label)
            layout.addWidget(self.username_input)
            layout.addWidget(self.password_label)
            layout.addWidget(self.password_input)
            layout.addWidget(self.login_button)
            layout.addWidget(self.register_button)
    
            # 设置布局
            self.setLayout(layout)
    
            # 子窗口
            self.registerWin = RegisterWindow()
            self.registerWin.closed.connect(self.on_reg_window_closed)
    
            # 连接信号和槽
            self.login_button.clicked.connect(self.on_login_button_clicked)
            self.register_button.clicked.connect(self.on_register_button_clicked)
    
        def on_sub_window_closed(self):
            # 子窗口已关闭
            print("子窗口已关闭")
    
        def on_login_button_clicked(self):
            username = self.username_input.text()
            password = self.password_input.text()
    
            # 在这里可以添加验证用户输入的代码,如果验证通过则可以跳转到主界面
    
        def on_register_button_clicked(self):
            self.hide()
            self.registerWin.show()
    
        def on_reg_window_closed(self):
            self.show()
    
    
    if __name__ == '__main__':
        app = QApplication([])
        login_window = LoginWindow()
        login_window.show()
        app.exec()
    
    
    4 条回复    2023-04-23 13:39:20 +08:00
    NoOneNoBody
        1
    NoOneNoBody  
       2023-04-23 12:54:40 +08:00
    提示不是写了么
    QWindow 和 QWidget 都没有 closed 这个信号,应该用 visibleChanged 或者 activeChanged ,或者写个自定义的 close event
    woshichuanqilz
        2
    woshichuanqilz  
    OP
       2023-04-23 13:10:51 +08:00
    @NoOneNoBody https://doc.qt.io/qt-6/qwidget.html#signals

    我查了一下这个网站, 发现 qwidget 的 signal 只有三个吗?
    woshichuanqilz
        3
    woshichuanqilz  
    OP
       2023-04-23 13:11:39 +08:00
    这样感觉这个比较简单的功能也要单独定义一个信号也挺麻烦的
    NoOneNoBody
        4
    NoOneNoBody  
       2023-04-23 13:39:20 +08:00
    @woshichuanqilz #2
    QWidget 是一个泛类型控件,就是给用户自定义用的,所以不会有比较专用的信号
    你试想想,如果用 QWidget 设计一个类 Button 控件,能有 colse 方法么?

    另外,信号不止三个的,它也是继承,父级有不少信号可用,你要循着手册去搜

    close() 其实是个组合事件,包括 hide 、destory 等,各自都可以做相应的事,qt 的思想是细分,让用户处理
    qt 可以算是属于 GUI“底层开发”
    如果你想直接对一个组合事件处理:
    1. 找人家写好的三方包
    2. 可以写一个自定义类(构件)继承,放到公共目录,以后从这个构件去创建就好了
    我就写了不少,例如文本框+文件浏览按钮+fileopen/save 对话框,以后写文件读写就直接调用不用再研究三者组合了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5583 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 93ms · UTC 06:34 · PVG 14:34 · LAX 22:34 · JFK 01:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.