当前位置: 首页 > news >正文

品牌宣传型网站建设方案怎么做拍卖网站

品牌宣传型网站建设方案,怎么做拍卖网站,一流的基础微网站开发,顶尖的赣州网站建设PyQt5快速入门 PyQt5的快速入门0. 写在前面1. 思维导图2. 第一个PyQt5的应用程序3. PyQt5的常用基本控件和布局3.1 PyQt5的常用基本控件3.1.1 按钮控件 QPushButton3.1.2 文本标签控件 QLabel3.1.3 单行输入框控件 QLineEdit3.1.4 A Quick Widgets Demo 3.2 PyQt5的常用基本控件… PyQt5快速入门 PyQt5的快速入门0. 写在前面1. 思维导图2. 第一个PyQt5的应用程序3. PyQt5的常用基本控件和布局3.1 PyQt5的常用基本控件3.1.1 按钮控件 QPushButton3.1.2 文本标签控件 QLabel3.1.3 单行输入框控件 QLineEdit3.1.4 A Quick Widgets Demo 3.2 PyQt5的常用基本控件的基本属性编辑3.2.1 调整窗口大小3.2.2 调整窗口位于屏幕中间3.2.3 设置窗体图标3.2.4 隐藏窗口标签栏 3.3 PyQt5的常用布局3.3.1 盒子布局垂直版QVBoxLayout3.3.2 盒子布局水平版QHBoxLayout3.3.3 网格布局QGridLayout3.3.4 表单布局QFormLayout3.3.5 栈布局QStackLayout 3.4 PyQt5常用的三种窗口3.4.1 PyQt5之QWidget3.4.2 PyQt5之QMainWindow3.4.3 PyQt5之QDialog 4. PyQt5的信号和槽4.1 信号与槽之接收信号4.2 信号与槽之自定义信号4.3 信号与槽之实例练习 5. PyQt5的多线程5.1 PyQt5多线程基础语法实例 6. PyQt5的界面设计神器——Qt Designer快速入门6.1 Qt Designer界面介绍6.2 将Qt Designer的UI文件集成到Python GUI项目 7. PyQt5综合案例 参考资料进一步学习 PyQt5的快速入门 0. 写在前面 本文为博主个人对自己学习PyQt5GUI技术的纲要式的总结主要的目的是以比较宏观的视角再次对PyQt5这一项技术作一次总结通过该文可以快速让读者建立起PyQt5最基本的知识体系了解PyQt5的基本界面的设计、信号与槽和多线程等知识并简单学会使用Qt Designer工具来实现快速的Python GUI界面设计。特别感谢王铭东老师在B站上发布的PyQt5快速入门视频教程。博主个人在学习的过程中全程跟敲了代码现完全开源感兴趣的同学可以在这里获取。 1. 思维导图 以下是博主个人在学习的过程中绘制的简要的 “辅助读懂PyQt5” 所需掌握的基本知识体系需要注意的事情是PyQt5的知识远远不止下图中所展示出来的内容在实际的项目开发中需要我们能在掌握必要的常识的基础上根据实际的项目需求学会自己主动查找有用的资料并最终完成自己的开发任务。 2. 第一个PyQt5的应用程序 import sys from PyQt5.QtWidgets import QApplication, QWidgetif __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(第一个PyQt5程序)# 设置窗口背景色w.setStyleSheet(background-color: rgb(255, 255, 255);)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()如上文的代码所示运行后我们可以得到这样的一个窗口 from PyQt5.QtWidgets import QApplication, QWidget我们可以使用from module import ....的形式来导入我们在进行Python GUI开发中所需要的库这些库通常是QtWidgets,QtGui和QtCore。 在Python的GUI开发中我们需要了解的是任何一个PyQt的应用程序都是从app QApplication(sys.argv)QApplication开始的。每一个应用程序都需要也仅仅需要一个QApplication来管理整个应用程序。 QWidget是PyQt中默认的三种重要的窗口之一我们需要根据我们具体的GUI开发的需求来选择我们使用的基础的窗口类型。这里我们使用w QWidget()来实例化一个QWidget实例。实例化窗口之后窗口本身是有很多的属性可以被设置的这一部分我们会在下文有适当的总结并展开说说。比如在这个样例中我们主要是使用了w.setWindowTitle(第一个PyQt5程序)来设置了窗口的标题并且使用了w.setStyleSheet(background-color: rgb(255, 255, 255);)来设置窗口的背景色为白色。 通过w.show()我们可以让我们所定义的窗体的实例对象展示出来。 最后我们通过app.exec_()来让应用程序进入事件循环(Event loop)。另外这里之所以使用的是exec_是为了避免与Python 2中的exec保留字发生冲突。 与应用程序的每次交互无论是按键、单击鼠标还是鼠标移动都会生成一个事件该事件放置在事件队列中。在事件循环中在每次迭代时检查队列如果找到等待事件则将事件和控制传递给事件的特定事件处理程序。事件处理程序处理事件然后将控制权传递回事件循环以等待更多事件。每个应用程序只有一个正在运行的事件循环。 3. PyQt5的常用基本控件和布局 3.1 PyQt5的常用基本控件 3.1.1 按钮控件 QPushButton import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButtonif __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之按钮)# 在窗口里面添加按钮控件btn QPushButton(按钮)# 把按钮绑定到对应的窗口等于是添加到窗口中显示btn.setParent(w)# 设置窗口背景色w.setStyleSheet(background-color: rgb(255, 255, 255);)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()这里其实符合面向对象编程的编程逻辑这些UI控件本质上都是一类一类的对象在使用这些对象的时候我们需要先创建一个对象的实例然后再来对他们进行操作来实现我们想要实现的功能。通过btn QPushButton(按钮) 我们实现了在窗口里面添加按钮控件该按钮控件的文本显示为“按钮”。但是仅仅只是创建了控件的实例的话是没有办法在窗体上显示出来的还需要我们通过btn.setParent(w)把按钮绑定到对应的窗口这样我们的按钮才能够在窗口中显示。 这里的QPushButton其实只是Button类型的控件的一个典型的代表在PyQt5中实际可用的按钮控件还有很多详细可以在Qt Designer中查看或者在需要的时候查阅文档。 3.1.2 文本标签控件 QLabel import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabelif __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之文本)# 在窗口里面添加按钮控件并绑定到w窗口btn QPushButton(按钮, w)# 把按钮绑定到对应的窗口等于是添加到窗口中显示# 设置按钮的位置btn.move(100, 100)# 在窗口里面添加文本标签并绑定到w窗口label QLabel(文本标签, w)# 设置文本标签的位置# label.move(100, 150)# 设置位置与大小 (x,y)(左上角00横x纵y) (w,h)(宽度高度)label.setGeometry(100, 150, 150, 50)# 设置窗口背景色w.setStyleSheet(background-color: rgb(255, 255, 255);)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()除了上文说的xxx.setParent(w)方法,我们还可以在一开始创建控件的时候就把控件绑定到窗体上这样就简化了代码如我们可以使用label QLabel(文本标签, w)实现在窗口里面添加文本标签并直接绑定到w窗口。 import sysfrom PyQt5.QtCore import Qt from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabelif __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()w.resize(1000, 500)# 设置窗口标题w.setWindowTitle(PyQt5程序之QLabel展示图片)# 创建一个位图变量photo QPixmap(imgs/Florian.jpg)# 按比例缩放至1000*500scaled_photo photo.scaled(1000, 500, Qt.KeepAspectRatio)# 创建一个标签控件实例label QLabel(w)# 将位图变量绑定到标签控件实例上label.setPixmap(scaled_photo)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()特别地QLabel 不仅仅可以用来显示文字它还可以用来显示图片。可以使用 QLabel 通过setPixmap()显示图像。这接受一个像素图您可以通过将图像文件名传递给 QPixmap 类来创建该像素图。比如widget.setPixmap(QPixmap(otje.jpg)) 这里的QLabel其实只是Display类型的控件的一个典型的代表在PyQt5中实际可用的按钮控件还有很多详细可以在Qt Designer中查看或者在需要的时候查阅文档。 3.1.3 单行输入框控件 QLineEdit import sys from PyQt5.QtWidgets import *if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之输入框)# 纯文本label QLabel(账号, w)label.setGeometry(100, 100, 50, 30)# 文本框edit QLineEdit(w)edit.setPlaceholderText(请输入账号)edit.setGeometry(150, 100, 200, 30)# 在窗口里面添加控件btn QPushButton(注册, w)btn.setGeometry(200, 150, 80, 30)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()通常我们可以使用edit QLineEdit(w)来创建一个单行的输入框可以使用edit.setPlaceholderText(请输入账号)来设置未输入数据情况下的提示信息如果我们想要在该输入行中输入密码的话我们也可以使用password.setEchoMode(QLineEdit.Password)来将其设置为密文模式。 这里的QLineEdit其实只是Input类型的控件的一个典型的代表在PyQt5中实际可用的按钮控件还有很多详细可以在Qt Designer中查看或者在需要的时候查阅文档。 3.1.4 A Quick Widgets Demo 该部分内容转载自PyQt5 Widgets在这篇文章中更加详细地距离了PyQt的各种奇妙的控件有兴趣的读者可以从这里进入去更进一步地阅读和学习我们这里仅举其中的一个比较爆炸性的例子作为展示。 import sysfrom PyQt5.QtWidgets import (QApplication,QCheckBox,QComboBox,QDateEdit,QDateTimeEdit,QDial,QDoubleSpinBox,QFontComboBox,QLabel,QLCDNumber,QLineEdit,QMainWindow,QProgressBar,QPushButton,QRadioButton,QSlider,QSpinBox,QTimeEdit,QVBoxLayout,QWidget, )# Subclass QMainWindow to customize your applications main window class MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle(Widgets App)layout QVBoxLayout()widgets [QCheckBox,QComboBox,QDateEdit,QDateTimeEdit,QDial,QDoubleSpinBox,QFontComboBox,QLCDNumber,QLabel,QLineEdit,QProgressBar,QPushButton,QRadioButton,QSlider,QSpinBox,QTimeEdit,]for w in widgets:layout.addWidget(w())widget QWidget()widget.setLayout(layout)# Set the central widget of the Window. Widget will expand# to take up all the space in the window by default.self.setCentralWidget(widget)if __name__ __main__:app QApplication(sys.argv)window MainWindow()window.show()app.exec()Widget功能QCheckbox多选框QComboBox下拉列表框QDateEdit日期编辑框QDateTimeEdit日期及时间编辑框QDial可旋转表盘QDoubleSpinbox浮点数的数字微调器QFontComboBox字体列表QLCDNumber简易液晶数字显示屏QLabel文本标签不支持交互QLineEdit单行文本输入框QProgressBar进度条QPushButton按钮QRadioButton单选框QSlider滑块QSpinBox整数数字微调器QTimeEdit时间编辑框 3.2 PyQt5的常用基本控件的基本属性编辑 3.2.1 调整窗口大小 import sys from PyQt5.QtWidgets import *if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之调整窗口大小)# 重置窗口大小w.resize(800, 600)# 将窗口设置在屏幕的左上角# w.move(0, 0)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()#pic_center) 在 PyQt 中我们可以使用w.resize(800, 600)来对窗体或其它控件的大小属性来进行自定义两个参数分别对应的是width和height。从上图我们也可以清晰看出设置后的主窗体的大小确实就是800 * 600。 3.2.2 调整窗口位于屏幕中间 import sys from PyQt5.QtWidgets import *if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之调整窗口于正中间位置)# 重置窗口大小w.resize(800, 600)# 调整窗口在屏幕中央显示# 获取我当前屏幕桌面的中心点的位置信息center_pointer QDesktopWidget().availableGeometry().center()print(center_pointer)x center_pointer.x()y center_pointer.y()print(x, y)# 打印窗口默认的几何信息位置和大小print(w.frameGeometry())print(w.frameGeometry().getRect())print(type(w.frameGeometry().getRect()))# 获取窗口的默认几何信息old_x, old_y, width, height w.frameGeometry().getRect()print(old_x, old_y, width, height)# 基于屏幕中心点和窗口的默认大小来调至合适的屏幕中央自适应w.move(x - int(width / 2), y - int(height / 2))# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()在PyQt的坐标系的构建中是以 左上角为原点从左向右为正方向的X轴Width以及从上到下为正方向的Y轴Height 来进行坐标系的构建的。实现该效果的思路首先是先使用center_pointer QDesktopWidget().availableGeometry().center()获取我当前屏幕桌面的中心点的位置信息。然后使用old_x, old_y, width, height w.frameGeometry().getRect()获取窗口控件的几何属性主要是获取它的width和height。这时候就只需要用我们所获取到的屏幕的中心点的坐标来分别减去一般的窗体的高度和宽度这样我们就可以获得窗体相对于屏幕的坐标系中如果要让窗体显示在屏幕正中的情况下窗体左上角定位点所应该在的具体的位置坐标了这时候再使用w.move(x - int(width / 2), y - int(height / 2))重新定位即可。 3.2.3 设置窗体图标 import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之设置窗口图标)# 设置窗口图标w.setWindowIcon(QIcon(imgs/clock.png))# PyQt5隐藏上方的标签栏# w.setWindowFlag(Qt.FramelessWindowHint)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()在PyQt中我们可以使用w.setWindowIcon(QIcon(imgs/clock.png))来给我们自己的窗口添加酷炫的Icon。 3.2.4 隐藏窗口标签栏 import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget类w QWidget()# 设置窗口标题w.setWindowTitle(PyQt5程序之隐藏窗口标签栏)# PyQt5隐藏上方的标签栏w.setWindowFlag(Qt.FramelessWindowHint)# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()# 设置窗口显示w.show()# 程序进行循环等待状态app.exec_()在PyQt中我们可以使用w.setWindowFlag(Qt.FramelessWindowHint)来隐藏上方的标签栏这样我们就相当于获得了一个完全空白的窗口面板我们可以在上面来进行完全自定义的具有个性的GUI界面的设计与实现。 3.3 PyQt5的常用布局 3.3.1 盒子布局垂直版QVBoxLayout import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 设置大小self.resize(300, 300)# 设置窗口标题self.setWindowTitle(PyQt5程序之垂直布局)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 垂直布局(限制)layout QVBoxLayout()# 作用是在布局器中增加一个伸缩量里面的参数表示QSpacerItem的个数默认值为零# 会将你放在layout中的空间压缩成默认的大小# 下面的空白区域的比例为1112# 加了一个伸缩器可以理解为一个弹簧layout.addStretch(1)# 设置布局的方向layout.setDirection(QBoxLayout.TopToBottom)# 设置布局的间距layout.setContentsMargins(10, 10, 10, 10)# 设置布局的内边距layout.setSpacing(10)# 设置布局self.setLayout(layout)# 按钮1btn1 QPushButton(按钮1)# 添加到布局器中layout.addWidget(btn1, Qt.AlignmentFlag.AlignTop)# 把按钮添加到布局中layout.addWidget(btn1)# 加了一个伸缩器可以理解为一个弹簧layout.addStretch(1)# 按钮2btn2 QPushButton(按钮2)# 把按钮添加到布局中layout.addWidget(btn2)# 加了一个伸缩器可以理解为一个弹簧layout.addStretch(1)# 按钮3btn3 QPushButton(按钮3)# 把按钮添加到布局中layout.addWidget(btn3)# 加了一个伸缩器可以理解为一个弹簧layout.addStretch(2)# 让当前的窗口使用这个排列的布局器self.setLayout(layout)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()使用布局管理器可以自动调整窗口部件的大小和位置以适应窗口大小的改变。当你改变窗口的大小时布局管理器会自动重新计算窗口部件的位置和大小使得窗口部件能够适应新的窗口大小避免了手动调整窗口部件大小和位置的繁琐工作。在使用布局管理器之前我们需要使用layout QVBoxLayout()创建一个布局对象。用布局来管理控件的方式不同于直接把控件绑定到窗口的形式我们在创建控件的时候也不需要默认指定Parent取而代之的是layout.addWidget(btn1)把想要添加的控件添加到布局对象中。为了控制好所添加入布局管理器的控件与控件之前的控件距离我们可以采用layout.addStretch(2)的方式来自定义控件与控件之前的距离里面的参数是权重的比例比如在上图中我们在按钮1、2、3的前后和中间分别设置了1112的权重的伸缩器从最后的页面中我们可以看到从上到下的所有的间隙的大小分布的比例差不多就是1112。最后布局无法直接被显示需要我们使用self.setLayout(layout)让当前的窗口使用我们定义好的布局器。 3.3.2 盒子布局水平版QHBoxLayout import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(400, 400)# 设置窗口标题self.setWindowTitle(PyQt5程序之水平布局)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 垂直布局# outer_container QVBoxLayout()outer_container QHBoxLayout()# 垂直布局器中有两个组一个是爱好组另一个是性别组hobby_group QGroupBox(爱好)# 创建一个垂直布局器v_inner_layout QVBoxLayout()# 在爱好组中加入可选的爱好choice1 QRadioButton(文明6)choice2 QRadioButton(云顶之弈)choice3 QRadioButton(毕业设计)# 把组件添加到布局器中v_inner_layout.addWidget(choice1)v_inner_layout.addWidget(choice2)v_inner_layout.addWidget(choice3)# 将布局器绑定到组hobby_group.setLayout(v_inner_layout)# 把当前的爱好组加入到垂直布局中outer_container.addWidget(hobby_group)gender_group QGroupBox(性别)# 创建一个水平布局器h_inner_layout QHBoxLayout()# 在爱好组中加入可选的爱好boy QRadioButton(男)girl QRadioButton(女)# 把组件添加到布局器中h_inner_layout.addWidget(boy)h_inner_layout.addWidget(girl)# 将布局器绑定到组gender_group.setLayout(h_inner_layout)# 把当前的性别组加入到垂直布局中outer_container.addWidget(gender_group)# 让当前的窗口使用布局器self.setLayout(outer_container)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()当最顶层布局为垂直布局 当最顶层布局为水平布局 从技术角度来说水平布局的布局管理器和垂直布局的布局管理器是类似的不同的仅仅是从空间上来看它约束的空间关系是一种水平的布局。都是先使用QVBoxLayout()或者QHBoxLayout()创建一个垂直布局器或者水平布局器然后再使用addWidget()把控件添加到布局器上最后使用setLayout()让布局绑定窗口或者控件。然而这个案例中所不同的地方是布局是可以嵌套的。当然布局是无法直接嵌套在另外一层布局上的所以就需要中间的容器。在当前的例子中内部的爱好和性别的两个组控件就是这中间的容器QGroupBox()对外层的容器充当控件又作为内层的布局的容器分别添加了垂直方向和水平方向的布局管理器。 3.3.3 网格布局QGridLayout import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(300, 300)# 设置窗口标题self.setWindowTitle(PyQt5程序之QGridLayout——计算器)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 最外层是一个垂直布局布局outer_container QVBoxLayout()# 创建一个输入框input_box QLineEdit()input_box.setPlaceholderText(请输入内容)# 把输入框和按钮放到布局中outer_container.addWidget(input_box)# 创建计算器的网络布局grid QGridLayout()# 计算器网格布局的数据准备这里刻意使用一种类似json格式的键值对的数据形式data {0: [7, 8, 9, , (],1: [4, 5, 6, -, )],2: [1, 2, 3, *, -],3: [0, ., , /, C]}# 把网格布局添加到外层的垂直布局中outer_container.addLayout(grid)for key_row, numbers in data.items():for index_column, value in enumerate(numbers):btn QPushButton(value)grid.addWidget(btn, key_row, index_column)# 让当前的窗口使用布局器self.setLayout(outer_container)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()这是一个计算器的布局样例。其中的按键是通过GridLayout来实现的。创建网格布局的方式是grid QGridLayout()和其它的布局方式不同的地方主要是对于网格布局我们在添加控件addWidget()的时候还需要指定当前的控件填在网格布局中的行列坐标。坐标是从0开始计数。当然有时候我们也会遇到可能一个控件需要跨多个网格的情况这时候就需要在添加控件的时候再额外指定它所跨的行的数量和所跨的列的数量。 比如layout.addWidget(button, row, col, 1, 2) 它表示当前的按钮会占据1行2列。 import sys from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButtonclass Calculator(QWidget):def __init__(self):super().__init__()# 创建网格布局layout QGridLayout(self)# 创建按钮并添加到布局中buttons [7, 8, 9, /,4, 5, 6, *,1, 2, 3, -,0, , ]row 0col 0for btnText in buttons:if btnText 0:# 为数字“0”的按钮设置 columnSpan 为 2button QPushButton(btnText, self)layout.addWidget(button, row, col, 1, 2) # 占据1行2列col 2 # 跳过下一列else:button QPushButton(btnText, self)layout.addWidget(button, row, col)col 1# 换行条件当到达每行的最后一个按钮时if col 4 and btnText ! 0:row 1col 0# 设置窗口的基本属性self.setLayout(layout)self.setWindowTitle(计算器示例)if __name__ __main__:app QApplication(sys.argv)calc Calculator()calc.show()sys.exit(app.exec_())3.3.4 表单布局QFormLayout import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(400, 300)# 设置窗口标题self.setWindowTitle(PyQt5程序之QFormLayout)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 创建一个垂直布局作为窗口的主要布局mainLayout QVBoxLayout()# 创建一个表单布局本质上就是一行一行的部分formLayout QFormLayout()# 创建标签和对应的字段控件# 姓名行及其输入框nameLabel QLabel(姓名:)nameLineEdit QLineEdit()formLayout.addRow(nameLabel, nameLineEdit)# 电子邮箱行及其输入框emailLabel QLabel(电子邮箱:)emailLineEdit QLineEdit()formLayout.addRow(emailLabel, emailLineEdit)# 将表单布局添加到主布局中mainLayout.addLayout(formLayout)# 创建一个提交按钮并添加到主布局中submitButton QPushButton(提交)mainLayout.addWidget(submitButton)# 设置窗口的主布局self.setLayout(mainLayout)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()表单布局最特别的地方在于表单布局的控件的添加不是我们所熟悉的addWidget()它不是一个一个控件来添加的它是使用诸如formLayout.addRow(nameLabel, nameLineEdit)的形式来一行一行来进行控件的添加的。QFormLayout被设计用来创建一个两列的表单布局其中左列通常包含标签QLabel右列包含与之相关的控件如QLineEdit、QCheckBox、QPushButton等。但是这并不意味着我们必须遵循这种标签-控件的模式我们可以根据需要添加任何类型的控件到左列或右列。例如在同一行的左列添加一个QLabel而在右列添加一个QPushButton。或者你也可以在左列和右列都添加QPushButton或其他类型的控件。QFormLayout会自动处理控件的对齐和间距使得布局看起来整洁且有序。 import sys from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QLabel, QLineEdit, QPushButtonclass FormLayoutExample(QWidget):def __init__(self):super().__init__()# 创建表单布局layout QFormLayout()# 添加控件到布局中layout.addRow(Name:, QLineEdit())layout.addRow(Age:, QLineEdit())# 在同一行添加不同类型的控件button1 QPushButton(Submit)button2 QPushButton(Cancel)layout.addRow(button1, button2)# 设置窗口的基本属性self.resize(400, 100)self.setLayout(layout)self.setWindowTitle(QFormLayout 示例)if __name__ __main__:app QApplication(sys.argv)ex FormLayoutExample()ex.show()sys.exit(app.exec_())3.3.5 栈布局QStackLayout import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class Window1(QWidget):def __init__(self):super().__init__()label QLabel(这里是窗口1, self)self.setStyleSheet(background-color: red)# 设置标签内的字体的属性font QFont()font.setPointSize(20)label.setFont(font)class Window2(QWidget):def __init__(self):super().__init__()label QLabel(这里是窗口2, self)self.setStyleSheet(background-color: green)# 设置标签内的字体的属性font QFont()font.setPointSize(20)label.setFont(font)class MyWindow(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.windows_stack Noneself.init_ui()def init_ui(self):# 设置大小self.resize(400, 400)# 设置窗口标题self.setWindowTitle(PyQt5程序之QStackLayout)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 垂直布局outer_container QVBoxLayout()# 展示区控件display QWidget()display.setStyleSheet(background-color:grey)# 为展示区控件绑定抽屉布局(加上self的含义是让它变成一个类变量)self.windows_stack QStackedLayout()# 创建两个新的窗口对象window1 Window1()window2 Window2()self.windows_stack.addWidget(window1)self.windows_stack.addWidget(window2)# 将抽屉布局绑定到展示控件上display.setLayout(self.windows_stack)# 按钮控件btn1 QPushButton(切换到窗口一)btn2 QPushButton(切换到窗口二)# 为按钮设置单击事件btn1.clicked.connect(self.show_window1)btn2.clicked.connect(self.show_window2)# 绑定控件outer_container.addWidget(display)outer_container.addWidget(btn1)outer_container.addWidget(btn2)# 让当前的窗口使用布局器self.setLayout(outer_container)def show_window1(self):self.windows_stack.setCurrentIndex(0)def show_window2(self):self.windows_stack.setCurrentIndex(1)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()这是点击窗口二按钮的显示情况 这是点击窗口一按钮的显示情况(也是默认的情况) 其实本例子在使用窗口切换的按钮中已经用到和后面要讲解的信号和槽相关的内容了这里暂时先按下不表作为一个引子抛砖引玉大家可以先对信号和槽的使用有一个大概的印象。这里有一个具体的实现细节是display QWidget()栈布局本身是作为一种布局存在而不是作为一种UI控件存在所以要使得栈布局能够正常发挥自己的作用需要给他找一个控件介质这里用的是QWidget()窗口控件。栈布局也叫抽屉布局“抽屉”的这个喻体很象形地体现出这种布局的特点它就像是一个多层的抽屉不同层的抽屉可以放、不同的“窗口”但是当们从上往下看的时候同一个时候只能看到一个拉开的抽屉也即只能看到一个窗口。使用这种“抽屉”布局能够实现同一空间区域的多样化的应用。一个形象的例子是我们电脑上的微信的窗口左侧是不同的好友而右侧则是我们和好友的聊天的页面我们点击不同的好友的时候右侧的区域会转变成不同的好友相关的聊天区但是空间依然还是那一块空间。在栈布局中不同的显示窗口的显示主要用setCurrentIndex(0)来实现通过指定想要展示的窗体的下标来实现展示的窗体的切换。下标从0开始计数。 3.4 PyQt5常用的三种窗口 3.4.1 PyQt5之QWidget import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyQWidget(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(700, 400)# 设置窗口标题self.setWindowTitle(PyQt5程序之QWidget)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 创建一个标签label QLabel(我是PyQt5的三种重要窗口之一,\n是QWidget窗口的示例~\n我的特点是自定义的程度高。, self)# 调整label的字体大小为30颜色为greenlabel.setFont(QFont(微软雅黑, 25, QFont.Bold))label.setStyleSheet(color: green)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyQWidgetw MyQWidget()w.show()app.exec_()QWidget窗口的使用方法之一是直接让我们所创建的自定义的窗口类继承它这样我们所自定义的窗口就是QWidget的子类就能够获得这种窗口的特点。在PyQt中QWidget是所有用户界面对象的基类。 3.4.2 PyQt5之QMainWindow import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyQMainWindow(QMainWindow):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(700, 400)# 设置窗口标题self.setWindowTitle(PyQt5程序之QMainWindow)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 创建菜单和动作file_menu QMenu(文件, self)new_action QAction(新建, self)open_action QAction(打开, self)save_action QAction(保存, self)exit_action QAction(退出, self)file_menu.addAction(new_action)file_menu.addAction(open_action)file_menu.addAction(save_action)file_menu.addSeparator() # 创建了一个分割的横线file_menu.addAction(exit_action)# 创建菜单栏并添加菜单menu_bar QMenuBar(self)menu_bar.addMenu(file_menu)self.setMenuBar(menu_bar)# 创建工具栏tool_bar self.addToolBar(工具)edit_action QAction(编辑, self)tool_bar.addAction(edit_action)# 设置中心部件central_MainWidget QWidget(self) # 使得中心区域可以容纳多个以上的组件。v_layout QVBoxLayout()# 创建一个文本编辑框text_edit QTextEdit(self)# 创建一个标签label QLabel(我是PyQt5的三种重要窗口之一,\n是QMainWindow窗口的示例~\n我的特点是自带菜单栏工具栏状态栏和中心内容区。, self)# 调整label的字体大小为30颜色为greenlabel.setFont(QFont(微软雅黑, 20, QFont.Bold))label.setStyleSheet(color: green)# 创建一个按钮点击时更新状态栏信息self.button QPushButton(点击更新状态栏, self)# 将控件绑定到布局v_layout.addWidget(text_edit)v_layout.addWidget(label)v_layout.addWidget(self.button)# 将布局绑定到主控件central_MainWidget.setLayout(v_layout)# 将主控件绑定到QMainWindow的中心内容区self.setCentralWidget(central_MainWidget)# 创建状态栏self.status_bar QStatusBar(self)self.status_bar.showMessage(欢迎使用应用程序)# 设置状态栏的永久显示项permanent_label QLabel(永久信息当前模式)self.status_bar.addPermanentWidget(permanent_label)self.setStatusBar(self.status_bar)# 连接动作的信号和槽# 连接上了事件有事件相关的控件都加了self变成了当前类的属性类变量# 这样才可以在当前类的其它方法中直接使用。exit_action.triggered.connect(self.close)self.button.clicked.connect(self.update_statusbar)* 这是中心内容区的按钮点击了之后用来更新状态栏的信息的方法。def update_statusbar(self):# 更新状态栏的临时信息self.status_bar.showMessage(新的风暴已经出现, 5000) # 5秒后消失if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QMainWindow子类——MyQMainWindoww MyQMainWindow()w.show()app.exec_()QMainWindow是一个提供主应用程序窗口的类通常包含一个菜单栏、工具栏、状态栏和一个中心部件通常是一个 QWidget 或其子类。QMainWindow是用于构建复杂应用程序的主要窗口类因为它提供了构建多组件、多面板界面的结构。 这是展开了顶部的菜单栏的QMainWindow 一般使用 menu_bar QMenuBar(self)来创建一个顶部菜单栏并绑定到当前的QMainWindow。 菜单栏中可以容纳多个菜单一般使用file_menu QMenu(文件, self)来创建一个菜单。 菜单中可以有多个菜单项在PyQt中我们称为QAction比如我们可以用new_action QAction(新建, self)来创建一个名为“新建”的QActionQAction是用来表示窗口上的动作或事件的。它包含了多种信息如图标、菜单文字、快捷键、状态栏文字和浮动帮助等。它可以和信号一样可以通过连接槽函数来实现特定的功能。 对于创建好的QAction我们需要file_menu.addAction(new_action)将其添加到菜单中。 菜单中除了可以添加事件之外还可以添加file_menu.addSeparator()以创建一个分割的横线。 当然我们所创建的菜单也需要添加到菜单栏中menu_bar.addMenu(file_menu) 并将我们创建的菜单栏绑定到当前的QMainWindowself.setMenuBar(menu_bar)。 当前选中的这一条就是工具栏 QAction的一个关键特性是其能够根据添加的位置改变自己的显示方式。例如如果将其添加到菜单中它会显示为一个菜单项 而如果添加到工具栏则会显示为一个按钮。 这种灵活性使得QAction成为在Qt中创建交互性窗口界面的重要工具。 QAction可以直接添加到工具栏上。 更新了状态栏信息的QMainWindow 使用self.status_bar QStatusBar(self)创建一个状态栏。 使用self.status_bar.showMessage(欢迎使用应用程序)在左下脚短暂显示状态信息。 也可以自己创建一个标签permanent_label QLabel(永久信息当前模式)然后把这个标签设置为永久显示的信息 self.status_bar.addPermanentWidget(permanent_label)。 最后记得把状态栏绑定到当前的主窗口self.setStatusBar(self.status_bar)。 当前选中的这一部分就是中心部件在这个中心部件中我们放置了一个QTextEdit、一个QLabel和一个QPushBotton用垂直布局将这三个控件整合起来。 值得额外注意的是对于QMainWindow而言它的中心部件其实可以看成是一个独立的窗口就像是我们前面学习的QWidget事实上它也确实是这样做的用一个QWidget的实例来作为容纳的介质所有其它的控件或者布局都放在这个QWidget中最后再self.setCentralWidget(central_MainWidget)将主控件绑定到QMainWindow的中心内容区即可。 3.4.3 PyQt5之QDialog import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class CustomDialog(QDialog):def __init__(self):super().__init__()# 设置大小self.resize(200, 200)self.setWindowTitle(自定义对话框)# 创建布局layout QVBoxLayout()# 创建标签self.label QLabel(请输入一些文本:, self)layout.addWidget(self.label)# 创建按钮self.ok_button QPushButton(确定, self)self.ok_button.clicked.connect(self.accept) # 点击按钮时接受对话框layout.addWidget(self.ok_button)# 设置对话框的布局self.setLayout(layout)def get_text(self):# 此处仅为示例实际上你可能需要从某个输入框获取文本return 示例文本 # 假设这是用户输入的文本class MyQMainWindow(QMainWindow):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(400, 400)# 设置窗口标题self.setWindowTitle(PyQt5程序之QDialog)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 添加一个按钮用于打开对话框self.open_dialog_button QPushButton(打开对话框, self)self.open_dialog_button.clicked.connect(self.show_dialog)self.setCentralWidget(self.open_dialog_button)def show_dialog(self):# 创建并显示自定义对话框dialog CustomDialog()if dialog.exec_(): # 执行对话框如果用户点击了确定按钮则返回Truetext dialog.get_text() # 获取用户输入的文本print(f用户输入的文本是: {text})if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QMainWindow子类——MyQMainWindoww MyQMainWindow()w.show()app.exec_()这是主界面 点击打开对话框后弹出正式的QDialog QDialog在 PyQt中是一个通用的对话框类用于创建模态或非模态对话框窗口。模态对话框会阻止用户与其他窗口交互直到对话框被关闭非模态对话框则允许用户同时与多个窗口交互。在我们这里的例子中我们创建的是一个模态对话框。 4. PyQt5的信号和槽 4.1 信号与槽之接收信号 import sysfrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(500, 300)# 设置窗口标题self.setWindowTitle(PyQt5程序之信号和槽1——接收信号)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 创建了一个按钮btn QPushButton(点我点我, self)# 设置窗口的宽度和高度btn.setGeometry(200, 200, 100, 30)# 为按钮的单击信号绑定对应的槽函数btn.clicked.connect(self.on_btn_clicked)def on_btn_clicked(self, arg):print(点我点我, arg)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()这是一个用来演示信号与槽的最基本的交互效果的一个示例在示例中我们通过多次点击窗体中的“点我点我”的按钮可以看到在控制台输出了“点我点我”的字样。在上述的代码中主要体现信号与槽的相关知识的代码是btn.clicked.connect(self.on_btn_clicked)这是将一个按钮控件btn的单击信号clicked与我们定义的类函数本质上是槽函数是我们写的对于btn按钮的单击事件的响应函数连接起来。一般来说响应函数槽函数我们都会写成是窗口类的类方法。至于为什么在“点我点我”字段后面害有一个False的原因是对于QPushButton的clicked信号它并不传递任何数据所以通常不需要为槽函数定义参数。但是我们其实定义了一个参数arg所以PyQt会自动传入一个默认值对于没有数据的信号通常是 False。 4.2 信号与槽之自定义信号 import sys import timefrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):# 自定义一个信号自定义的信号只可以放在类变量这里# 后面的str表示该信号将会传递一个str类型的数据变量my_signal pyqtSignal(str)def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(500, 300)# 设置窗口标题self.setWindowTitle(PyQt5程序之信号和槽2——自定义信号)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 创建了一个按钮btn QPushButton(测试自定义信号, self)# 设置窗口的宽度和高度btn.setGeometry(200, 200, 100, 30)# 为按钮的单击信号绑定对应的槽函数btn.clicked.connect(self.on_btn_clicked)# 为自定义的信号绑定他对应的槽函数self.my_signal.connect(self.find_error)def on_btn_clicked(self):for index, ip in enumerate([192.168.21.%d % x for x in range(1, 255)]):print(f正在检查{ip}..., end)if index % 5 0:self.my_signal.emit(【发现错误】) # 相当于啊调用了自定义信号my_signal的槽函数else:self.my_signal.emit()# 延时0.01stime.sleep(0.01)def find_error(self, msg):print(msg)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_() 在上一个例子中我们所使用的信号是按钮控件自带的clicked单击信号但是当我们需要完成更加复杂的用户交互的时候有些时候我们所需要的信号并不一定有现成的这时候就需要我们进行信号的自定义。我们可以使用形如my_signal pyqtSignal(str)来自定义一个信号其中后面的str表示该信号将会传递一个str类型的数据变量。当我们需要传入的参数很多的时候一般我们也是只写一个str而具体的字符串用JSON格式的字符串来封装。和预定义好的信号不同的是对于我们自定义的信号我们得使用self.my_signal.emit(【发现错误】)在代码中主动进行信号的发射来调用了自定义信号my_signal的槽函数。当然相同的是自定义的信号和预定义的信号一样都需要我们为信号连接上相对应的响应函数self.my_signal.connect(self.find_error)。 4.3 信号与槽之实例练习 import sys import timefrom PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import *class MyWindow(QWidget):# 自定义一个信号自定义的信号只可以放在类变量这里# 后面的str表示该信号将会传递一个str类型的数据变量my_signal pyqtSignal(str)# 用于更新显示框处的信息的文本变量info def __init__(self):# 切记一定要调用父类的__init__方法因为它里面有很多对UI控件的初始化操作super().__init__()# 把对当前的窗口控件的具体的UI布局写到有个专门的方法中以免初始化的方法内容太臃肿self.init_ui()def init_ui(self):# 设置大小self.resize(500, 350)# 设置窗口标题self.setWindowTitle(PyQt5程序之信号和槽3——练习)# 设置窗口图标self.setWindowIcon(QIcon(imgs/clock.png))# 创建了一个多行文本框self.text QTextEdit(self)# 设置 QTextEdit 为只读self.text.setReadOnly(True)# 设置字体大小为20font QFont()font.setPointSize(10)self.text.setFont(font)# 设置多行文本框的窗口的宽度和高度self.text.setGeometry(50, 20, 400, 250)# 创建了一个按钮btn QPushButton(测试自定义信号, self)# 设置窗口的宽度和高度btn.setGeometry(200, 280, 100, 30)# 为按钮的单击信号绑定对应的槽函数btn.clicked.connect(self.on_btn_clicked)# 为自定义的信号绑定他对应的槽函数self.my_signal.connect(self.find_error)def on_btn_clicked(self):# 每次启动前先清空输入框self.info self.text.setText()for index, ip in enumerate([192.168.21.%d % x for x in range(1, 255)]):signal_line 模拟正在检查 ip ...if index % 5 0:self.my_signal.emit(signal_line 【发现错误】) # 相当于啊调用了自定义信号my_signal的槽函数else:self.my_signal.emit(signal_line)# 延时0.01stime.sleep(0.01)def find_error(self, msg):self.info msg \nself.text.setText(self.info)# self.text.append(msg\n)print(msg)if __name__ __main__:# 实例化QApplication类# sys.argv是命令行的参数app QApplication(sys.argv)# 实例化QWidget子类——MyWindoww MyWindow()w.show()app.exec_()在实例练习中和上一个实例不一样的地方是除了仅仅是在控制行中输出内容之外我们还尝试把内容输出到窗口的展示区。相比于在上一个实例中我们在单击事件的响应函数中既传参又进行具体的操作不同在这个实例中我们在单击事件的响应函数中不执行操作只通过信号发射传递参数。而所有的打印和显示到UI上的操作我们都留到自定义信号的响应函数中才去具体执行。但是依然出现的一个问题是UI的文本的更新并没有如我们设想的如控制行的输出区一样一行一行地输出和更新相反他需要等控制行中的所有的文本都打印完毕之后他才会一次性把所有的文本更新到UI展示区而会产生这样的现象的问题是因为这些所有的操作都是在主线程中执行的所以UI的更新会阻塞等待控制行的操作先处理完之后才一起更新。而如果想要实现后台操作和UI更新能够同步进行的话就需要我们学会使用多线程技术。 5. PyQt5的多线程 5.1 PyQt5多线程基础语法实例 动态加载ui文件import sys import timefrom PyQt5.QtCore import QThread from PyQt5.QtWidgets import * from PyQt5 import uicclass MyWidget(QWidget):def __init__(self):super().__init__()self.myThread Noneself.ui Noneself.ui_thread_btn Noneself.QThread_btn Noneself.text_edit Noneself.init_ui()def init_ui(self):self.ui uic.loadUi(ui/QThread-1.ui)self.ui_thread_btn self.ui.pushButtonself.QThread_btn self.ui.pushButton_2self.text_edit self.ui.textEdit# 给登录按钮绑定信号和槽函数self.ui_thread_btn.clicked.connect(self.click1)# 给忘记密码按钮绑定信号和槽函数self.QThread_btn.clicked.connect(self.click2)def click1(self):for i in range(5):time.sleep(1)print(f正在使用UI线程......{i1})def click2(self):# 这里的子线程必须要写成self的属性否则无法实现异步的效果# 因为我们并不希望myThread线程在click2函数运行结束的时候就被销毁我们希望它可以根据它的需求继续留存着。self.myThread MyQThread()self.myThread.start()class MyQThread(QThread):def __init__(self):super().__init__()def run(self):for i in range(5):time.sleep(1)print(f正在使用子线程......{i1})if __name__ __main__:app QApplication(sys.argv)w MyWidget()# 展示窗口# w.show() # 在这种情况下这是一个错误示范w.ui.show() # 这才是正确的操作sys.exit(app.exec_())当我点击的是左边的按钮的时候这时候是没有使用多线程的情况在命令行中输出UI线程的时候我是无法同时对输入行内的数字进行编辑的。 而当我点击的是右边的按钮的时候这时候是使用多线程的情况在命令行中输出子线程的时候我可以同时对输入行内的数字进行编辑。这就达到了我们使用多线程技术来实现对操作和UI更新的分离的效果。在PyQt中使用多线程的方法并不难主要是继承PyQt中本身自带的QThread类重写run方法在run方法中书写具体的业务逻辑即可。在使用的时候只需要在对应的响应的槽函数中实例化一个线程实例然后再启动线程的start()方法来运行run方法就行。这里使用的UI是使用Qt Designer进行设计的至于具体要如何使用Qt Desiner来进行GUI的设计以及对于已经设计好的UI文件我们要如何集成到Python的GUI项目中在下一部分我们会具体展开讲解。 6. PyQt5的界面设计神器——Qt Designer快速入门 6.1 Qt Designer界面介绍 在进入Qt Designer的时候程序首先会让我们选择窗体这里面一共有5种可以选择的窗体但是其实本质上是三大类窗体就是我们在上面所介绍的QWidget、QMainWindow和QDialog。 在选择窗体的类型之后我们就得到一个带有点阵的可以用于直接设计的GUI界面其中左侧有一系列的可以通过直接拖拽来移动到窗体中的UI控件和布局。 每当我们拖拽控件到窗体上的时候对象查看器中就会多出来一个UI控件的对象。 当我们选中一个UI对象的时候属性编辑器中就会显示出当前的对象的一些基本的属性我们可以通过属性编辑器来直接对属性进行编辑。 我们也可以使用Qt Designer来进行简单的信号和槽的编辑和设置但是这里面并不提供自定义的槽函数的实现所以对于Qt Designer来说他很适合用来进行GUI的设计但是他并不是适合用来为Python GUI程序注入灵魂——即进行信号与槽的编辑。此外Qt Designer也支持对我们已经设计好的GUI进行预览的功能。当我们完成了UI的设计之后我们保存记得得到一份.ui文件。 6.2 将Qt Designer的UI文件集成到Python GUI项目 动态加载ui文件import sys import timefrom PyQt5.QtWidgets import * from PyQt5 import uicclass MyWidget(QWidget):def __init__(self):super().__init__()self.ui Noneself.user_name Noneself.password Noneself.login_btn Noneself.forget_btn Noneself.text_browser Noneself.init_ui()def init_ui(self):self.ui uic.loadUi(ui/login.ui)# self.explain_function() # 这是一个用来对ui文件进行输出测试的测试方法self.user_name self.ui.lineEdit # 这是获取用户名输入框self.password self.ui.lineEdit_2 # 这是获取用户密码输入框self.login_btn self.ui.pushButton # 这是获取登录按钮self.forget_btn self.ui.pushButton_2 # 这是获取忘记密码按钮self.text_browser self.ui.textBrowser # 这是获取文本浏览器# 给登录按钮绑定信号和槽函数self.login_btn.clicked.connect(self.login)# 给忘记密码按钮绑定信号和槽函数self.forget_btn.clicked.connect(self.forget)# 给文本浏览器绑定信号和槽函数self.text_browser.textChanged.connect(self.show_text)def login(self):user_name self.user_name.text()password self.password.text()print(您当前输入的用户名为 user_name)print(您当前输入的密码为 password)print(登录成功)# self.text_browser.setText(登录成功)def forget(self):print(找回密码成功)# self.text_browser.setText(找回密码成功)def show_text(self):# 获取当前时间的字符串self.text_browser.setText(文本信息改变 time.gmtime().__str__())def explain_function(self):# 往下是使用print输出来尝试了解我们所载入的ui对象中到底有些什么东西print(self.ui) # 打印ui文件中的最顶层的对象print(self.ui.__dict__) # 获取ui文件中最顶层的对象中的所有的属性以下是ui文件中最顶层的对象中的所有的属性以键值对的方式给出{label: PyQt5.QtWidgets.QLabel object at 0x0000014D5EE89750,lineEdit: PyQt5.QtWidgets.QLineEdit object at 0x0000014D5EE89870, lineEdit_2: PyQt5.QtWidgets.QLineEdit object at 0x0000014D5EE89900, label_2: PyQt5.QtWidgets.QLabel object at 0x0000014D5EE89990, pushButton: PyQt5.QtWidgets.QPushButton object at 0x0000014D5EE89A20, pushButton_2: PyQt5.QtWidgets.QPushButton object at 0x0000014D5EE89AB0, textBrowser: PyQt5.QtWidgets.QTextBrowser object at 0x0000014D5EE89B40}print(self.ui.label.text()) # ui文件中最顶层的对象中的label对象的text()方法if __name__ __main__:app QApplication(sys.argv)w MyWidget()# 展示窗口# w.show() # 在这种情况下这是一个错误示范w.ui.show() # 这才是正确的操作sys.exit(app.exec_())以我这里设计的这一份简单的登录界面为例不同于以往的需要自己去定义各种各样的UI控件结合了Qt Designer的UI设计我们只需要通过self.ui uic.loadUi(ui/login.ui)载入我们已经设计好的UI界面即可。而UI界面中的控件本质上其实我们是通过管理对象实例来对这些控件对象进行操作的从我们载入的UI对象中我们可以根据我们在UI设计中对他们的命名来获取这些UI对象进而可以像直接用代码编辑UI的时候那样通过对对象的处理来实现各种业务逻辑。 7. PyQt5综合案例 至此关于PyQt5的基本知识已经介绍完毕有了这些基本知识我们就可以着手去尝试我们所需要的Python GUI程序的编写了当然只学会这些还是远远不够的如果想要更近一步的学习可以参考我列出的进一步学习中的学习链接如果对于上面的知识想要进一步的巩固可以尝试去仔细阅读和学习我在参考资料中列出的学习链接。此外在我的Gitee代码仓库中还有其它的未完全给出的学习代码其中还包含一个完整的登录功能的综合案例欢迎大家进一步学习。最后的最后诚挚感谢王铭东老师在B站的无私分享! 参考资料 bilibili-王铭东-PyQt5快速入门Python的PyQt官方文档Qt文档 进一步学习 英文版的PyQt学习资料——非常系统且全面白月黑羽老师的B站教学视频白月黑羽老师的个人学习资料网站PyQt5界面美化 教程 QtDesigner
http://www.pierceye.com/news/949678/

