创建一个窗口

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 文件时不需要执行