PyQt基础

创建一个窗口界面

  1. # -*- coding: utf-8 -*-
  2. #0.导入所需要的包
  3. import sys #内置库
  4. from PyQt5.Qt import * #主要包含常用的QT类
  5. #1.创建一个应用对象
  6. app = QApplication(sys.argv) #创建应用程序
  7. #当别人通过命令行启动这个程序的时候吗,可以设定一种功能(接收命令传递的参数,来执行不同的业务逻辑)
  8. #sys.argv 默认以列表显示文件名,python 文件名 1 2 3
  9. #['文件名','1','2','3']
  10. print(app.arguments()) #应用程序参数(局部变量)
  11. print(qApp.arguments()) #应用程序参数(全局变量)
  12. #2.控件的操作
  13. #创建控件,设置控件(大小位置样式),事件,信号的处理
  14. #2.1 创建控件
  15. #当我们创建一个控件之后,如果说这个控件没有父控件,则把它当做顶层控件(窗口)
  16. #系统会自动给窗口添加写默认装饰,窗口控件具备一些特性(设置标题,图标等)
  17. window = QWidget() #创建一个控件,此时什么样式都没有
  18. #2.2 设置控件
  19. window.setWindowTitle("社会我奥哥~~~")
  20. window.resize(500,500)
  21. window.move(400,400)
  22. label = QLabel(window) #创建一个文本框,设置父控件为window,此时控件默认在父控件的左上角
  23. label.setText("Hello world")
  24. label.move(250,250)
  25. #2.3 展示控件
  26. #刚创建好的一个控件后,(这个控件没有任何父控件),默认情况下不会被展示,只有手动的调用show()才会显示
  27. window.show()
  28. #3.应用程序的执行,进入到消息循环
  29. #app.exec_()
  30. #让整个程序开学执行,并且进入到消息循环(无限循环)
  31. #检测整个程序所接受到的用户交互信息,此时程序持续等待用户的点击。
  32. sys.exit(app.exec_()) #执行并进入消息循环,保持页面显示出来不会自动退出
  33. #用户执行的命令导致报错,或者用户退出了的代码,告诉sys.exit 程序系统

Pycharm活动模板设置

File——setting——Editor——Live Templates——Python——Add

image.png
Abbreviatior 设置模板名
Description 介绍
Template text 模板内容(放入代码)

$TITLE$ #标题设置在这里,创建完模板光标自动定位在这里 $CODE #设置完TITLE后,光标定位的位置

PyQt5面向对象

当我们创建一个页面,需要添加很多组件,我们可以新建一个py文件,并且设置类,每次使用的时候导入该类,就可以非常方便的使用,并且可以优化代码。

  1. #新建一个DefaultMenu文件,写入如下内容
  2. # -*- coding: utf-8 -*-
  3. from PyQt5.Qt import * #导入所需要的包
  4. class Window(QWidget): #创建类,其中Window继承了QWidget
  5. #设置构造方法,当我调用这个方法时,也会启动该方法
  6. def __init__(self):
  7. super().__init__() #调用了父类的方法,此时QWidget才生效
  8. print("xxx")
  9. self.setWindowTitle("社会我奥哥~~~") #self就是通过Window创建实例对象,所以可以直接调用
  10. self.resize(500, 500)
  11. self.move(400, 400)
  12. self.setup_ui()
  13. def setup_ui(self):
  14. label = QLabel(self)
  15. label.setText("Test")
  16. label.move(250, 250)
  17. #在主文件中输入以下内容
  18. from DefultMenu import Window
  19. #就可以调用其中的内容了

获取所有子类并遍历

__subclasses__获取该类的所有子类
查看子类

  1. def getSubClasses(cls):
  2. for subcls in cls.__subclasses__():
  3. print(subcls)
  4. if len(cls.__subclasses__()) > 0
  5. getSubClasses(subcls)

QObject

对象的名称和属性设置API

创建参数

QObject的API为

API 用法
setObjectName(“唯一名称”) 给QT对象设置的一个名称,一般名称是唯一的,当做对象ID使用
objectName() 获取一个QT对象的名称
setProperty(“属性名称”,值) 给一个QT对象动态的添加一个属性与值
property(“属性名称”) 获取一个对象的属性值
dynamicPropertyNames() 获取一个对象中所有通过setProperty()设置的属性名称
  1. class Window(QWidget):
  2. def __init__(self):
  3. super().__init__()
  4. print("xxx")
  5. self.setWindowTitle("社会我奥哥~~~")
  6. self.resize(500, 500)
  7. self.move(400, 400)
  8. self.setup_ui()
  9. def setup_ui(self):
  10. self.Qobjectdxsx() #调用函数
  11. def Qobjectdxsx(self):
  12. #测试API
  13. obj = QObject() #创建一个QT的Object类
  14. obj.setObjectName("notice") #设置setObjectName变量为notice
  15. print(obj.objectName()) #打印出notice
  16. obj.setProperty("notice_level","error") #创建属性值,前面是名称,后面是值
  17. obj.setProperty("notice_level2","warring")
  18. print(obj.property("notice_level")) #打印出error
  19. print(obj.dynamicPropertyNames()) #打印出使用setProperty方法创建的参数

对象名称和属性设置案例

image.png

  1. #创建文件Object.qss
  2. QLabel#notice {
  3. font-size: 20px; color: red;
  4. }
  5. #如果不设置notice,那么所有的QLabel都会使用该QSS样式
  6. # -*- coding: utf-8 -*-
  7. from PyQt5.Qt import *
  8. class Window(QWidget):
  9. def __init__(self):
  10. super().__init__()
  11. print("xxx")
  12. self.setWindowTitle("社会我奥哥~~~")
  13. self.resize(500, 500)
  14. self.move(400, 400)
  15. self.setup_ui()
  16. def setup_ui(self):
  17. self.Qobjectdxsx()
  18. def Qobjectdxsx(self):
  19. with open("ObjectQT.qss","r") as f:
  20. qApp.setStyleSheet(f.read()) #全局内容都读取Object.qss中的QSS样式。f.read读取所有的字符串
  21. #所有变量都会遵循该文件中的样式
  22. lable = QLabel(self)
  23. lable.setText("芜湖~~~")
  24. #lable.setStyleSheet("font-size: 20px; color: red;") #单独给label变量的文字内容设置QSS样式
  25. label.setObjectName("notice") #将label的Obejctname设置为notice,就能使用QSS文件中的QLabel样式了
  26. lable2 = QLabel(self)
  27. lable2.setText("666666")
  28. lable2.move(100,100)

