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

Abbreviatior 设置模板名
Description 介绍
Template text 模板内容(放入代码)
$TITLE$ #标题设置在这里,创建完模板光标自动定位在这里 $CODE #设置完TITLE后,光标定位的位置
PyQt5面向对象
当我们创建一个页面,需要添加很多组件,我们可以新建一个py文件,并且设置类,每次使用的时候导入该类,就可以非常方便的使用,并且可以优化代码。
#新建一个DefaultMenu文件,写入如下内容# -*- coding: utf-8 -*-from PyQt5.Qt import * #导入所需要的包class Window(QWidget): #创建类,其中Window继承了QWidget#设置构造方法,当我调用这个方法时,也会启动该方法def __init__(self):super().__init__() #调用了父类的方法,此时QWidget才生效print("xxx")self.setWindowTitle("社会我奥哥~~~") #self就是通过Window创建实例对象,所以可以直接调用self.resize(500, 500)self.move(400, 400)self.setup_ui()def setup_ui(self):label = QLabel(self)label.setText("Test")label.move(250, 250)#在主文件中输入以下内容from DefultMenu import Window#就可以调用其中的内容了
获取所有子类并遍历
__subclasses__获取该类的所有子类
查看子类
def getSubClasses(cls):for subcls in cls.__subclasses__():print(subcls)if len(cls.__subclasses__()) > 0getSubClasses(subcls)
QObject
对象的名称和属性设置API
创建参数
QObject的API为
| API | 用法 |
|---|---|
| setObjectName(“唯一名称”) | 给QT对象设置的一个名称,一般名称是唯一的,当做对象ID使用 |
| objectName() | 获取一个QT对象的名称 |
| setProperty(“属性名称”,值) | 给一个QT对象动态的添加一个属性与值 |
| property(“属性名称”) | 获取一个对象的属性值 |
| dynamicPropertyNames() | 获取一个对象中所有通过setProperty()设置的属性名称 |
class Window(QWidget):def __init__(self):super().__init__()print("xxx")self.setWindowTitle("社会我奥哥~~~")self.resize(500, 500)self.move(400, 400)self.setup_ui()def setup_ui(self):self.Qobjectdxsx() #调用函数def Qobjectdxsx(self):#测试APIobj = QObject() #创建一个QT的Object类obj.setObjectName("notice") #设置setObjectName变量为noticeprint(obj.objectName()) #打印出noticeobj.setProperty("notice_level","error") #创建属性值,前面是名称,后面是值obj.setProperty("notice_level2","warring")print(obj.property("notice_level")) #打印出errorprint(obj.dynamicPropertyNames()) #打印出使用setProperty方法创建的参数
对象名称和属性设置案例

