创建一个窗口
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 文件时不需要执行