对象的父子关系

只能有一个父对象

API 作用
setParent(parent) 设置父对象,父对象只能设置一个
parent() 获取父对象
children() 获取所有直接子对象
findChild(参数1, 参数2, 参数3) 获取某一个指定名称和类型的子对象
可以填写Object类型,Qlabel类型元祖,名称notice,查找选项Qt.FindChildrenRecursively(递归查找)
Qt.FindDirectChildrenOnly(只查找直接子对象)
findChildren(参数1, 参数2, 参数3) 可以查询多个

QT内存应用场景

Object继承树

  1. obj1 = QObject()
  2. obj2 = QObject()
  3. obj2.setParent(obj1) #设计obj2为obj1的子类
  4. obj2.destroyed.connect(lambda : print("Obj2被释放了")) #监听ojb2的释放情况
  5. #此时启动,ojb1会被释放,obj2是obj1的子类所以也会跟着被释放。
  6. #因为obj1此时并没有被指向某个位置,所以被python自动释放了。obj2虽然指向了,但obj1无了也跟着无了
  7. #如果给obj1指向一个位置,则不会被清理回收
  8. obj1 = QObject()
  9. self.liaoojb1 = obj1 #设置一个变量,指向ojb1,此时就不会被回收了
  10. obj2 = QObject()
  11. obj2.setParent(obj1) #设计obj2为obj1的子类
  12. obj2.destroyed.connect(lambda : print("Obj2被释放了")) #监听ojb2的释放情况
  13. del self.liaoojb1 #释放变量

父子对象操作

创建两个独立窗口

  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window1 = QWidget()
  5. window1.setWindowTitle("我是端口1")
  6. window1.resize(350,350)
  7. window2 = QWidget()
  8. window2.setWindowTitle("我是端口2")
  9. window2.resize(750,750)
  10. window1.show()
  11. window2.show()
  12. sys.exit(app.exec_())

创建一个窗口,包含另外两个子控件QWidget

  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window1 = QWidget()
  5. window1.setWindowTitle("我是端口1")
  6. window1.resize(650,650)
  7. label1 = QLabel(window1)
  8. label1.setText("我是lable1")
  9. label1.move(100,100)
  10. label2 = QLabel(window1)
  11. label2.setText("我是lable2")
  12. label2.move(200,200)
  13. window1.show()
  14. sys.exit(app.exec_())

创建一个窗口,包含多个子控件

  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window1 = QWidget()
  5. window1.setWindowTitle("我是端口1")
  6. window1.resize(650,650)
  7. label1 = QLabel(window1)
  8. label1.setText("我是lable1")
  9. label1.move(100,100)
  10. label2 = QLabel(window1)
  11. label2.setText("我是lable2")
  12. label2.move(200,200)
  13. window1.show()
  14. for i in window1.findChildren(QLabel):
  15. print(i)
  16. i.setStyleSheet('background: cyan;')
  17. sys.exit(app.exec_())

信号与槽的操作

API 作用
self.obj.objectNameChanged.connect() 当object名称改变时,连接,触发变量。
此时连接监听该方法,如果修改了name,则触发指定函数
self.obj.objectNameChanged.disconnect() 删除前面的connect()监听
self.obj.blockSignals(False/True) 临时开启/关闭监听
self.obj.signalsBlock() 查看信号是否被阻止
self.obj.receivers(self.obj.objectNameChanged) 查看有多少信号接收器
  1. def Qobjectxh(self):
  2. self.liaoobj = QObject()
  3. # def destroye_cao():
  4. # print("对象被释放了")
  5. # self.liaoobj.destroyed.connect(destroye_cao)
  6. # del self.liaoobj
  7. def obj_name_event(name):
  8. print("对象名称发生了改变",name)
  9. self.liaoobj.objectNameChanged.connect(obj_name_event)
  10. self.liaoobj.setObjectName("qwq")
  11. self.liaoobj.blockSignals(True)
  12. print(self.liaoobj.signalsBlocked())
  13. self.liaoobj.setObjectName("awa")
  14. print(self.liaoobj.receivers(self.liaoobj.objectNameChanged))

信号与槽的操作案例

  1. def onChange(title):
  2. print("修改了标题")
  3. window.blockSignals(True) #临时关闭监听
  4. window.setWindowTitle("大帅比-" + title)
  5. window.blockSignals(False) #临时打开监听
  6. window.windowTitleChanged.connect(onChange)
  7. window.setWindowTitle("LiAo")

类型判定

API 作用
isWidgetType() 判断是否是控件类型,是否继承自QWidget类
inherits(父类) 一个对象是否继承(直接或者间接)自某个类
  1. obj = QObject()
  2. label1 = QLabel(window)
  3. label1.setText("123123")
  4. label1.move(100,100)
  5. label2 = QLabel(window)
  6. label2.setText("123123=-=")
  7. label2.move(150,150)
  8. btn1 = QPushButton(window)
  9. btn1.setText("点我")
  10. w = QWidget()
  11. obj1 = [obj,label1,btn1,w,label2]
  12. for i in obj1:
  13. #print(i.isWidgetType()) #判断是否为Widget的子类
  14. print(i.inherits("QLabel")) #判断上级父类是否是QLabel
  15. if i.inherits("QLabel"):
  16. i.setStyleSheet("background: red;")