#创建文件Object.qssQLabel#notice {font-size: 20px; color: red;}#如果不设置notice,那么所有的QLabel都会使用该QSS样式# -*- coding: utf-8 -*-from PyQt5.Qt import *class Window(QWidget):def __init__(self):super().__init__()print("xxx")self.setWindowTitle("社会我奥哥~~~")self.resize(500, 500)self.move(400, 400)self.setup_ui()def setup_ui(self):self.Qobjectdxsx()def Qobjectdxsx(self):with open("ObjectQT.qss","r") as f:qApp.setStyleSheet(f.read()) #全局内容都读取Object.qss中的QSS样式。f.read读取所有的字符串#所有变量都会遵循该文件中的样式lable = QLabel(self)lable.setText("芜湖~~~")#lable.setStyleSheet("font-size: 20px; color: red;") #单独给label变量的文字内容设置QSS样式label.setObjectName("notice") #将label的Obejctname设置为notice,就能使用QSS文件中的QLabel样式了lable2 = QLabel(self)lable2.setText("666666")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继承树
obj1 = QObject()obj2 = QObject()obj2.setParent(obj1) #设计obj2为obj1的子类obj2.destroyed.connect(lambda : print("Obj2被释放了")) #监听ojb2的释放情况#此时启动,ojb1会被释放,obj2是obj1的子类所以也会跟着被释放。#因为obj1此时并没有被指向某个位置,所以被python自动释放了。obj2虽然指向了,但obj1无了也跟着无了#如果给obj1指向一个位置,则不会被清理回收obj1 = QObject()self.liaoojb1 = obj1 #设置一个变量,指向ojb1,此时就不会被回收了obj2 = QObject()obj2.setParent(obj1) #设计obj2为obj1的子类obj2.destroyed.connect(lambda : print("Obj2被释放了")) #监听ojb2的释放情况del self.liaoojb1 #释放变量
父子对象操作
创建两个独立窗口
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window1 = QWidget()window1.setWindowTitle("我是端口1")window1.resize(350,350)window2 = QWidget()window2.setWindowTitle("我是端口2")window2.resize(750,750)window1.show()window2.show()sys.exit(app.exec_())
创建一个窗口,包含另外两个子控件QWidget
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window1 = QWidget()window1.setWindowTitle("我是端口1")window1.resize(650,650)label1 = QLabel(window1)label1.setText("我是lable1")label1.move(100,100)label2 = QLabel(window1)label2.setText("我是lable2")label2.move(200,200)window1.show()sys.exit(app.exec_())
创建一个窗口,包含多个子控件
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window1 = QWidget()window1.setWindowTitle("我是端口1")window1.resize(650,650)label1 = QLabel(window1)label1.setText("我是lable1")label1.move(100,100)label2 = QLabel(window1)label2.setText("我是lable2")label2.move(200,200)window1.show()for i in window1.findChildren(QLabel):print(i)i.setStyleSheet('background: cyan;')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) | 查看有多少信号接收器 |
def Qobjectxh(self):self.liaoobj = QObject()# def destroye_cao():# print("对象被释放了")# self.liaoobj.destroyed.connect(destroye_cao)# del self.liaoobjdef obj_name_event(name):print("对象名称发生了改变",name)self.liaoobj.objectNameChanged.connect(obj_name_event)self.liaoobj.setObjectName("qwq")self.liaoobj.blockSignals(True)print(self.liaoobj.signalsBlocked())self.liaoobj.setObjectName("awa")print(self.liaoobj.receivers(self.liaoobj.objectNameChanged))
信号与槽的操作案例
def onChange(title):print("修改了标题")window.blockSignals(True) #临时关闭监听window.setWindowTitle("大帅比-" + title)window.blockSignals(False) #临时打开监听window.windowTitleChanged.connect(onChange)window.setWindowTitle("LiAo")
类型判定
| API | 作用 |
|---|---|
| isWidgetType() | 判断是否是控件类型,是否继承自QWidget类 |
| inherits(父类) | 一个对象是否继承(直接或者间接)自某个类 |
obj = QObject()label1 = QLabel(window)label1.setText("123123")label1.move(100,100)label2 = QLabel(window)label2.setText("123123=-=")label2.move(150,150)btn1 = QPushButton(window)btn1.setText("点我")w = QWidget()obj1 = [obj,label1,btn1,w,label2]for i in obj1:#print(i.isWidgetType()) #判断是否为Widget的子类print(i.inherits("QLabel")) #判断上级父类是否是QLabelif i.inherits("QLabel"):i.setStyleSheet("background: red;")
对象删除
| API | 作用 |
|---|---|
| obj.deleteLater() | 删除一个对象时, 解除它与父对象之间的关系 |
| deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象 | |
| 这样做的好处是可以在这些延迟删除的时间内完成一些操作,坏处就是内存释放会不及时 |
事件机制
class App(QApplication):def notify(self, recevier ,evt):if recevier.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress:print(recevier, evt)return super().notify(recevier, evt)class Btn(QPushButton):def event(self, evt):if evt.type() == QEvent.MouseButtonPress:print(evt)return super().event(evt)def mousePressEvent(self, *args, **kwargs):print("鼠标被按下")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
def setSec(self,sec): #自定义函数,设置时间self.setText(str(sec))def timerEvent(self, *args, **kwargs): #修改时间变换事件current_count = int(self.text()) #设置变量值current_count -= 1self.setText(str(current_count))if current_count == 0:self.killTimer(self.timeid1) #停止时间变换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_())
<a name="OnE4F"></a># QWiget<a name="WG6mb"></a>## 大小与位置**坐标的计算**<br />左上角为坐标原点,向右为x轴正方向,向下为y轴正方向。`label1.move(100,100)`<a name="XH7Z4"></a>### 获取数值| **API** | **内容** || --- | --- || x() | 相对于父控件的x位置。顶层控件相对于桌面x的位置 || y() | 相对于父控件的y位置。顶层控件相对于桌面y的位置 || pos() | x和y的组合,QPoint(x,y) || width() | 控件的宽度,不包含任何窗口框架 || height() | 控件的高度,不包含任何窗口框架 || size() | width和height的组合 || geometry() | 用户区域相对于父控件的位置和尺寸组合 || rect() | 0,0,width,heigh的组合 || framSize() | 框架大小 || framGeometry() | 框架尺寸 |<a name="LXbGG"></a>### 设置数值| **API** | **设置的参数** || --- | --- || move(x,y) | 操作的是x,y。也是pos。包括窗口框架 || resize(width,height) | 操作的是宽高 || setGeometry(x,y) | 此处参照物为用户区域,放到show()后 || adjusSize() | 根据内容自适应大小 || setFixedSize() | 设置固定尺寸 |```shellimport sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.move(100,100)#window.resize(500,500)#window.adjustSize()window.setFixedSize(800,800)label1 = QLabel(window)label1.setText("里奥")label1.move(250,400)def onclick():print("添加了内容")text = label1.text() + "里奥!"label1.setText(text)label1.adjustSize()btn = QPushButton(window)btn.setText("点我添加内容")btn.move(400,400)btn.clicked.connect(onclick)window.show()sys.exit(app.exec_())
创建九宫格/自适应大小
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)#设置数量widget_count = 99#一行有多少列column_count = 9window = QWidget()window.resize(505,505)window.setWindowTitle("九宫格")#计算一个控件的宽度widget_width = window.width() / column_count#总共有多少行row_count = (widget_count - 1) // column_count + 1widget_height = window.height() / row_countfor i in range(0 , widget_count):w = QWidget(window)w.resize(widget_width,widget_height)widget_x = i % column_count * widget_widthwidget_y = i // column_count * widget_heightw.move(widget_x,widget_y)w.setStyleSheet("background-color: red;border: 1px solid yellow;")w.show()window.show()sys.exit(app.exec_())
尺寸限定
| API | 设置的参数 |
|---|---|
| minimumWidth() | 最小的尺寸宽度 |
| minimumHeight() | 最小的尺寸高度 |
| maximumWidth() | 最大的尺寸宽度 |
| maximumHeight() | 最大的尺寸高度 |
| minimumSize() | 最小尺寸 |
| maximumSize | 最大尺寸 |
| 前面加上set | 设置参数 |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("最小最大尺寸设置")window.resize(400,400)window.setMinimumSize(200,200)window.setMaximumSize(600,600)window.show()sys.exit(app.exec_())
设置内容区域
注意:看清楚标签的起始位置。
| API | 设置的参数 |
|---|---|
| setContentsMargins(左,上,右,下) | 设置内容边距 |
| getContentsMargins() | 获取内容边距 |
| contentsRect() | 获取内容区域 |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("内容位置设置")window.resize(400,400)label = QLabel(window)label.setText("这是一段话")label.resize(300,300)label.setStyleSheet("background-color: blue;")label.setContentsMargins(10,100,100,100)print(label.getContentsMargins())print(label.contentsRect())window.show()sys.exit(app.exec_())
鼠标操作
形状设置
| API | 设置的参数 | 图形 |
|---|---|---|
| Qt.ArrowCursor | 正常的鼠标 | ![]() |
| Qt.UpArrowCursor | 向上箭头 | ![]() |
| Qt.CrossCursor | 十字标(坐标) | ![]() |
| Qt.IBeamCursor | 选择文字 | ![]() |
| Qt.WaitCursor | 等待 | ![]() |
| Qt.BusyCursor | 正忙 | ![]() |
| Qt.ForbiddenCursor | 禁止 | ![]() |
| Qt.PointingHandCursor | 手指,点击 | ![]() |
| Qt.WhatsThisCursor | 提示信息 | ![]() |
| Qt.SizeVerCursor | 向上拉大小 | ![]() |
| Qt.SizeHorCursor | 左右拉大小 | ![]() |
| Qt.SizeBDiagCursor | 斜着拉 | ![]() |
| Qt.SizeAllCursor | 调整位置/大小 | ![]() |
| Qt.SplitVCursor | 左右拉布局大小 | ![]() |
| Qt.SplitHCursor | 上下拉布局大小 | ![]() |
| Qt.OpenHandCursor | 打开的手掌 | ![]() |
| Qt.ClosedHandCursor | 合着的手掌 | ![]() |
| Qt.BlankCursor | 鼠标消失 |
window.setCursor(Qt.ForbiddenCursor) #移动到window控件改变鼠标样式
自定义鼠标
QCursor
pixmap = QPixmap("qe.jpg") #设置鼠标样式new_pixmap = pixmap.scaled(50, 50) #设置鼠标大小cursor = QCursor(new_pixmap,50 , 0) #设置鼠标所在图片的位置label.setCursor(cursor) #设置图片label.unsetCursor() #删除鼠标样式
鼠标重置/获取
cursor_pos = window.cursor()cursor_pos.setPos(100,100)
鼠标跟踪
import sysfrom PyQt5.Qt import *class Mywindow(QWidget): #修改类def mouseMoveEvent(self,me):print("鼠标移动了",me.globalPos()) #当鼠标移动时,触发命令。如果没有setMouseTracking,则左键时才开启app = QApplication(sys.argv)window = Mywindow()window.setWindowTitle("形状设置")window.resize(400, 400)window.setMinimumSize(200, 200)window.setMaximumSize(600, 600)window.setMouseTracking(True) #开启鼠标监控print(window.hasMouseTracking()) #打印是否开启监控window.show()sys.exit(app.exec_())
案例
import sysfrom PyQt5.Qt import *class Mywindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle("形状设置")self.resize(400, 400)self.setMinimumSize(200, 200)self.setMaximumSize(600, 600)self.setMouseTracking(True)pixmap = QPixmap("qe.jpg").scaled(50, 50)cursor = QCursor(pixmap)self.setCursor(cursor)label = QLabel(self)self.label = labellabel.setText("qwq")label.resize(50, 50)label.move(150, 150)label.setStyleSheet("background-color: cyan;")def mouseMoveEvent(self, me):print("鼠标移动了", me.pos())self.label.move(me.pos())app = QApplication(sys.argv)window = Mywindow()window.show()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) | 输入法调用 |
import sysfrom PyQt5.Qt import *class Window(QWidget):def __init__(self):super().__init__()self.setWindowTitle("事件的学习")self.resize(500, 500)def set_up_ui(self):passdef showEvent(self, QShowEvent):print("窗口被展示了出来")def closeEvent(self, QCloseEvent):print("窗口被关闭了")def moveEvent(self, QMoveEvent):print("窗口被移动了")def resizeEvent(self, QResizEvent):print("窗口被改变大小了")def enterEvent(self, QEnterEvent):print("当鼠标进入")self.setStyleSheet("background-color: yellow")def leaveEvent(self, QLeaveEvent):print("鼠标离开了")self.setStyleSheet("background-color: blue")def mousePressEvent(self, QMousePressEvent):print("鼠标长按")def mouseReleaseEvent(self, QMouseReleaseEvent):print("鼠标释放")def mouseDoubleClickEvent(self, QMouseReleaseEvent):print("双击鼠标")def mouseMoveEvent(self, QMouseMoveEvent):self.setMouseTracking(False)print("鼠标按下移动了")def keyPressEvent(self, QKeyPressEvent):print("键盘按下")def keyReleaseEvent(self, QKeyReleaseEvent):print("键盘释放")def focusInEvent(self, QFocusInEvent):print("获取焦点")if __name__ == '__main__':app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
事件转发机制
import sysfrom PyQt5.Qt import *class Winodow(QWidget):def mousePressEvent(self, QMousePressEvent):print("鼠标按下")class MinWindow(QWidget):def mousePressEvent(self, QMousePressEvent):print("中间控件被按下")class Label(QLabel):def mousePressEvent(self, evt):print("标签被按下")evt.accept() #告诉系统,被我处理你不用再转发给父对象evt.isAccepted()#查看是否为被接收的状态evt.ignore() #告诉系统,事件并没有被处理继续网上传app = QApplication(sys.argv)print(app.arguments())window = Winodow()window.setWindowTitle("社会我奥哥~~~")window.resize(500, 500)window.move(400, 400)minWindow = MinWindow(window)minWindow.resize(300, 300)minWindow.setAttribute(Qt.WA_StyledBackground, True)minWindow.setStyleSheet("background-color: red")#label1 = Label(minWindow)label1 = QLabel(minWindow)label1.setText("标签,点我!!!!")label1.setStyleSheet("background-color: yellow")label1.move(100, 100)window.show()sys.exit(app.exec_())
监听用户键盘
| API | 作用 |
|---|---|
| Qt.NoModifier | 没有修饰键 |
| Qt.ShiftModifier | Shift键被按下 |
| Qt.ControlModifier | Ctrl键被按下 |
| Qt.AltModifier | Alt键被按下 |
案例-快捷键
import sysfrom PyQt5.Qt import *class Winodow(QWidget):def mousePressEvent(self, QMousePressEvent):print("鼠标按下")self.grabKeyboard() #当点击时焦点进入到该窗口class MinWindow(QWidget):def mousePressEvent(self, QMousePressEvent):self.grabKeyboard() #当点击时焦点进入到该窗口print("中间控件被按下")class Label(QLabel):def mousePressEvent(self, evt):self.grabKeyboard() #当点击时焦点进入到该窗口print("标签被按下")def enterEvent(self, evt):print("欢迎光临")def leaveEvent(self, evt):print("谢谢惠顾")def keyPressEvent(self, evt):print("xx")if evt.key() == Qt.Key_Tab: #判定是否按下了TABprint("用户按下了TAB键")if evt.modifiers() == Qt.ControlModifier and evt.key() == Qt.Key_S: #判定是否按下了Ctrl+Sprint("用户按下了Ctrl+S键")if evt.modifiers() == Qt.ControlModifier | Qt.ShiftModifier and evt.key() == Qt.Key_A:print("用户按下了Ctrl+Shift+A键") #判定是否按下了Ctrl+Shift+Sapp = QApplication(sys.argv)print(app.arguments())window = Winodow()window.setWindowTitle("社会我奥哥~~~")window.resize(500, 500)window.move(400, 400)minWindow = MinWindow(window)minWindow.resize(300, 300)minWindow.setAttribute(Qt.WA_StyledBackground, True)minWindow.setStyleSheet("background-color: red")label1 = Label(minWindow)#label1 = QLabel(minWindow)label1.setText("标签,点我!!!!")label1.setStyleSheet("background-color: yellow")label1.move(100, 100)label1.resize(100,100)window.show()sys.exit(app.exec_())
案例-鼠标按下窗口移动
import sysfrom PyQt5.Qt import *class Window(QWidget):def __init__(self):super().__init__()self.move_falg = False #设置移动判断为Falseself.setWindowTitle("鼠标控制操作")self.resize(500, 500)self.move(400, 400)def mousePressEvent(self, evt):if evt.button() == Qt.LeftButton:self.move_falg = Trueself.mouse_x = evt.globalX() #获取按下位置的全局变量X 1000self.mouse_y = evt.globalY() #获取按下位置的全局变量Y 1000print(self.mouse_x,self.mouse_y) #此时就获取一个基准点,我们没次点击移动就要从基准点上改变X,Yself.origin_x = self.x() #获取当前窗口在桌面的位置X 600self.origin_y = self.y() #获取当前窗口在桌面的位置Y 600print(self.origin_x,self.origin_y)def mouseMoveEvent(self, evt):if self.move_falg: #开始判断#print(evt.globalX(),evt.globalX())move_x = evt.globalX() - self.mouse_x #移动后的全局变量,减去静止时全局的变量,获取的X 1500-1000=500move_y = evt.globalY() - self.mouse_y #移动后的全局变量,减去静止时全局的变量,获取的Y 1500-1000=500#print(move_x,move_y)dest_x = self.origin_x + move_x #当前位置 + 移动后的差值 500+600dest_y = self.origin_y + move_y #当前位置 + 移动后的差值 500+600self.move(dest_x,dest_y)def mouseReleaseEvent(self, evt):print("鼠标释放")self.move_falg = Falseapp = QApplication(sys.argv)window = Window()window.setMouseTracking(True) #设置鼠标跟踪window.show()sys.exit(app.exec_())
父子关系扩充
| API | 用法 |
|---|---|
| child(x,y) | 获取在指定坐标的控件 |
| parentWidget() | 获取指定控件的父控件 |
| childrenRect() | 所有子控件组成的边界矩形 |
案例-点击标签变成红色
import sysfrom PyQt5.Qt import *class Window(QWidget):def mousePressEvent(self, evt):#self.setStyleSheet("background-color: red")local_x = evt.x()local_y = evt.y()sub_widget = self.childAt(local_x,local_y)if sub_widget is not None:sub_widget.setStyleSheet("background-color: red")print("被点击了", local_x, local_y)app = QApplication(sys.argv)window = Window()window.setWindowTitle("父子关系")window.resize(500, 500)for i in range(1, 11):label = QLabel(window)label.setText("标签" + str(i))label.move(40 * i, 40 * i)window.show()sys.exit(app.exec_())
层级关系
调整控件的图层位置,也可以说z轴。
| API | 说明 |
|---|---|
| lower() | 将控件降低到最底层 |
| raise_() | 将控件提升到最上层 |
| a.stackUnder(b) | 让a放在b下面 |
import sysfrom PyQt5.Qt import *class Label(QLabel):def mousePressEvent(self,evt):print("xxxx")self.raise_()app = QApplication(sys.argv)print(app.arguments())window = QWidget()window.setWindowTitle("社会我奥哥~~~")window.resize(500,500)window.move(400,400)label1 = Label(window)label1.setText("标签1")label1.resize(200,200)label1.setStyleSheet("background-color: red")label2 = Label(window)label2.setText("标签2")label2.resize(200,200)label2.move(100,100)label2.setStyleSheet("background-color: green")#label2.lower()#label1.raise_()#label2.stackUnder(label1)window.show()sys.exit(app.exec_())
窗口特定操作
图标与不透明度
| API | 作用 |
|---|---|
| setWindowIcon() | 设置左上角图标 |
| setWindowTitle() | 设置窗口标题 |
| setWindowOpacity(float) | 设置不透明度 |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("")window.resize(500,500)icon = QIcon("qe.jpg")window.setWindowIcon(icon)print(window.windowTitle())window.setWindowOpacity(0.5)window.show()sys.exit(app.exec_())
窗口状态-最大化/最小化/全屏/活跃
| API | 作用 |
|---|---|
| window.setWindowState | 设置窗口状态 |
| Qt.WindowMinimized | 最小化 |
| Qt.WindowMaximized | 最大化 |
| Qt.WindowFullScreen | 全屏 |
| Qt.WindowActive | 设置窗口活跃 |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("QWQ")window.resize(500,500)print(window.windowState() == Qt.WindowNoState)# window.setWindowState(Qt.WindowMinimized) #最小化# window.setWindowState(Qt.WindowMaximized) #最大化# window.setWindowState(Qt.WindowFullScreen) #全屏w2 = QWidget()w2.setWindowTitle("AWA")w2.resize(200,200)window.show()w2.show()window.setWindowState(Qt.WindowActive) #设置活跃,直接和用户交互sys.exit(app.exec_())
最大化/最小化
| API | 作用 |
|---|---|
| window.showNormal() | 直接设置正常大小 |
| window.showMinimized() | 直接设置最小化 |
| window.showMaximized() | 直接设置最大化 |
| window.showFullScreen() | 直接设置全屏 |
import sysfrom PyQt5.Qt import *class Window(QWidget):def mousePressEvent(self,MousePressEvent):if self.isMaximized():self.showNormal()else:self.showMaximized()app = QApplication(sys.argv)window = Window()window.setWindowTitle("QWQ")window.resize(500,500)window.show()sys.exit(app.exec_())
窗口标志-案例
无边框无标题栏/窗口半透明/自定义最小化/支持拖拽用户区移动
import sysfrom PyQt5.Qt import *class Window(QWidget):def __init__(self, *args, **kwargs): #被调用时启动super().__init__(*args, **kwargs) #调用自己的全部参数self.move_flag = False #设置是否可以移动self.setWindowFlags(Qt.FramelessWindowHint) # 设置无边框self.setWindowOpacity(0.9) # 设置不透明度self.setWindowTitle("QWQ")self.resize(500, 500)self.setup_ui()def setup_ui(self):#按钮的公共数据,为了方便管理self.top_margin = 10 #距离顶部的距离self.btn_w = 80 #长self.btn_h = 40 #宽# 添加三个子控件按钮close_btn = QPushButton(self)self.close_btn = close_btn #临时变量赋值给窗口变量,需要给其他函数用,所以要用到self存储close_btn.setText("关闭")close_btn.resize(self.btn_w, self.btn_h) #设置大小max_btn = QPushButton(self)self.max_btn = max_btn #临时变量赋值给窗口变量,需要给其他函数用,所以要用到self存储max_btn.setText("最大化")max_btn.resize(self.btn_w, self.btn_h) #设置大小min_btn = QPushButton(self)self.min_btn = min_btn #临时变量赋值给窗口变量,需要给其他函数用,所以要用到self存储min_btn.setText("最小化")min_btn.resize(self.btn_w, self.btn_h) #设置大小def Max(): #设置max函数if self.isMaximized(): #如果为最大化self.showNormal() #变成为正常大小max_btn.setText("最大化") #标题设置为最大化else:self.showMaximized() #如果不是最大化,变成最大化max_btn.setText("缩小") #标题设置为缩小# 设置信号close_btn.pressed.connect(self.close) #绑定按下信号,连接关闭函数min_btn.pressed.connect(self.showMinimized) #绑定按下信号,连接最小化函数max_btn.pressed.connect(Max) #绑定按下信号,连接max函数def resizeEvent(self, QResizeEvent): #当改变了大小时close_btn_x = self.width() - self.btn_w #关闭按钮X位置 = 总长度 - 一个按钮长度close_btn_y = self.top_margin #关闭按钮Y位置 = 总长度 - 固定的距离self.close_btn.move(close_btn_x, close_btn_y)max_btn_x = close_btn_x - self.btn_w #最大化按钮X位置 = 关闭按钮X位置 - 一个按钮长度max_btn_y = self.top_margin #最大化按钮Y位置 = 关闭按钮X位置 - 一个按钮长度self.max_btn.move(max_btn_x, max_btn_y)min_btn_x = max_btn_x - self.btn_w #最小化按钮X位置 = 最大化按钮X位置 - 一个按钮长度min_btn_y = self.top_margin #最小化按钮Y位置 = 最大化按钮Y位置 - 一个按钮长度self.min_btn.move(min_btn_x, min_btn_y)def mousePressEvent(self, evt):if evt.button() == Qt.LeftButton:self.move_flag = Trueself.mouse_x = evt.globalX()self.mouse_y = evt.globalY()print(self.mouse_x, self.mouse_y)self.origin_x = self.x()self.origin_y = self.y()def mouseMoveEvent(self, evt):if self.move_flag:print(evt.globalX(),evt.globalX())move_x = evt.globalX() - self.mouse_xmove_y = evt.globalY() - self.mouse_ydest_x = self.origin_x + move_xdest_y = self.origin_y + move_yself.move(dest_x,dest_y)def mouseReleaseEvent(self, evt):self.move_flag = Falseapp = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
控件交互
控件是否可用
btn.setEnabled(False) 设置控件是否可用btn.isEnabled()查看控件是否可用
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("qwq")window.resize(500,500)btn = QPushButton(window)btn.setText("按下")btn.pressed.connect(lambda : print("按钮被点击了"))btn.setEnabled(False) #设置是否可用 不可用print(btn.isEnabled()) #打印是否可用#此时按钮就是灰色window.show()sys.exit(app.exec_())
可见隐形
| API | 作用 |
|---|---|
| setVisible(bool) | 设置控件是否可见 |
| setHidden(bool) | 设置控件是否可见 |
| window.show() | 展示控件 |
| window.hide() | 隐藏控件 |
import sysfrom PyQt5.Qt import *class Window(QWidget):def paintEvent(self,evt):print("窗口被绘制了")return super().paintEvent(evt)class Btn(QPushButton):def paintEvent(self,evt):print("按钮被绘制了")return super().paintEvent(evt)app = QApplication(sys.argv)window = Window()window.setWindowTitle("qwq")window.resize(500,500)btn = Btn(window)btn.setText("按下")btn.pressed.connect(lambda : btn.setVisible(False))window.setVisible(True)sys.exit(app.exec_())
判断隐形
| API | 作用 |
|---|---|
| btn.isHidden() | 判定控件是否基于父控件隐藏 |
| btn.isVisible() | 获取控件最终状态是否可见 |
| btn.isVisibleTo(window) | 如果能随着widget控件的显示和隐藏, 而同步变化, 则返回True |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("qwq")window.resize(500,500)btn = QPushButton(window)btn.setText("按下")window.setVisible(True)print(btn.isHidden())print(btn.isVisible())print(btn.isVisibleTo(window))sys.exit(app.exec_())
被编辑状态
记事本,创建新文本框等操作。
| API | 作用 |
|---|---|
| window.setWindowModified(True) | 设置被编辑状态 |
| window.isWindowModified() | 判断被编辑状态 |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QWidget()window.setWindowTitle("qwq[*]") #设置一个 * 符号 但默认不显示window.resize(500,500)window.setWindowModified(True) #设置为被编辑状态print(window.isWindowModified()) #打印是否为编辑状态window.setVisible(True)sys.exit(app.exec_())
删除控件
删除控件和关闭控件是不一样的
| API | 作用 |
|---|---|
| window.close() | 关闭隐藏控件 |
| window.deleteLater() | 删除控件 |
| window.setAttribute(Qt.WA_DeleteOnClose, True) | 被关闭就是被删除 |
案例-简易的登录判断
import sysfrom PyQt5.Qt import *class Window(QWidget):def __init__(self):super().__init__()self.setWindowTitle("交互状态案例")self.resize(500,500)self.setup_ui()def setup_ui(self):#添加三个子控件#消息提示登录是否成功label = QLabel(self)label.move(100,50)label.setVisible(False) #因为是提示,所以先隐藏Edis1 = QLineEdit(self) #设置文本框Edis1.setText("文本框")Edis1.move(100,100)btn = QPushButton(self)btn.setText("登录")btn.move(100,150)btn.setEnabled(False) #先设置为不可用def test_cao(text): #设置函数,会将文本内容也添加进来print("文本内容发生了改变",text)btn.setEnabled(len(text) > 0) #如果文本内容不为空,则开启Edis1.textChanged.connect(test_cao) #如果编辑框内容更改了,执行函数def check():content = Edis1.text()if content == "LiAo118235":label.setText("登录成功")else:label.setText("登录失败")label.show()label.adjustSize()btn.pressed.connect(check)app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())
消息提示
| API | 作用 |
|---|---|
| window = QMainWindow() | 创建工具组合窗口 |
| window.statusBar() | 显示下面状态栏 |
| window.setWindowFlags(Qt.WindowContextHelpButtonHint) | 设置添加窗口上下文帮助按钮 |
| window.setStatusTip(“这是窗口”) | 当鼠标停留到窗口控件身上之后,在状态栏提示的一段文本 |
| label.setToolTip(“这是提示标签”) | 鼠标放上去停一会显示的文本 |
| label.setToolTipDuration(4000) | 设置显示时长 |
import sysfrom PyQt5.Qt import *app = QApplication(sys.argv)window = QMainWindow() #创建组合控件window.setWindowTitle("信息提示")window.resize(500,500)#懒加载#用到的时候才会加载window.statusBar()window.setWindowFlags(Qt.WindowContextHelpButtonHint) #设置添加窗口上下文帮助按钮#当鼠标停留到窗口控件身上之后,在状态栏提示的一段文本window.setStatusTip("这是窗口")label = QLabel(window)label.setText("我是控件")label.setStatusTip("芜湖~")#鼠标放上去停一会显示label.setToolTip("这是提示标签")#设置显示时长label.setToolTipDuration(4000) #设置4秒label.setWhatsThis("这是标签")window.show()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) | 设置子控件获取焦点的先后顺序 |
import sysfrom PyQt5.Qt import *class Window(QWidget):def mousePressEvent(self,evt):#self.focusNextChild() #聚焦到下一个子控件,下一行#self.focusPreviousChild() #聚焦到上一个子控件,下一行self.focusNextPrevChild(True) #通过True和False判断为上下app = QApplication(sys.argv)window = Window()window.setWindowTitle("社会我奥哥~~~")window.resize(500,500)le1 = QLineEdit(window)le1.move(50,50)le2 = QLineEdit(window)le2.move(50,100)le3 = QLineEdit(window)le3.move(50,150)QWidget.setTabOrder(le1,le3) #设置焦点顺序QWidget.setTabOrder(le3,le2)window.show()#le2.setFocus()#获取当前窗口内部,所有子控件当中获取焦点的控件#print(window.focusWidget())sys.exit(app.exec_())

