相关文章:

  • 营销型网站建设公司地址外贸网站seo优化
  • 建设网站是什么科目wordpress对接易支付宝
  • wordpress英文意思能做SEO优化的网站建设
  • 海沧建设网站多少一站式服务英文
  • wordpress网站需要多大空间建设营销型网站
  • id97网站怎么做的项目营销策划方案
  • 站群网站怎么做缓存
  • 网站(网店)建设方案范文北京网站搭建服务
  • 建设银行网站怎么设置转账额度百度竞价培训班
  • 八大员继续教育入口做优化网站注意什么
  • 网络空间服务商宁波seo网络推广推荐公众号
  • 网站登录注册做验证码的目地汕头网站建设浩森宇特
  • 做鼻翼整形整形的网站开原网站开发
  • 宿州专业网站建设学做app
  • 宁德商城网站开发设计个人网站在那建设
  • 培训网站建设情况淄博网站排名优化
  • 运营一个网站的成本网络营销第二板斧是什么
  • 企业建站报价手机网站开发开发
  • 足彩网站怎样做推广友情链接官网
  • 十大免费音乐网站网络营销策划推广公司有哪些
  • 免费开源代码网站上海企业建设网站
  • 万家灯火网站建设win7系统做网站服务器
  • 网站直播用php怎么做做家旅游的视频网站好
  • 平台网站建设方案查看自己电脑的网站开发语言
  • 织梦如何做网站地图建设一个网站用什么软件下载
  • 建设银行互联网网站怎么制作小程序软件
  • 做购物网站平台视觉比较好看的网站
  • 网站建设要做什么会计科目网站建设的展望 视频
  • 那种广告式网站怎么做网站为什么具有网络营销价值
  • 包头建站怎么下载网站动态图片