对象删除

API 作用
obj.deleteLater() 删除一个对象时, 解除它与父对象之间的关系

deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象

这样做的好处是可以在这些延迟删除的时间内完成一些操作,坏处就是内存释放会不及时

事件机制

  1. class App(QApplication):
  2. def notify(self, recevier ,evt):
  3. if recevier.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress:
  4. print(recevier, evt)
  5. return super().notify(recevier, evt)
  6. class Btn(QPushButton):
  7. def event(self, evt):
  8. if evt.type() == QEvent.MouseButtonPress:
  9. print(evt)
  10. return super().event(evt)
  11. def mousePressEvent(self, *args, **kwargs):
  12. print("鼠标被按下")
  13. return super().mousePressEvent(*args, **kwargs)

定时器

创建一个窗口,并设置一个子控件QLabel。

  • 展示倒计时10s
  • 倒计时结束停止计时 ```python from PyQt5.Qt import * import sys

class labelObject(QLabel): #创建一个新的类,继承QLabel def init(self, args, **kwargs): #调用此方法时会启动该函数,args, kwargs设置变量的多样性 super().init(*args, kwargs) #调用父类,才能使用后面的参数 self.setText(“10”) #设置时间文本 self.move(225, 225) self.setStyleSheet(“font-size: 22px;”) self.timeid1 = self.startTimer(1000) #设置计算时间与时间ID

  1. def setSec(self,sec): #自定义函数,设置时间
  2. self.setText(str(sec))
  3. def timerEvent(self, *args, **kwargs): #修改时间变换事件
  4. current_count = int(self.text()) #设置变量值
  5. current_count -= 1
  6. self.setText(str(current_count))
  7. if current_count == 0:
  8. self.killTimer(self.timeid1) #停止时间变换
  9. print("停止")

app = QApplication(sys.argv)

window = QWidget() window.setWindowTitle(“定时器的使用”) window.resize(500, 500) window.move(400, 400)

label1 = labelObject(window)
label1.setSec(200)

window.show()

sys.exit(app.exec_())

  1. <a name="OnE4F"></a>
  2. # QWiget
  3. <a name="WG6mb"></a>
  4. ## 大小与位置
  5. **坐标的计算**<br />左上角为坐标原点,向右为x轴正方向,向下为y轴正方向。`label1.move(100,100)`
  6. <a name="XH7Z4"></a>
  7. ### 获取数值
  8. | **API** | **内容** |
  9. | --- | --- |
  10. | x() | 相对于父控件的x位置。顶层控件相对于桌面x的位置 |
  11. | y() | 相对于父控件的y位置。顶层控件相对于桌面y的位置 |
  12. | pos() | x和y的组合,QPoint(x,y) |
  13. | width() | 控件的宽度,不包含任何窗口框架 |
  14. | height() | 控件的高度,不包含任何窗口框架 |
  15. | size() | width和height的组合 |
  16. | geometry() | 用户区域相对于父控件的位置和尺寸组合 |
  17. | rect() | 0,0,width,heigh的组合 |
  18. | framSize() | 框架大小 |
  19. | framGeometry() | 框架尺寸 |
  20. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/22750215/1649247369299-23020c26-129f-4780-b088-5da8b6f62292.png#clientId=u146c6cd0-4a02-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=433&id=u02a40bc4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=433&originWidth=896&originalType=binary&ratio=1&rotation=0&showTitle=false&size=191209&status=done&style=none&taskId=ue1a71268-1e95-478f-aea2-8e61033ed78&title=&width=896)
  21. <a name="LXbGG"></a>
  22. ### 设置数值
  23. | **API** | **设置的参数** |
  24. | --- | --- |
  25. | move(x,y) | 操作的是x,y。也是pos。包括窗口框架 |
  26. | resize(width,height) | 操作的是宽高 |
  27. | setGeometry(x,y) | 此处参照物为用户区域,放到show()后 |
  28. | adjusSize() | 根据内容自适应大小 |
  29. | setFixedSize() | 设置固定尺寸 |
  30. ```shell
  31. import sys
  32. from PyQt5.Qt import *
  33. app = QApplication(sys.argv)
  34. window = QWidget()
  35. window.move(100,100)
  36. #window.resize(500,500)
  37. #window.adjustSize()
  38. window.setFixedSize(800,800)
  39. label1 = QLabel(window)
  40. label1.setText("里奥")
  41. label1.move(250,400)
  42. def onclick():
  43. print("添加了内容")
  44. text = label1.text() + "里奥!"
  45. label1.setText(text)
  46. label1.adjustSize()
  47. btn = QPushButton(window)
  48. btn.setText("点我添加内容")
  49. btn.move(400,400)
  50. btn.clicked.connect(onclick)
  51. window.show()
  52. sys.exit(app.exec_())

创建九宫格/自适应大小

  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. #设置数量
  5. widget_count = 99
  6. #一行有多少列
  7. column_count = 9
  8. window = QWidget()
  9. window.resize(505,505)
  10. window.setWindowTitle("九宫格")
  11. #计算一个控件的宽度
  12. widget_width = window.width() / column_count
  13. #总共有多少行
  14. row_count = (widget_count - 1) // column_count + 1
  15. widget_height = window.height() / row_count
  16. for i in range(0 , widget_count):
  17. w = QWidget(window)
  18. w.resize(widget_width,widget_height)
  19. widget_x = i % column_count * widget_width
  20. widget_y = i // column_count * widget_height
  21. w.move(widget_x,widget_y)
  22. w.setStyleSheet("background-color: red;border: 1px solid yellow;")
  23. w.show()
  24. window.show()
  25. sys.exit(app.exec_())

尺寸限定

