004.PyQt5_两种方式创建一个窗体

创建一个窗口

1.1 面向过程版本代码

  • 代码示例
    from PyQt5.Qt import *
    import sys
     
    app=QApplication(sys.argv)
     
    window=QWidget()
    window.setWindowTitle('我的第一个窗体')
    window.resize(500,500)
    window.move(400,200)
     
    label=QLabel(window)
    label.setText('Hello World!')
    label.move(200,200)
    window.show()
    sys.exit(app.exec_())
    
  • 运行结果:
  • 代码说明:
    # 0.导入需要的包和模块
    from PyQt5.Qt import * # 主要包含了我们常用的一些类
    import sys
     
    # sys.argv:当别人通过命令行启动这个程序的时候,可以设定一种功能(接收命令行传递的参数,来执行不同的业务逻辑
    # 1.创建一个应用程序
    app=QApplication(sys.argv)
     
    # 2.控件的操作(创建控件,设置控件大小、位置、样式,事件,信号的处理...)
    # 2.1 创建一个窗口
    """
    当我们创建一个控件之后,如果说,这个控件没有父控件,
    则把它当作是顶层控件(窗口),系统会自动给这个窗口添加一些装饰(标题栏),
    窗口控件具备一些特性(设置标题、图标)
    """
    window=QWidget()
    # 设置窗口标题
    window.setWindowTitle('我的第一个窗体')
    # 设置窗口大小
    window.resize(500,500)
    # 设置窗口位置
    window.move(400,200)
     
    # 2.2 设置控件
    # 控件也可以作为一个容器(承载其他的控件)
    # 设置一个标签,展示在窗口内部
    label=QLabel(window) # 注意传参window,否则label不会出现在窗口上
    # 设置标签里的内容
    label.setText('Hello World!')
    # 设置位置
    label.move(200,200)
      
    # 2.3 展示窗口
    # 刚创建好一个控件后,(这个控件没有什么父控件),默认情况下不会被展示,只有手动show一下
    # 如果这个控件,有父控件的,那么一般情况下,父控件展示后,子控件会自动展示
    window.show()
     
    # 3.应用程序的执行,进入到消息循环(无限循环),否则窗口就会show一次之后消失
    # 检测到整个程序所接收到的用户的交互信息
    sys.exit(app.exec_()) # 退出码,0表示正常退出(自动结束或用户手动关闭),非0表示异常退出
    

1.2 面向对象版本代码

  • 代码示例
    from PyQt5.Qt import *
    import sys
    
    
    class Window(QWidget):#继承QWidget类
        # 重写父类__init__方法
        def __init__(self):
            # 重用父类的__init__方法
            super().__init__()
            self.setWindowTitle('面向对象创建窗体')
            self.resize(500, 500)
            
        #添加子控件
        def setup_ui(self):
            label = QLabel(self)
            label.setText('点击点击...')
            
    if __name__=='__main__':
        app=QApplication(sys.argv)
        window=Window()
        window.setup_ui()
        window.show()
        sys.exit(app.exec_())
    
  • 运行结果:

  • 面向过程的缺点:
    • 代码冗余量大
    • 修改某控件查找麻烦
  • 面向对象继承的提出
    • 创建面向对象不能瞎改原本的类,可以考虑通过继承来实现
    # 0.导入包和模块
    from PyQt5.Qt import *
    import sys
    
    
    # 继承类、定义自己的方法
    class Window(QWidget):
        def __init__(self):
            print("继承类")
    
    
    # 1.创建应用程序对象
    app = QApplication(sys.argv)
    
    # 2.1 创建控件
    window = Window()
    
    # 2.2 设置控件
    window.setWindowTitle("用了继承类")
    window.resize(500, 500)
    
    # 2.3 展示控件
    window.show()
    
    # 3.进入消息循环
    sys.exit(app.exec_())
    
    
  • 运行报错:父类的 init() 方法没有被调用
  • 错误原因:当我们用 window = QWidget() 方法去创建控件时,会自动调用系统提供给我们的 QWidget 的 init 方法。但在继承过程中,重新写了 init 方法,导致创建对象时,会自动先调用子类 init 方法,而子类 init 方法没有调用父类 init 方法里的准备操作。
  • 解决方法:在子类的 init 方法里首先调用父类的 init 方法,即不是替换而是在原基础上增加自己的配置。修改后的类继承如下:
    # 0.导入包和模块
    from PyQt5.Qt import *
    import sys
    
    
    # 继承类、定义自己的方法
    class Window(QWidget):
        def __init__(self):
            # super后自动补全后面的内容
            super(Window, self).__init__()
            print("继承类")
    
    
    # 1.创建应用程序对象
    app = QApplication(sys.argv)
    
    # 2.1 创建控件
    window = Window()
    
    # 2.2 设置控件
    window.setWindowTitle("用了继承类")
    window.resize(500, 500)
    
    # 2.3 展示控件
    window.show()
    
    # 3.进入消息循环
    sys.exit(app.exec_())
    
    
  • 运行结果:
  • 输出了”继承类“这三个字还有原来那个窗口。
  • 同理,可以把菜单栏的控件相关配置全都塞到继承类里面去(就像 print 语句)。
  • 类的封装
  • self:通过 Window 类创建出来的实例对象
    # 继承类、定义自己的方法
    class Window(QWidget):
        def __init__(self):
            super(Window, self).__init__()
            self.setWindowTitle("面向对象")
            self.resize(500, 500)
    
            label = QLabel(self)
            label.setText("标签签")
    
    
  • 把子控件的添加单独列到一个方法里面去
    # 继承类、定义自己的方法
    class Window(QWidget):
        # 初始化
        def __init__(self):
            super(Window, self).__init__()
            self.setWindowTitle("面向对象")
            self.resize(500, 500)
            self.setup_ui()
    
        # 存放所有子控件以及子控件的配置操作
        def setup_ui(self):
            label = QLabel(self)
            label.setText("标签签")
    
    
  • 从功能层面与刚刚的写法并无区别,但从结构来说这个更清晰。
  • 再进一步,把导入的包和继承的类放在另一个 python 文件 Menu.py (注意该文件名称得是英语)中,然后如下一句话就可以导入类。
    from Menu import Window
    
  • 这样,通过类增强了代码的可维护性,有问题直接改这个类,其他地方统统不需要动。
  • 类的测试
  • 如果需要去测试类的功能是否正常,直接在 Menu.py 文件中加上测试代码就行。
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
    
  • 但该测试部分在被导入时是不需要执行的,这时候就用到了
    if __name__ == '__main__': 
    

它帮助我们的测试代码只有在右键运行时才会执行,而在被导入其他 python 文件时不需要执行

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失心疯_2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值