API 设置的参数
minimumWidth() 最小的尺寸宽度
minimumHeight() 最小的尺寸高度
maximumWidth() 最大的尺寸宽度
maximumHeight() 最大的尺寸高度
minimumSize() 最小尺寸
maximumSize 最大尺寸
前面加上set 设置参数
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("最小最大尺寸设置")
  6. window.resize(400,400)
  7. window.setMinimumSize(200,200)
  8. window.setMaximumSize(600,600)
  9. window.show()
  10. sys.exit(app.exec_())

设置内容区域

注意:看清楚标签的起始位置。

API 设置的参数
setContentsMargins(左,上,右,下) 设置内容边距
getContentsMargins() 获取内容边距
contentsRect() 获取内容区域
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("内容位置设置")
  6. window.resize(400,400)
  7. label = QLabel(window)
  8. label.setText("这是一段话")
  9. label.resize(300,300)
  10. label.setStyleSheet("background-color: blue;")
  11. label.setContentsMargins(10,100,100,100)
  12. print(label.getContentsMargins())
  13. print(label.contentsRect())
  14. window.show()
  15. sys.exit(app.exec_())

鼠标操作

形状设置

API 设置的参数 图形
Qt.ArrowCursor 正常的鼠标 image.png
Qt.UpArrowCursor 向上箭头 image.png
Qt.CrossCursor 十字标(坐标) image.png
Qt.IBeamCursor 选择文字 image.png
Qt.WaitCursor 等待 image.png
Qt.BusyCursor 正忙 image.png
Qt.ForbiddenCursor 禁止 image.png
Qt.PointingHandCursor 手指,点击 image.png
Qt.WhatsThisCursor 提示信息 image.png
Qt.SizeVerCursor 向上拉大小 image.png
Qt.SizeHorCursor 左右拉大小 image.png
Qt.SizeBDiagCursor 斜着拉 image.png
Qt.SizeAllCursor 调整位置/大小 image.png
Qt.SplitVCursor 左右拉布局大小 image.png
Qt.SplitHCursor 上下拉布局大小 image.png
Qt.OpenHandCursor 打开的手掌 image.png
Qt.ClosedHandCursor 合着的手掌 image.png
Qt.BlankCursor 鼠标消失
  1. window.setCursor(Qt.ForbiddenCursor) #移动到window控件改变鼠标样式

自定义鼠标

QCursor

  1. pixmap = QPixmap("qe.jpg") #设置鼠标样式
  2. new_pixmap = pixmap.scaled(50, 50) #设置鼠标大小
  3. cursor = QCursor(new_pixmap,50 , 0) #设置鼠标所在图片的位置
  4. label.setCursor(cursor) #设置图片
  5. label.unsetCursor() #删除鼠标样式

鼠标重置/获取

  1. cursor_pos = window.cursor()
  2. cursor_pos.setPos(100,100)

鼠标跟踪

  1. import sys
  2. from PyQt5.Qt import *
  3. class Mywindow(QWidget): #修改类
  4. def mouseMoveEvent(self,me):
  5. print("鼠标移动了",me.globalPos()) #当鼠标移动时,触发命令。如果没有setMouseTracking,则左键时才开启
  6. app = QApplication(sys.argv)
  7. window = Mywindow()
  8. window.setWindowTitle("形状设置")
  9. window.resize(400, 400)
  10. window.setMinimumSize(200, 200)
  11. window.setMaximumSize(600, 600)
  12. window.setMouseTracking(True) #开启鼠标监控
  13. print(window.hasMouseTracking()) #打印是否开启监控
  14. window.show()
  15. sys.exit(app.exec_())

案例

  1. import sys
  2. from PyQt5.Qt import *
  3. class Mywindow(QWidget):
  4. def __init__(self):
  5. super().__init__()
  6. self.setWindowTitle("形状设置")
  7. self.resize(400, 400)
  8. self.setMinimumSize(200, 200)
  9. self.setMaximumSize(600, 600)
  10. self.setMouseTracking(True)
  11. pixmap = QPixmap("qe.jpg").scaled(50, 50)
  12. cursor = QCursor(pixmap)
  13. self.setCursor(cursor)
  14. label = QLabel(self)
  15. self.label = label
  16. label.setText("qwq")
  17. label.resize(50, 50)
  18. label.move(150, 150)
  19. label.setStyleSheet("background-color: cyan;")
  20. def mouseMoveEvent(self, me):
  21. print("鼠标移动了", me.pos())
  22. self.label.move(me.pos())
  23. app = QApplication(sys.argv)
  24. window = Mywindow()
  25. window.show()
  26. sys.exit(app.exec_())

QWidget 常见事件

API 作用
显示和关闭事件
showEvent(QShowEvent) 控件显示时调用
closeEvent(QCloseEvent) 控件关闭时调用
移动事件
moveEvent(QMoveEvent) 控件移动时调用
调整大小
resizeEvent(QResizeEvent) 控件调整大小时调用
鼠标事件
enterEvent(QEvent) 鼠标进入时触发
leaveEvent(QEvent) 鼠标离开时触发
mousePressEvent(QMouseEvent) 鼠标按下时触发
mouseReleaseEvent(QMouseEvent) 鼠标释放时触发
mouseDoubleClickEvent(QMouseEvent) 鼠标双击时触发
mouseMoveEvent(QMouseEvent) 鼠标按下后移动时触发
setMouseTracking(True) 追踪设置后,没有按下的移动也能触发
键盘事件
keyPressEvent(QKeyEvent) 键盘按下时调用
keyReleaseEvent(QKeyEvent) 键盘释放时调用
焦点事件
focusInEvent(QFocusEvent) 获取焦点时调用
focusOutEvent(QFocusEvent) 失去焦点时调用
拖拽事件
dragEnterEvent(QDragEnterEvent) 拖拽进入控件时调用
dragLeaveEvent(QDragLeaveEvent) 拖拽离开控件时调用
dragMoveEvent(QDragMoveEvent) 拖拽在控件内移动时调用
dropEvent(QDropEvent) 拖拽放下时调用
绘制事件
paintEvent(QPaintEvent) 显示控件, 更新控件时调用
改变事件
changeEvent(QEvent) 窗体改变, 字体改变时调用
右键菜单
contextMenuEvent(QContextMenuEvent) 访问右键菜单时调用
输入法
inputMethodEvent(QInputMethodEvent) 输入法调用
  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def __init__(self):
  5. super().__init__()
  6. self.setWindowTitle("事件的学习")
  7. self.resize(500, 500)
  8. def set_up_ui(self):
  9. pass
  10. def showEvent(self, QShowEvent):
  11. print("窗口被展示了出来")
  12. def closeEvent(self, QCloseEvent):
  13. print("窗口被关闭了")
  14. def moveEvent(self, QMoveEvent):
  15. print("窗口被移动了")
  16. def resizeEvent(self, QResizEvent):
  17. print("窗口被改变大小了")
  18. def enterEvent(self, QEnterEvent):
  19. print("当鼠标进入")
  20. self.setStyleSheet("background-color: yellow")
  21. def leaveEvent(self, QLeaveEvent):
  22. print("鼠标离开了")
  23. self.setStyleSheet("background-color: blue")
  24. def mousePressEvent(self, QMousePressEvent):
  25. print("鼠标长按")
  26. def mouseReleaseEvent(self, QMouseReleaseEvent):
  27. print("鼠标释放")
  28. def mouseDoubleClickEvent(self, QMouseReleaseEvent):
  29. print("双击鼠标")
  30. def mouseMoveEvent(self, QMouseMoveEvent):
  31. self.setMouseTracking(False)
  32. print("鼠标按下移动了")
  33. def keyPressEvent(self, QKeyPressEvent):
  34. print("键盘按下")
  35. def keyReleaseEvent(self, QKeyReleaseEvent):
  36. print("键盘释放")
  37. def focusInEvent(self, QFocusInEvent):
  38. print("获取焦点")
  39. if __name__ == '__main__':
  40. app = QApplication(sys.argv)
  41. window = Window()
  42. window.show()
  43. sys.exit(app.exec_())

事件转发机制

  1. import sys
  2. from PyQt5.Qt import *
  3. class Winodow(QWidget):
  4. def mousePressEvent(self, QMousePressEvent):
  5. print("鼠标按下")
  6. class MinWindow(QWidget):
  7. def mousePressEvent(self, QMousePressEvent):
  8. print("中间控件被按下")
  9. class Label(QLabel):
  10. def mousePressEvent(self, evt):
  11. print("标签被按下")
  12. evt.accept() #告诉系统,被我处理你不用再转发给父对象
  13. evt.isAccepted()#查看是否为被接收的状态
  14. evt.ignore() #告诉系统,事件并没有被处理继续网上传
  15. app = QApplication(sys.argv)
  16. print(app.arguments())
  17. window = Winodow()
  18. window.setWindowTitle("社会我奥哥~~~")
  19. window.resize(500, 500)
  20. window.move(400, 400)
  21. minWindow = MinWindow(window)
  22. minWindow.resize(300, 300)
  23. minWindow.setAttribute(Qt.WA_StyledBackground, True)
  24. minWindow.setStyleSheet("background-color: red")
  25. #label1 = Label(minWindow)
  26. label1 = QLabel(minWindow)
  27. label1.setText("标签,点我!!!!")
  28. label1.setStyleSheet("background-color: yellow")
  29. label1.move(100, 100)
  30. window.show()
  31. sys.exit(app.exec_())

监听用户键盘

API 作用
Qt.NoModifier 没有修饰键
Qt.ShiftModifier Shift键被按下
Qt.ControlModifier Ctrl键被按下
Qt.AltModifier Alt键被按下

案例-快捷键

  1. import sys
  2. from PyQt5.Qt import *
  3. class Winodow(QWidget):
  4. def mousePressEvent(self, QMousePressEvent):
  5. print("鼠标按下")
  6. self.grabKeyboard() #当点击时焦点进入到该窗口
  7. class MinWindow(QWidget):
  8. def mousePressEvent(self, QMousePressEvent):
  9. self.grabKeyboard() #当点击时焦点进入到该窗口
  10. print("中间控件被按下")
  11. class Label(QLabel):
  12. def mousePressEvent(self, evt):
  13. self.grabKeyboard() #当点击时焦点进入到该窗口
  14. print("标签被按下")
  15. def enterEvent(self, evt):
  16. print("欢迎光临")
  17. def leaveEvent(self, evt):
  18. print("谢谢惠顾")
  19. def keyPressEvent(self, evt):
  20. print("xx")
  21. if evt.key() == Qt.Key_Tab: #判定是否按下了TAB
  22. print("用户按下了TAB键")
  23. if evt.modifiers() == Qt.ControlModifier and evt.key() == Qt.Key_S: #判定是否按下了Ctrl+S
  24. print("用户按下了Ctrl+S键")
  25. if evt.modifiers() == Qt.ControlModifier | Qt.ShiftModifier and evt.key() == Qt.Key_A:
  26. print("用户按下了Ctrl+Shift+A键") #判定是否按下了Ctrl+Shift+S
  27. app = QApplication(sys.argv)
  28. print(app.arguments())
  29. window = Winodow()
  30. window.setWindowTitle("社会我奥哥~~~")
  31. window.resize(500, 500)
  32. window.move(400, 400)
  33. minWindow = MinWindow(window)
  34. minWindow.resize(300, 300)
  35. minWindow.setAttribute(Qt.WA_StyledBackground, True)
  36. minWindow.setStyleSheet("background-color: red")
  37. label1 = Label(minWindow)
  38. #label1 = QLabel(minWindow)
  39. label1.setText("标签,点我!!!!")
  40. label1.setStyleSheet("background-color: yellow")
  41. label1.move(100, 100)
  42. label1.resize(100,100)
  43. window.show()
  44. sys.exit(app.exec_())

案例-鼠标按下窗口移动

  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def __init__(self):
  5. super().__init__()
  6. self.move_falg = False #设置移动判断为False
  7. self.setWindowTitle("鼠标控制操作")
  8. self.resize(500, 500)
  9. self.move(400, 400)
  10. def mousePressEvent(self, evt):
  11. if evt.button() == Qt.LeftButton:
  12. self.move_falg = True
  13. self.mouse_x = evt.globalX() #获取按下位置的全局变量X 1000
  14. self.mouse_y = evt.globalY() #获取按下位置的全局变量Y 1000
  15. print(self.mouse_x,self.mouse_y) #此时就获取一个基准点,我们没次点击移动就要从基准点上改变X,Y
  16. self.origin_x = self.x() #获取当前窗口在桌面的位置X 600
  17. self.origin_y = self.y() #获取当前窗口在桌面的位置Y 600
  18. print(self.origin_x,self.origin_y)
  19. def mouseMoveEvent(self, evt):
  20. if self.move_falg: #开始判断
  21. #print(evt.globalX(),evt.globalX())
  22. move_x = evt.globalX() - self.mouse_x #移动后的全局变量,减去静止时全局的变量,获取的X 1500-1000=500
  23. move_y = evt.globalY() - self.mouse_y #移动后的全局变量,减去静止时全局的变量,获取的Y 1500-1000=500
  24. #print(move_x,move_y)
  25. dest_x = self.origin_x + move_x #当前位置 + 移动后的差值 500+600
  26. dest_y = self.origin_y + move_y #当前位置 + 移动后的差值 500+600
  27. self.move(dest_x,dest_y)
  28. def mouseReleaseEvent(self, evt):
  29. print("鼠标释放")
  30. self.move_falg = False
  31. app = QApplication(sys.argv)
  32. window = Window()
  33. window.setMouseTracking(True) #设置鼠标跟踪
  34. window.show()
  35. sys.exit(app.exec_())

父子关系扩充

API 用法
child(x,y) 获取在指定坐标的控件
parentWidget() 获取指定控件的父控件
childrenRect() 所有子控件组成的边界矩形

案例-点击标签变成红色

  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def mousePressEvent(self, evt):
  5. #self.setStyleSheet("background-color: red")
  6. local_x = evt.x()
  7. local_y = evt.y()
  8. sub_widget = self.childAt(local_x,local_y)
  9. if sub_widget is not None:
  10. sub_widget.setStyleSheet("background-color: red")
  11. print("被点击了", local_x, local_y)
  12. app = QApplication(sys.argv)
  13. window = Window()
  14. window.setWindowTitle("父子关系")
  15. window.resize(500, 500)
  16. for i in range(1, 11):
  17. label = QLabel(window)
  18. label.setText("标签" + str(i))
  19. label.move(40 * i, 40 * i)
  20. window.show()
  21. sys.exit(app.exec_())

层级关系

调整控件的图层位置,也可以说z轴。

API 说明
lower() 将控件降低到最底层
raise_() 将控件提升到最上层
a.stackUnder(b) 让a放在b下面
  1. import sys
  2. from PyQt5.Qt import *
  3. class Label(QLabel):
  4. def mousePressEvent(self,evt):
  5. print("xxxx")
  6. self.raise_()
  7. app = QApplication(sys.argv)
  8. print(app.arguments())
  9. window = QWidget()
  10. window.setWindowTitle("社会我奥哥~~~")
  11. window.resize(500,500)
  12. window.move(400,400)
  13. label1 = Label(window)
  14. label1.setText("标签1")
  15. label1.resize(200,200)
  16. label1.setStyleSheet("background-color: red")
  17. label2 = Label(window)
  18. label2.setText("标签2")
  19. label2.resize(200,200)
  20. label2.move(100,100)
  21. label2.setStyleSheet("background-color: green")
  22. #label2.lower()
  23. #label1.raise_()
  24. #label2.stackUnder(label1)
  25. window.show()
  26. sys.exit(app.exec_())

窗口特定操作

图标与不透明度

API 作用
setWindowIcon() 设置左上角图标
setWindowTitle() 设置窗口标题
setWindowOpacity(float) 设置不透明度
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("")
  6. window.resize(500,500)
  7. icon = QIcon("qe.jpg")
  8. window.setWindowIcon(icon)
  9. print(window.windowTitle())
  10. window.setWindowOpacity(0.5)
  11. window.show()
  12. sys.exit(app.exec_())

窗口状态-最大化/最小化/全屏/活跃

API 作用
window.setWindowState 设置窗口状态
Qt.WindowMinimized 最小化
Qt.WindowMaximized 最大化
Qt.WindowFullScreen 全屏
Qt.WindowActive 设置窗口活跃
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("QWQ")
  6. window.resize(500,500)
  7. print(window.windowState() == Qt.WindowNoState)
  8. # window.setWindowState(Qt.WindowMinimized) #最小化
  9. # window.setWindowState(Qt.WindowMaximized) #最大化
  10. # window.setWindowState(Qt.WindowFullScreen) #全屏
  11. w2 = QWidget()
  12. w2.setWindowTitle("AWA")
  13. w2.resize(200,200)
  14. window.show()
  15. w2.show()
  16. window.setWindowState(Qt.WindowActive) #设置活跃,直接和用户交互
  17. sys.exit(app.exec_())

最大化/最小化

API 作用
window.showNormal() 直接设置正常大小
window.showMinimized() 直接设置最小化
window.showMaximized() 直接设置最大化
window.showFullScreen() 直接设置全屏


  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def mousePressEvent(self,MousePressEvent):
  5. if self.isMaximized():
  6. self.showNormal()
  7. else:
  8. self.showMaximized()
  9. app = QApplication(sys.argv)
  10. window = Window()
  11. window.setWindowTitle("QWQ")
  12. window.resize(500,500)
  13. window.show()
  14. sys.exit(app.exec_())

窗口标志-案例

无边框无标题栏/窗口半透明/自定义最小化/支持拖拽用户区移动

  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def __init__(self, *args, **kwargs): #被调用时启动
  5. super().__init__(*args, **kwargs) #调用自己的全部参数
  6. self.move_flag = False #设置是否可以移动
  7. self.setWindowFlags(Qt.FramelessWindowHint) # 设置无边框
  8. self.setWindowOpacity(0.9) # 设置不透明度
  9. self.setWindowTitle("QWQ")
  10. self.resize(500, 500)
  11. self.setup_ui()
  12. def setup_ui(self):
  13. #按钮的公共数据,为了方便管理
  14. self.top_margin = 10 #距离顶部的距离
  15. self.btn_w = 80 #长
  16. self.btn_h = 40 #宽
  17. # 添加三个子控件按钮
  18. close_btn = QPushButton(self)
  19. self.close_btn = close_btn #临时变量赋值给窗口变量,需要给其他函数用,所以要用到self存储
  20. close_btn.setText("关闭")
  21. close_btn.resize(self.btn_w, self.btn_h) #设置大小
  22. max_btn = QPushButton(self)
  23. self.max_btn = max_btn #临时变量赋值给窗口变量,需要给其他函数用,所以要用到self存储
  24. max_btn.setText("最大化")
  25. max_btn.resize(self.btn_w, self.btn_h) #设置大小
  26. min_btn = QPushButton(self)
  27. self.min_btn = min_btn #临时变量赋值给窗口变量,需要给其他函数用,所以要用到self存储
  28. min_btn.setText("最小化")
  29. min_btn.resize(self.btn_w, self.btn_h) #设置大小
  30. def Max(): #设置max函数
  31. if self.isMaximized(): #如果为最大化
  32. self.showNormal() #变成为正常大小
  33. max_btn.setText("最大化") #标题设置为最大化
  34. else:
  35. self.showMaximized() #如果不是最大化,变成最大化
  36. max_btn.setText("缩小") #标题设置为缩小
  37. # 设置信号
  38. close_btn.pressed.connect(self.close) #绑定按下信号,连接关闭函数
  39. min_btn.pressed.connect(self.showMinimized) #绑定按下信号,连接最小化函数
  40. max_btn.pressed.connect(Max) #绑定按下信号,连接max函数
  41. def resizeEvent(self, QResizeEvent): #当改变了大小时
  42. close_btn_x = self.width() - self.btn_w #关闭按钮X位置 = 总长度 - 一个按钮长度
  43. close_btn_y = self.top_margin #关闭按钮Y位置 = 总长度 - 固定的距离
  44. self.close_btn.move(close_btn_x, close_btn_y)
  45. max_btn_x = close_btn_x - self.btn_w #最大化按钮X位置 = 关闭按钮X位置 - 一个按钮长度
  46. max_btn_y = self.top_margin #最大化按钮Y位置 = 关闭按钮X位置 - 一个按钮长度
  47. self.max_btn.move(max_btn_x, max_btn_y)
  48. min_btn_x = max_btn_x - self.btn_w #最小化按钮X位置 = 最大化按钮X位置 - 一个按钮长度
  49. min_btn_y = self.top_margin #最小化按钮Y位置 = 最大化按钮Y位置 - 一个按钮长度
  50. self.min_btn.move(min_btn_x, min_btn_y)
  51. def mousePressEvent(self, evt):
  52. if evt.button() == Qt.LeftButton:
  53. self.move_flag = True
  54. self.mouse_x = evt.globalX()
  55. self.mouse_y = evt.globalY()
  56. print(self.mouse_x, self.mouse_y)
  57. self.origin_x = self.x()
  58. self.origin_y = self.y()
  59. def mouseMoveEvent(self, evt):
  60. if self.move_flag:
  61. print(evt.globalX(),evt.globalX())
  62. move_x = evt.globalX() - self.mouse_x
  63. move_y = evt.globalY() - self.mouse_y
  64. dest_x = self.origin_x + move_x
  65. dest_y = self.origin_y + move_y
  66. self.move(dest_x,dest_y)
  67. def mouseReleaseEvent(self, evt):
  68. self.move_flag = False
  69. app = QApplication(sys.argv)
  70. window = Window()
  71. window.show()
  72. sys.exit(app.exec_())

控件交互

控件是否可用

btn.setEnabled(False) 设置控件是否可用
btn.isEnabled()查看控件是否可用

  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("qwq")
  6. window.resize(500,500)
  7. btn = QPushButton(window)
  8. btn.setText("按下")
  9. btn.pressed.connect(lambda : print("按钮被点击了"))
  10. btn.setEnabled(False) #设置是否可用 不可用
  11. print(btn.isEnabled()) #打印是否可用
  12. #此时按钮就是灰色
  13. window.show()
  14. sys.exit(app.exec_())

可见隐形

API 作用
setVisible(bool) 设置控件是否可见
setHidden(bool) 设置控件是否可见
window.show() 展示控件
window.hide() 隐藏控件
  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def paintEvent(self,evt):
  5. print("窗口被绘制了")
  6. return super().paintEvent(evt)
  7. class Btn(QPushButton):
  8. def paintEvent(self,evt):
  9. print("按钮被绘制了")
  10. return super().paintEvent(evt)
  11. app = QApplication(sys.argv)
  12. window = Window()
  13. window.setWindowTitle("qwq")
  14. window.resize(500,500)
  15. btn = Btn(window)
  16. btn.setText("按下")
  17. btn.pressed.connect(lambda : btn.setVisible(False))
  18. window.setVisible(True)
  19. sys.exit(app.exec_())

判断隐形

API 作用
btn.isHidden() 判定控件是否基于父控件隐藏
btn.isVisible() 获取控件最终状态是否可见
btn.isVisibleTo(window) 如果能随着widget控件的显示和隐藏, 而同步变化, 则返回True
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("qwq")
  6. window.resize(500,500)
  7. btn = QPushButton(window)
  8. btn.setText("按下")
  9. window.setVisible(True)
  10. print(btn.isHidden())
  11. print(btn.isVisible())
  12. print(btn.isVisibleTo(window))
  13. sys.exit(app.exec_())

被编辑状态

记事本,创建新文本框等操作。

API 作用
window.setWindowModified(True) 设置被编辑状态
window.isWindowModified() 判断被编辑状态
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QWidget()
  5. window.setWindowTitle("qwq[*]") #设置一个 * 符号 但默认不显示
  6. window.resize(500,500)
  7. window.setWindowModified(True) #设置为被编辑状态
  8. print(window.isWindowModified()) #打印是否为编辑状态
  9. window.setVisible(True)
  10. sys.exit(app.exec_())

删除控件

删除控件和关闭控件是不一样的

API 作用
window.close() 关闭隐藏控件
window.deleteLater() 删除控件
window.setAttribute(Qt.WA_DeleteOnClose, True) 被关闭就是被删除

案例-简易的登录判断

  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def __init__(self):
  5. super().__init__()
  6. self.setWindowTitle("交互状态案例")
  7. self.resize(500,500)
  8. self.setup_ui()
  9. def setup_ui(self):
  10. #添加三个子控件
  11. #消息提示登录是否成功
  12. label = QLabel(self)
  13. label.move(100,50)
  14. label.setVisible(False) #因为是提示,所以先隐藏
  15. Edis1 = QLineEdit(self) #设置文本框
  16. Edis1.setText("文本框")
  17. Edis1.move(100,100)
  18. btn = QPushButton(self)
  19. btn.setText("登录")
  20. btn.move(100,150)
  21. btn.setEnabled(False) #先设置为不可用
  22. def test_cao(text): #设置函数,会将文本内容也添加进来
  23. print("文本内容发生了改变",text)
  24. btn.setEnabled(len(text) > 0) #如果文本内容不为空,则开启
  25. Edis1.textChanged.connect(test_cao) #如果编辑框内容更改了,执行函数
  26. def check():
  27. content = Edis1.text()
  28. if content == "LiAo118235":
  29. label.setText("登录成功")
  30. else:
  31. label.setText("登录失败")
  32. label.show()
  33. label.adjustSize()
  34. btn.pressed.connect(check)
  35. app = QApplication(sys.argv)
  36. window = Window()
  37. window.show()
  38. sys.exit(app.exec_())

消息提示

API 作用
window = QMainWindow() 创建工具组合窗口
window.statusBar() 显示下面状态栏
window.setWindowFlags(Qt.WindowContextHelpButtonHint) 设置添加窗口上下文帮助按钮
window.setStatusTip(“这是窗口”) 当鼠标停留到窗口控件身上之后,在状态栏提示的一段文本
label.setToolTip(“这是提示标签”) 鼠标放上去停一会显示的文本
label.setToolTipDuration(4000) 设置显示时长
  1. import sys
  2. from PyQt5.Qt import *
  3. app = QApplication(sys.argv)
  4. window = QMainWindow() #创建组合控件
  5. window.setWindowTitle("信息提示")
  6. window.resize(500,500)
  7. #懒加载
  8. #用到的时候才会加载
  9. window.statusBar()
  10. window.setWindowFlags(Qt.WindowContextHelpButtonHint) #设置添加窗口上下文帮助按钮
  11. #当鼠标停留到窗口控件身上之后,在状态栏提示的一段文本
  12. window.setStatusTip("这是窗口")
  13. label = QLabel(window)
  14. label.setText("我是控件")
  15. label.setStatusTip("芜湖~")
  16. #鼠标放上去停一会显示
  17. label.setToolTip("这是提示标签")
  18. #设置显示时长
  19. label.setToolTipDuration(4000) #设置4秒
  20. label.setWhatsThis("这是标签")
  21. window.show()
  22. sys.exit(app.exec_())

焦点控制

单控件角度

API 作用
setFocus() 指定控件获取焦点
setFocusPolicy(Policy) 设置焦点获取策略
Qt.TabFocus 只能通过Tab键获得焦点
Qt.ClickFocus 只能通过被单击获得焦点
Qt.StrongFocus 可通过上面两种方式获得焦点
Qt.NoFocus 不能通过上两种方式获得焦点(默认值),setFocus仍可使其获得焦点
clearFocus() 取消焦点

父控件角度

点击按钮更换聚焦-下一个筐

API 作用
focusWidget() 获取子控件中当前聚焦的控件
focusNextChild() 聚焦下一个子控件
focusPreviousChild() 聚焦上一个子控件
focusNextPrevChild(bool) True: 下一个 False: 上一个
setTabOrder(pre_widget, next_widget) 设置子控件获取焦点的先后顺序
  1. import sys
  2. from PyQt5.Qt import *
  3. class Window(QWidget):
  4. def mousePressEvent(self,evt):
  5. #self.focusNextChild() #聚焦到下一个子控件,下一行
  6. #self.focusPreviousChild() #聚焦到上一个子控件,下一行
  7. self.focusNextPrevChild(True) #通过True和False判断为上下
  8. app = QApplication(sys.argv)
  9. window = Window()
  10. window.setWindowTitle("社会我奥哥~~~")
  11. window.resize(500,500)
  12. le1 = QLineEdit(window)
  13. le1.move(50,50)
  14. le2 = QLineEdit(window)
  15. le2.move(50,100)
  16. le3 = QLineEdit(window)
  17. le3.move(50,150)
  18. QWidget.setTabOrder(le1,le3) #设置焦点顺序
  19. QWidget.setTabOrder(le3,le2)
  20. window.show()
  21. #le2.setFocus()
  22. #获取当前窗口内部,所有子控件当中获取焦点的控件
  23. #print(window.focusWidget())
  24. sys.exit(app.exec_())