谦逊的电脑桌 · antd 如何同时获取一个select ...· 2 天前 · |
体贴的风衣 · How to apply filter ...· 2 天前 · |
坚韧的酸菜鱼 · 讨论:夏天来了,您可以不开或少开空调吗? ...· 4 天前 · |
耍酷的菠菜 · Dockerfile命令整理 - ...· 5 天前 · |
阳光的海豚 · Puma Future Match NR ...· 2 周前 · |
无邪的消防车 · 港圈李嘉欣:何超琼提出离婚未果,找到娱记甘比 ...· 4 月前 · |
文雅的小蝌蚪 · 快手直播伴侣30帧好还是60怎,快手直播伴侣 ...· 7 月前 · |
行走的打火机 · Developer Community· 8 月前 · |
欢快的花生 · 如何在Windows上使用Nginx托管Gi ...· 10 月前 · |
当一个控件没有父控件的时候,它会被包装成一个框架(有标题栏啊,等等......)
但是,我们可以通过init函数中第二个参数flags 来设置的, 后面再讲(待放链接)
关于控件的坐标系统:
API之获取:
11 window.resize(200,200 ) 13 print (window.geometry()) # 输出: PyQt5.QtCore.QRect(100, 100, 200, 200) 16 window.show() 17 print (window.geometry()) # 输出: PyQt5.QtCore.QRect(101, 131, 200, 200) 20 # 3,进入消息循环 21 sys.exit(app.exec_()) 控件显示之后,某些数据才会正确所以,要获取控件的尺寸,一定要在控件显示完毕之后再去获取!
API之设置 :
move 是操控的x,y 也就是pos ,包含框架。
resize 操控的是用户区域 ,不包含框架(但是太小的话,也不行)
setGeometry() 也是用户区域,
但是此时会有问题:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 # window.setGeometry(0,0,150,150) # 这样不行,需要放在展示后面 12 window.show() 13 window.setGeometry(0,0,150,150) 16 #3,进入消息循环 17 sys.exit(app.exec_())setGeometry()要放在show() 后面 , 在前面会无效!
adjustSize() 根据内容自适应大小
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 window.move(200,200) 11 window.resize(500,500) 13 label = QLabel(window) 14 label.setText("hello world") 15 label.move(100,100) 16 label.setStyleSheet("background-color:cyan;") #为了更清晰看到具体的区域 18 def addContent(): 19 new_content = label.text() +"hello world" 20 label.setText(new_content) 21 label.resize(label.width()+100,label.height()) 24 btn = QPushButton(window) 25 btn.setText("增加内容") 26 btn.move(200,200) 27 btn.clicked.connect(addContent)增加内容(版本二) 笨方法改变大小
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 window.move(200,200) 11 window.resize(500,500) 13 label = QLabel(window) 14 label.setText("hello world") 15 label.move(100,100) 16 label.setStyleSheet("background-color:cyan;") #为了更清晰看到具体的区域 18 def addContent(): 19 new_content = label.text() +"hello world" 20 label.setText(new_content) 22 btn = QPushButton(window) 23 btn.setText("增加内容") 24 btn.move(200,200) 25 btn.clicked.connect(addContent)增加内容(版本一)此时不行,是因为label 的大小是固定的
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 window.move(200,200) 11 window.resize(500,500) 13 label = QLabel(window) 14 label.setText("hello world") 15 label.move(100,100) 16 label.setStyleSheet("background-color:cyan;") #为了更清晰看到具体的区域 18 def addContent(): 19 new_content = label.text() +"hello world" 20 label.setText(new_content) 21 # label.resize(label.width()+100,label.height()) 笨方法 22 label.adjustSize() 25 btn = QPushButton(window) 26 btn.setText("增加内容") 27 btn.move(200,200) 28 btn.clicked.connect(addContent) 32 window.show() 35 #3,进入消息循环 36 sys.exit(app.exec_())增加内容(版本三)自适应大小
setFixedSize() 设置固定尺寸:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 window.move(200,200) 11 # window.resize(500,500) # 这不是固定大小,可以拖拽 12 window.setFixedSize(500,500) # 这才是固定大小 14 label = QLabel(window) 15 label.setText("hello world") 16 label.move(100,100) 19 window.show() 22 #3,进入消息循环 23 sys.exit(app.exec_())设置固定大小
大小位置之案例 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 window.resize(500,500) 11 window.move(300,300) 14 window.show() 17 #3,进入消息循环 18 sys.exit(app.exec_())View Code
首先我们先看下关于子控件的显示问题:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 w = QWidget(window) 11 w.resize(100,100) 12 w.setStyleSheet("background-color:red;") 15 window.show() #显示子控件时是这样的,它必须要在顶层窗口的前面, 16 #因为当顶层窗口显示时,它会遍历它身上的所有的子控件 17 window.resize(500,500) 18 window.move(300,300) 20 #3,进入消息循环 21 sys.exit(app.exec_())子控件的正常显示
但是如果子控件的代码放在了顶层窗口的后面,就没法显示了,因为已经遍历完了,不会再遍历它了。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 12 window.show() #显示子控件时是这样的,它必须要在顶层窗口的前面, 13 #因为当顶层窗口显示时,它会遍历它身上的所有的子控件 14 window.resize(500,500) 15 window.move(300,300) 17 w = QWidget(window) 18 w.resize(100,100) 19 w.setStyleSheet("background-color:red;") 22 #3,进入消息循环 23 sys.exit(app.exec_())此时,不会显示子控件
如何解决,要自己手动调用才能显示子控件:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 12 window.show() #显示子控件时是这样的,它必须要在顶层窗口的前面, 13 #因为当顶层窗口显示时,它会遍历它身上的所有的子控件 14 window.resize(500,500) 15 window.move(300,300) 17 w = QWidget(window) 18 w.resize(100,100) 19 w.setStyleSheet("background-color:red;") 20 w.show() # 自己手动展示 22 #3,进入消息循环 23 sys.exit(app.exec_())手动调用show() 解决上述问题
难点是关于九宫格的布局:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #创建控件 8 window = QWidget() 10 window.show() 12 window.resize(500,500) 13 window.move(300,300) 16 #总控件的个数 17 widget_count = 9 19 #有多少列 20 column_count = 3 22 #一个控件的宽度 23 widget_width = window.width()/column_count 25 #row_count 是有多少行 26 row_count = (widget_count-1)//column_count +1 28 #一个控件的高度 29 widget_height = window.height()/row_count 31 for i in range(widget_count): 32 w = QWidget(window) 33 w.resize(widget_width,widget_height) 34 x,y = divmod(i,column_count) 35 w.move(widget_width*y,widget_height*x) 36 w.setStyleSheet("background-color:red;border:1px solid yellow") 37 w.show() 39 #3,进入消息循环 40 sys.exit(app.exec_())31 for i in range(widget_count): 32 w = QWidget(window) 33 w.resize(widget_width,widget_height) 34 x,y = divmod(i,column_count) 35 w.move(widget_width*y,widget_height* x) 36 w.setStyleSheet( " background-color:red;border:1px solid yellow " ) 37 w.show() 39 # 3,进入消息循环 40 sys.exit(app.exec_()) 修改总数为50,列数为4
import math import sys from PyQt5.QtWidgets import QWidget, QLabel, QApplication, QPushButton class Window(QWidget): def __init__(self): super().__init__() self.setWindowTitle("QT的学习") self.resize(500,500) self.num = 33 self.col = 3 self.set_ui() def set_ui(self): temp = 0 width = self.width()/self.col height = self.height()/math.ceil(self.num / self.col) for rIdx in range(math.ceil(self.num / self.col)): for cIdx in range(self.col): temp += 1 if temp >self.num: break w = QWidget(self) w.resize(width, height) w.move(cIdx*width,rIdx*height) w.setStyleSheet("background-color:red;border:1px solid yellow;") # def timerEvent(self, evt): # self.setGeometry(100,100,self.num,self.num) # self.num += 50 if __name__ == '__main__': app =QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())View Code
直接上案例(api 比较简单)
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("最小尺寸和最大尺寸的限定") 14 # window.resize(500,500) 15 window.setMinimumSize(200,200) #当然也可单独限制高和宽 16 window.setMaximumSize(600,600) 19 #展示控件 20 window.show() 22 #3,进入消息循环 23 sys.exit(app.exec_())限制最大最小尺寸,即可宽高一起设置,也可单独设置
此时能否通过代码来修改尺寸呢?
答案也是不行的。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("最小尺寸和最大尺寸的限定") 14 # window.resize(500,500) 15 window.setMinimumSize(200,200) #当然也可单独限制高和宽 16 window.setMaximumSize(500,500) 18 window.resize(1000,1000) #通过代码也是无法修改的 20 #展示控件 21 window.show() 23 #3,进入消息循环 24 sys.exit(app.exec_())一旦限制之后,通过代码也是无法修改的
内容区域:(文本区域)
内容区域默认是整个标签,可以通过获取内容区域来查看:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("内容边距的设定") 14 window.resize(500,500) 17 label = QLabel(window) 18 label.setText("Life is short,I learn Python!") 19 label.resize(300,300) 20 label.setStyleSheet("background-color:cyan;") 22 print(label.contentsRect()) 25 #展示控件 26 window.show() 29 #3,进入消息循环 30 sys.exit(app.exec_()) 31 ''' 32 输出: 33 PyQt5.QtCore.QRect(0, 0, 300, 300) 34 '''查看内容区域
再次查看内容区域:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("内容边距的设定") 14 window.resize(500,500) 17 label = QLabel(window) 18 label.setText("Life is short,I learn Python!") 19 label.resize(300,300) 20 label.setStyleSheet("background-color:cyan;border:1px solid red") 22 print(label.contentsRect()) 25 #展示控件 26 window.show() 29 #3,进入消息循环 30 sys.exit(app.exec_()) 31 ''' 32 输出: 33 PyQt5.QtCore.QRect(1, 1, 298, 298) #之所以是因为border 占用了内容区域 34 '''边框占用内容区域
内容区域是可以进行控制的,可以通过设置内容边距来实现。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("内容边距的设定") 14 window.resize(500,500) 17 label = QLabel(window) 18 label.setText("Life is short,I learn Python!") 19 label.resize(300,300) 20 label.setStyleSheet("background-color:cyan;border:1px solid red") 22 label.setContentsMargins(100,0,0,0) # 设置内容边距,四个参数是边距顺时针,从左开始 23 print(label.contentsRect()) 26 #展示控件 27 window.show() 30 #3,进入消息循环 31 sys.exit(app.exec_()) 32 ''' 33 输出: 34 PyQt5.QtCore.QRect(100, 0, 200, 300) 35 '''使用setContentsMargins设置内容边距
默认文本显示是水平靠左,竖直居中的 !
当然,各个边的内容边距,我们可以通过getContentsMargins() 来获得,
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("内容边距的设定") 14 window.resize(500,500) 17 label = QLabel(window) 18 label.setText("Life is short,I learn Python!") 19 label.resize(300,300) 20 label.setStyleSheet("background-color:cyan;border:1px solid red") 22 label.setContentsMargins(100,0,100,0) 23 # print(label.contentsRect()) 25 print(label.getContentsMargins()) #打印各个边内容边距设置的具体值 27 #展示控件 28 window.show() 31 #3,进入消息循环 32 sys.exit(app.exec_()) 33 ''' 34 输出: 35 (100, 0, 100, 0) 36 '''查看内容边距的设置
API之显示和关闭事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def showEvent(self, QShowEvent): #具体传过来的事件是什么后面说 16 print("窗口被展示出来") 18 def closeEvent(self, QCloseEvent): #点×调用它 19 print("窗口被关闭了") 21 if __name__ == '__main__': 22 app =QApplication(sys.argv) 24 window = Window() 25 window.show() 27 sys.exit(app.exec_())显示窗口,和关闭窗口事件
API之移动事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def moveEvent(self, QMoveEvent): 16 print("窗口被移动了") 18 if __name__ == '__main__': 19 app =QApplication(sys.argv) 21 window = Window() 22 window.show() 24 sys.exit(app.exec_())移动窗口事件
API之调整大小事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def resizeEvent(self, QResizeEvent): 16 print("窗口改变了尺寸大小") 18 if __name__ == '__main__': 19 app =QApplication(sys.argv) 21 window = Window() 22 window.show() 24 sys.exit(app.exec_())改变窗口尺寸大小事件
这里要注意的是,窗口移动仅仅指的是窗口的 左上角坐标 改变,
而调整大小是整个形状大小改变,二者是不同的。
API之鼠标事件 :
鼠标事件之 进入和离开事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def enterEvent(self, QEvent): 16 print("鼠标进入") 18 def leaveEvent(self, QEvent): 19 print("鼠标离开") 21 if __name__ == '__main__': 22 app =QApplication(sys.argv) 24 window = Window() 25 window.show() 27 sys.exit(app.exec_())鼠标进入和离开窗口
它就可以用做当鼠标在不同位置的时候,给我们呈现不同的样式的应用场景!
例如,鼠标进入给显示黄色,离开显示绿色。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def enterEvent(self, QEvent): 16 print("鼠标进入") 17 self.setStyleSheet("background-color:yellow;") 19 def leaveEvent(self, QEvent): 20 print("鼠标离开") 21 self.setStyleSheet("background-color:green;") 23 if __name__ == '__main__': 24 app =QApplication(sys.argv) 26 window = Window() 27 window.show() 29 sys.exit(app.exec_())进入黄色,离开绿色
鼠标事件之 左键按下和释放( 按下/释放==单击 )事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def mousePressEvent(self, QMouseEvent): 16 print("鼠标被按下了") 18 def mouseReleaseEvent(self, QMouseEvent): 19 print("鼠标被释放了") 21 if __name__ == '__main__': 22 app =QApplication(sys.argv) 24 window = Window() 25 window.show() 27 sys.exit(app.exec_())鼠标按下/释放
鼠标事件之 左键双击事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def mouseDoubleClickEvent(self, QMouseEvent): 16 print("鼠标被双击了") 19 if __name__ == '__main__': 20 app =QApplication(sys.argv) 22 window = Window() 23 window.show() 25 sys.exit(app.exec_())
鼠标事件之 移动事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def mouseMoveEvent(self, QMouseEvent): 16 print("鼠标移动了") 18 if __name__ == '__main__': 19 app =QApplication(sys.argv) 21 window = Window() 22 window.show() 24 sys.exit(app.exec_())按下后移动
设置追踪后,没有按下也可以出发移动事件:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 10 self.setMouseTracking(True) #设置鼠标追踪 13 def set_ui(self): 14 pass 16 def mouseMoveEvent(self, QMouseEvent): 17 print("鼠标移动了") 19 if __name__ == '__main__': 20 app =QApplication(sys.argv) 22 window = Window() 24 window.show() 26 sys.exit(app.exec_())在初始化时,设置鼠标追踪
API之键盘事件 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("QWidget 之事件的api 之显示关闭的学习") 8 self.resize(400,400) 9 self.set_ui() 10 self.setMouseTracking(True) #设置鼠标追踪 13 def set_ui(self): 14 pass 16 def keyPressEvent(self, QKeyEvent): 17 print("键盘上某个键被按下了") 19 def keyReleaseEvent(self, QKeyEvent): 20 print("键盘上某个键被释放了") 25 if __name__ == '__main__': 26 app =QApplication(sys.argv) 28 window = Window() 30 window.show() 32 sys.exit(app.exec_())按键的按压和释放
具体哪个按键,我们可以对事件进行判断,这里先不说。
API之焦点事件 :
某个控件,获得了焦点,比如,用户输入,输入到的是获得焦点的输入框,而不是另外一个输入框。
API之拖拽事件 :
将文件直接拖拽到当前的窗口中,例如,直接将.py 文件拓展到cmd 命令行中。
API之绘制事件 :
我们之所以可以看到控件,就是因为绘制事件。所以,如果,我们想自定义个控件的形状,就可以在这里完成。
API之改变事件 :
API之右键菜单事件 :
API之输入法事件 :
事件之应用场景:
此时,假设窗口中有两个按钮,二者是父子关系,
假设,现在鼠标点击触发了事件,但是儿子中没有实现相应的方法,这时这个事件不会被立即丢弃,而是去看它的父亲中有没有实现相应的方法,如果实现就发给父亲,这就是事件的转发。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print("顶层窗口-按下") 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print("中间窗口-按下") 11 class Label(QLabel): 12 def mousePressEvent(self, QMouseEvent): 13 print("标签控件被按下") 15 #1,创建app 16 app = QApplication(sys.argv) 19 #2,控件的操作: 20 #创建控件 21 window = Window() 22 mid_window = (window) 23 mid_window.resize(300,300) 24 mid_window.setStyleSheet("background-color:red;") #此时,它不起作用,因为它这个样式默认被取消掉了 26 label = Label(mid_window) 27 label.setText("我是标签") 28 label.setStyleSheet("background-color:yellow") 31 #设置控件 32 window.setWindowTitle("事件转发") 33 window.resize(500,500) 37 #展示控件 38 window.show() 40 #3,进入消息循环 41 sys.exit(app.exec_())View Code
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print("顶层窗口-按下") 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print("中间窗口-按下") 11 class Label(QLabel): 12 def mousePressEvent(self, QMouseEvent): 13 print("标签控件被按下") 15 #1,创建app 16 app = QApplication(sys.argv) 19 #2,控件的操作: 20 #创建控件 21 window = Window() 23 mid_window = MidWindow(window) 24 mid_window.resize(300,300) 25 mid_window.setAttribute(Qt.WA_StyledBackground,True) #这样能是下方的qss生效 26 mid_window.setStyleSheet("background-color:red;") 28 label = Label(mid_window) 29 label.setText("我是标签") 30 label.setStyleSheet("background-color:yellow") 31 label.move(100,100) 33 #设置控件 34 window.setWindowTitle("事件转发") 35 window.resize(500,500) 39 #展示控件 40 window.show() 42 #3,进入消息循环 43 sys.exit(app.exec_())使中间的窗口的qss 生效 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print ( " 顶层窗口-按下 " ) 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print ( " 中间窗口-按下 " ) 11 class Label(QLabel): 12 pass 14 # 1,创建app 15 app = QApplication(sys.argv) 18 # 2,控件的操作: 19 # 创建控件 20 window = Window() 22 mid_window = MidWindow(window) 23 mid_window.resize(300,300 ) 24 mid_window.setAttribute(Qt.WA_StyledBackground,True) # 这样能是下方的qss生效 25 mid_window.setStyleSheet( " background-color:red; " ) 27 label = Label(mid_window) 28 label.setText( " 我是标签 " ) 29 label.setStyleSheet( " background-color:yellow " ) 30 label.move(100,100 ) 32 # 设置控件 33 window.setWindowTitle( " 事件转发 " ) 34 window.resize(500,500 ) 38 # 展示控件 39 window.show() 41 # 3,进入消息循环 42 sys.exit(app.exec_()) 此时,去掉Label 中的方法
这个时候是会将事件转发给它的父控件的, 注意是父控件,不是父对象 。
如果将中间控件的方法也给它去掉之后,那么会继续转发到上层父控件!
4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print ( " 顶层窗口-按下 " ) 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print ( " 中间窗口-按下 " ) 12 class Label(QLabel): 13 def mousePressEvent(self, QMouseEvent): 14 print ( " 标签窗口-按下 " ) 16 # 1,创建app 17 app = QApplication(sys.argv) 20 # 2,控件的操作: 21 # 创建控件 22 window = Window() 24 mid_window = MidWindow(window) 25 mid_window.resize(300,300 ) 26 mid_window.setAttribute(Qt.WA_StyledBackground,True) # 这样能是下方的qss生效 27 mid_window.setStyleSheet( " background-color:red; " ) 29 label = QLabel(mid_window) # 注意,这行是QLabel 30 label.setText( " 我是标签 " ) 31 label.setStyleSheet( " background-color:yellow " ) 32 label.move(100,100 ) 34 btn = QPushButton(mid_window) 35 btn.setText( " 我是按钮 " ) 36 btn.setStyleSheet( " background-color:yellow; " ) 37 btn.move(50,50 ) 41 # 设置控件 42 window.setWindowTitle( " 事件转发 " ) 43 window.resize(500,500 ) 47 # 展示控件 48 window.show() 50 # 3,进入消息循环 51 sys.exit(app.exec_()) View Code上面这段代码要说明的是:
当我们点击按钮时候,它是不会触发中间窗口的,但是点击标签时它是会触发中间窗口。
这说明了按钮的QPushButton () 内部是有方法来处理相应的点击的,但是标签QLabel是没有相应的方法来处理的。
这也正说明了QPushButton 就是用来被点击的,而QLabel 的天生的才能只是用来展示内容的。
而且就算是有方法存在也不行,必须对事件对象作出处理,否则还是会往上传。如下代码:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print("顶层窗口-按下") 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print("中间窗口-按下") 12 class Label(QLabel): 13 def mousePressEvent(self, QMouseEvent): 14 # print("标签窗口-按下") 15 pass # 此时虽然有这个方法,但是并为对QMouseEvent 对象作出处理 17 #1,创建app 18 app = QApplication(sys.argv) 21 #2,控件的操作: 22 #创建控件 23 window = Window() 25 mid_window = MidWindow(window) 26 mid_window.resize(300,300) 27 mid_window.setAttribute(Qt.WA_StyledBackground,True) #这样能是下方的qss生效 28 mid_window.setStyleSheet("background-color:red;") 30 label = Label(mid_window) 31 label.setText("我是标签") 32 label.setStyleSheet("background-color:yellow") 33 label.move(100,100) 35 btn = QPushButton(mid_window) 36 btn.setText("我是按钮") 37 btn.setStyleSheet("background-color:yellow;") 38 btn.move(50,50) 42 #设置控件 43 window.setWindowTitle("事件转发") 44 window.resize(500,500) 48 #展示控件 49 window.show() 51 #3,进入消息循环 52 sys.exit(app.exec_())View code
此时如果点击标签,还是会触发中间窗口的。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print("顶层窗口-按下") 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print("中间窗口-按下") 12 class Label(QLabel): 13 # def mousePressEvent(self, QMouseEvent): 14 # print("标签窗口-按下") 15 def mousePressEvent(self, event): 16 print("标签窗口-按下") 17 event.accept() # 这代表的是告诉操作系统, 18 # 我们已经收到了这个事件对象,不需要再次向上转发了 19 #1,创建app 20 app = QApplication(sys.argv) 23 #2,控件的操作: 24 #创建控件 25 window = Window() 27 mid_window = MidWindow(window) 28 mid_window.resize(300,300) 29 mid_window.setAttribute(Qt.WA_StyledBackground,True) #这样能是下方的qss生效 30 mid_window.setStyleSheet("background-color:red;") 32 label = Label(mid_window) 33 label.setText("我是标签") 34 label.setStyleSheet("background-color:yellow") 35 label.move(100,100) 37 btn = QPushButton(mid_window) 38 btn.setText("我是按钮") 39 btn.setStyleSheet("background-color:yellow;") 40 btn.move(50,50) 44 #设置控件 45 window.setWindowTitle("事件转发") 46 window.resize(500,500) 50 #展示控件 51 window.show() 53 #3,进入消息循环 54 sys.exit(app.exec_())事件对象的方法accept() 告诉操作系统不让向上转发事件了
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print("顶层窗口-按下") 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print("中间窗口-按下") 12 class Label(QLabel): 13 # def mousePressEvent(self, QMouseEvent): 14 # print("标签窗口-按下") 15 def mousePressEvent(self, event): 16 print("标签窗口-按下") 17 print(event.isAccepted()) # 它用来查看事件对象是否被接受了 18 #1,创建app 19 app = QApplication(sys.argv) 22 #2,控件的操作: 23 #创建控件 24 window = Window() 26 mid_window = MidWindow(window) 27 mid_window.resize(300,300) 28 mid_window.setAttribute(Qt.WA_StyledBackground,True) #这样能是下方的qss生效 29 mid_window.setStyleSheet("background-color:red;") 31 label = Label(mid_window) 32 label.setText("我是标签") 33 label.setStyleSheet("background-color:yellow") 34 label.move(100,100) 36 btn = QPushButton(mid_window) 37 btn.setText("我是按钮") 38 btn.setStyleSheet("background-color:yellow;") 39 btn.move(50,50) 43 #设置控件 44 window.setWindowTitle("事件转发") 45 window.resize(500,500) 49 #展示控件 50 window.show() 52 #3,进入消息循环 53 sys.exit(app.exec_())event.isAccepted() 查看事件对象是否被接收
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, QMouseEvent): 6 print("顶层窗口-按下") 7 class MidWindow(QWidget): 8 def mousePressEvent(self, QMouseEvent): 9 print("中间窗口-按下") 12 class Label(QLabel): 13 # def mousePressEvent(self, QMouseEvent): 14 # print("标签窗口-按下") 15 def mousePressEvent(self, event): 16 print("标签窗口-按下") 17 event.ignore() 18 print(event.isAccepted()) 20 #1,创建app 21 app = QApplication(sys.argv) 24 #2,控件的操作: 25 #创建控件 26 window = Window() 28 mid_window = MidWindow(window) 29 mid_window.resize(300,300) 30 mid_window.setAttribute(Qt.WA_StyledBackground,True) #这样能是下方的qss生效 31 mid_window.setStyleSheet("background-color:red;") 33 label = Label(mid_window) 34 label.setText("我是标签") 35 label.setStyleSheet("background-color:yellow") 36 label.move(100,100) 38 btn = QPushButton(mid_window) 39 btn.setText("我是按钮") 40 btn.setStyleSheet("background-color:yellow;") 41 btn.move(50,50) 45 #设置控件 46 window.setWindowTitle("事件转发") 47 window.resize(500,500) 51 #展示控件 52 window.show() 54 #3,进入消息循环 55 sys.exit(app.exec_()) 56 ''' 57 输出: 58 标签窗口-按下 (虚假的,它不代表事件对象被处理了,后面将它忽略了) 59 False 60 中间窗口-按下 61 '''event.ignore() 将事件对象忽略,它将会向上继续转发事件
其实,我们是可以利用event.ignore() 来实现,整个父控件都去处理它这个信号的,相当于加了个标识!。
事件消息之案例 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class MyLabel(QLabel): 6 def enterEvent(self, *args, **kwargs): 7 self.setText("欢迎光临") 8 print("鼠标进入") 9 def leaveEvent(self, *args, **kwargs): 10 self.setText("谢谢惠顾") 11 print("鼠标离开") 14 #1,创建app 15 app = QApplication(sys.argv) 18 #2,控件的操作: 19 #创建控件 20 window = QWidget() 23 #设置控件 24 window.setWindowTitle("事件的案例1") 25 window.resize(500,500) 27 label = MyLabel(window) 28 label.setStyleSheet("background-color:cyan") 29 label.move(200,200) 30 label.resize(100,100) 34 #展示控件 35 window.show() 37 #3,进入消息循环 38 sys.exit(app.exec_())
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class MyLabel(QLabel): 6 def enterEvent(self, *args, **kwargs): 7 self.setText("欢迎光临") 8 print("鼠标进入") 9 def leaveEvent(self, *args, **kwargs): 10 self.setText("谢谢惠顾") 11 print("鼠标离开") 13 # def keyPressEvent(self, QKeyEvent): 14 # 15 def keyPressEvent(self, event): 16 # event.key() == Qt.Key_Tab #所有的普通都可以这样对比 17 #键分为 普通键和修饰键 ctrl alt fn 等键 18 if event.key() == Qt.Key_Tab: 19 print("点击了Tab键") 22 #1,创建app 23 app = QApplication(sys.argv) 26 #2,控件的操作: 27 #创建控件 28 window = QWidget() 31 #设置控件 32 window.setWindowTitle("事件的案例1") 33 window.resize(500,500) 35 label = MyLabel(window) 36 label.setStyleSheet("background-color:cyan") 37 label.move(200,200) 38 label.resize(100,100) 42 #展示控件 43 window.show() 45 #3,进入消息循环 46 sys.exit(app.exec_())监听Tab
这时不行,因为用户按下按键,但是控件有多个,所以我们要设置将焦点给标签,这样才能捕获到按键。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class MyLabel(QLabel): 6 def enterEvent(self, *args, **kwargs): 7 self.setText("欢迎光临") 8 print("鼠标进入") 9 def leaveEvent(self, *args, **kwargs): 10 self.setText("谢谢惠顾") 11 print("鼠标离开") 13 # def keyPressEvent(self, QKeyEvent): 14 # 15 def keyPressEvent(self, event): 16 # event.key() == Qt.Key_Tab #所有的普通都可以这样对比 17 #键分为 普通键和修饰键 ctrl alt fn 等键 18 if event.key() == Qt.Key_Tab: 19 print("点击了Tab键") 22 #1,创建app 23 app = QApplication(sys.argv) 26 #2,控件的操作: 27 #创建控件 28 window = QWidget() 31 #设置控件 32 window.setWindowTitle("事件的案例1") 33 window.resize(500,500) 35 label = MyLabel(window) 36 label.setStyleSheet("background-color:cyan") 37 label.move(200,200) 38 label.resize(100,100) 39 label.grabKeyboard() # 让label 捕获键盘 42 #展示控件 43 window.show() 45 #3,进入消息循环 46 sys.exit(app.exec_())用grabKeyboard()来让label来获取焦点
下面看组合键,它就涉及到了修饰键了。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class MyLabel(QLabel): 6 def enterEvent(self, *args, **kwargs): 7 self.setText("欢迎光临") 8 print("鼠标进入") 9 def leaveEvent(self, *args, **kwargs): 10 self.setText("谢谢惠顾") 11 print("鼠标离开") 13 # def keyPressEvent(self, QKeyEvent): 14 # 15 def keyPressEvent(self, event): 16 # event.key() == Qt.Key_Tab #所有的普通都可以这样对比 17 #键分为 普通键和修饰键 ctrl alt fn 等键 18 # if event.key() == Qt.Key_Tab: 19 # print("点击了Tab键") 20 if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_S: #modifiers() 是获取修饰键的 21 print("用户点击了 Ctrl + S ") 24 #1,创建app 25 app = QApplication(sys.argv) 28 #2,控件的操作: 29 #创建控件 30 window = QWidget() 33 #设置控件 34 window.setWindowTitle("事件的案例1") 35 window.resize(500,500) 37 label = MyLabel(window) 38 label.setStyleSheet("background-color:cyan") 39 label.move(200,200) 40 label.resize(100,100) 41 label.grabKeyboard() # 让label 捕获键盘 44 #展示控件 45 window.show() 47 #3,进入消息循环 48 sys.exit(app.exec_())Ctrl + s 组合键
如果有多个修饰键:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class MyLabel(QLabel): 6 def enterEvent(self, *args, **kwargs): 7 self.setText("欢迎光临") 8 print("鼠标进入") 9 def leaveEvent(self, *args, **kwargs): 10 self.setText("谢谢惠顾") 11 print("鼠标离开") 13 # def keyPressEvent(self, QKeyEvent): 14 # 15 def keyPressEvent(self, event): 16 # event.key() == Qt.Key_Tab #所有的普通都可以这样对比 17 #键分为 普通键和修饰键 ctrl alt fn 等键 18 # if event.key() == Qt.Key_Tab: 19 # print("点击了Tab键") 20 if event.modifiers() == Qt.ControlModifier | Qt.ShiftModifier and event.key() == Qt.Key_A: #modifiers() 是获取修饰键的 21 print("用户点击了 Ctrl + Shift+ A ") 24 #1,创建app 25 app = QApplication(sys.argv) 28 #2,控件的操作: 29 #创建控件 30 window = QWidget() 33 #设置控件 34 window.setWindowTitle("事件的案例1") 35 window.resize(500,500) 37 label = MyLabel(window) 38 label.setStyleSheet("background-color:cyan") 39 label.move(200,200) 40 label.resize(100,100) 41 label.grabKeyboard() # 让label 捕获键盘 44 #展示控件 45 window.show() 47 #3,进入消息循环 48 sys.exit(app.exec_())Ctrl + Shift +A
多个修饰键要用 按位或 | 来写。
简单了解 按位或 :
一般情况下,用户区是不支持拖拽的,只有标题栏那个地方可以拖拽。
它解决如下需求:
其实这里涉及到三个事件,鼠标按下,鼠标移动,鼠标松开,
这里涉及的计算问题如下:
具体计算向量的时候应该以全局的坐标为准,因为桌面不会变。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("窗口移动的学习") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 pass 15 def mousePressEvent(self, event): 16 # print("鼠标按下") 17 QMouseEvent 18 #确定两个点,鼠标第一次按下的点,和控件窗口的原始点 19 self.mouse_x = event.globalX() 20 self.mouse_y = event.globalY() 21 self.contrl_window_x = self.x() # 控件窗口的全局坐标 22 self.contrl_window_y = self.y() 26 def mouseMoveEvent(self, event): 27 # print("鼠标移动") 28 #计算移动向量 29 move_x = event.globalX() - self.mouse_x 30 move_y = event.globalY() - self.mouse_y 31 print(move_x,move_y) 32 #我们将这个移动向量作用到控件窗口的原始点就行了 33 self.move(self.contrl_window_x+move_x,self.contrl_window_y+move_y) 36 def mouseReleaseEvent(self, QMouseEvent): 37 print("鼠标松开") 40 if __name__ == '__main__': 41 app =QApplication(sys.argv) 43 window = Window() 44 window.show() 46 sys.exit(app.exec_())View Code
此时一定要避免鼠标跟踪,如果有鼠标跟踪的话,会立马崩溃。这时因为设置鼠标跟踪的话,会立马执行mouseMoveEvent() 方法,但是它的逻辑里需要先执行的是鼠标按下的操作,所以会崩。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("窗口移动的学习") 8 self.resize(400,400) 9 self.set_ui() 11 self.move_flag = False 14 def set_ui(self): 15 pass 17 def mousePressEvent(self, event): 18 self.move_flag = True 19 # print("鼠标按下") 20 QMouseEvent 21 #确定两个点,鼠标第一次按下的点,和控件窗口的原始点 22 self.mouse_x = event.globalX() 23 self.mouse_y = event.globalY() 24 self.contrl_window_x = self.x() # 控件窗口的全局坐标 25 self.contrl_window_y = self.y() 27 def mouseMoveEvent(self, event): 28 if self.move_flag: 29 # print("鼠标移动") 30 #计算移动向量 31 move_x = event.globalX() - self.mouse_x 32 move_y = event.globalY() - self.mouse_y 33 print(move_x,move_y) 34 #我们将这个移动向量作用到控件窗口的原始点就行了 35 self.move(self.contrl_window_x+move_x,self.contrl_window_y+move_y) 37 def mouseReleaseEvent(self, QMouseEvent): 38 print("鼠标松开") 39 self.move_flag = False 42 if __name__ == '__main__': 43 app =QApplication(sys.argv) 45 window = Window() 46 window.setMouseTracking(True) 47 window.show() 49 sys.exit(app.exec_())通过move_flag 来解决鼠标追踪的问题
这时有鼠标跟踪也没关系了,点击鼠标,给移动标记为True ,松开鼠标,移动标记为False .
此时,还有点小问题,就是如果这时候,我们通过鼠标的右键也是可以移动窗口的。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("窗口移动的学习") 8 self.resize(400,400) 9 self.set_ui() 11 self.move_flag = False 14 def set_ui(self): 15 pass 17 def mousePressEvent(self, event): 18 if event.button() == Qt.LeftButton: 19 self.move_flag = True 20 # print("鼠标按下") 21 QMouseEvent 22 #确定两个点,鼠标第一次按下的点,和控件窗口的原始点 23 self.mouse_x = event.globalX() 24 self.mouse_y = event.globalY() 25 self.contrl_window_x = self.x() # 控件窗口的全局坐标 26 self.contrl_window_y = self.y() 28 def mouseMoveEvent(self, event): 29 if self.move_flag: 30 # print("鼠标移动") 31 #计算移动向量 32 move_x = event.globalX() - self.mouse_x 33 move_y = event.globalY() - self.mouse_y 34 print(move_x,move_y) 35 #我们将这个移动向量作用到控件窗口的原始点就行了 36 self.move(self.contrl_window_x+move_x,self.contrl_window_y+move_y) 38 def mouseReleaseEvent(self, QMouseEvent): 39 print("鼠标松开") 40 self.move_flag = False 43 if __name__ == '__main__': 44 app =QApplication(sys.argv) 46 window = Window() 47 window.setMouseTracking(True) 48 window.show() 50 sys.exit(app.exec_())通过 event.button() 来设置只能鼠标左键按下才能移动
API 之设置鼠标形状
:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("鼠标操作") 14 window.resize(500,500) 16 window.setCursor(Qt.BusyCursor) #转圈圈的样式 20 #展示控件 21 window.show() 23 #3,进入消息循环 24 sys.exit(app.exec_())Qt.BusyCursor 繁忙的样式
其他的效果都可以尝试。
也可以自定义图标。
下面看如何自定义:
先看,鼠标变化它是对应到具体的控件的,它只有进入到相应的控件才会变化。
所以,我们在上面先创建个对象。
那么QCursor 对象如何创建,我们点进去,它需要一个QPixMap对象,
所以我们再构造一个QPixMap对象。它的构造方法是将图片的路径传入即可。
图片如下图:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("鼠标操作") 14 window.resize(500,500) 16 # window.setCursor(Qt.BusyCursor) #转圈圈的样式 18 pixmap = QPixmap("d:/icon.png") 19 cursor = QCursor(pixmap) 20 window.setCursor(cursor) 22 #展示控件 23 window.show() 25 #3,进入消息循环 26 sys.exit(app.exec_())这时鼠标进入之后就变成相应的图片了
而且图片的大小本身都是可以调节的,可以通过pixmap 中的scaled() 进行缩放。
但是要注意,scaled() 是将缩放后的图片通过返回值的形式给出的,
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("鼠标操作") 14 window.resize(500,500) 16 # window.setCursor(Qt.BusyCursor) #转圈圈的样式 18 pixmap = QPixmap("d:/icon.png") 19 new_pixmap = pixmap.scaled(50,50) #改变图片的尺寸 #注意它是以返回值的形式给出 21 cursor = QCursor(new_pixmap) 22 window.setCursor(cursor) 24 #展示控件 25 window.show() 27 #3,进入消息循环 28 sys.exit(app.exec_())
关于鼠标的热点位置:
可以修改为0,0, 这就是图片的左上角成为热点。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("鼠标操作") 14 window.resize(500,500) 16 # window.setCursor(Qt.BusyCursor) #转圈圈的样式 18 pixmap = QPixmap("d:/icon.png") 19 new_pixmap = pixmap.scaled(50,50) #改变图片的尺寸 #注意它是以返回值的形式给出 21 cursor = QCursor(new_pixmap,0,0) # 将热点修改为0,0 22 window.setCursor(cursor) 24 #展示控件 25 window.show() 27 #3,进入消息循环 28 sys.exit(app.exec_())修改热点位置为左上角
API 之设置重置形状 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("鼠标操作") 14 window.resize(500,500) 16 # window.setCursor(Qt.BusyCursor) #转圈圈的样式 18 pixmap = QPixmap("d:/icon.png") 19 new_pixmap = pixmap.scaled(50,50) #改变图片的尺寸 #注意它是以返回值的形式给出 21 cursor = QCursor(new_pixmap,0,0) # 将热点修改为0,0 22 window.setCursor(cursor) 25 window.unsetCursor() # 重置鼠标形状,使上面的设置失效 27 #展示控件 28 window.show() 30 #3,进入消息循环 31 sys.exit(app.exec_())重置鼠标形状
API 之获取鼠标对象 :
获取鼠标对象,之后我们就可以获取它的图片,它的位置,等等。。。
16 current_cursor = window.cursor() # 获取鼠标对象 18 print (current_cursor.pos()) # 获取鼠标的位置 PyQt5.QtCore.QPoint(748, 260) 19 # 它是相对于整个电脑屏幕的 21 # 为了验证这一点,我们通过下的验证 22 current_cursor.setPos(0,0) # 这时鼠标的位置在 屏幕的左上角 26 # 展示控件 27 window.show() 29 # 3,进入消息循环 30 sys.exit(app.exec_()) 获取鼠标对象它里面的pos() 方法获取的位置是相对于整个屏幕的左上角而言的!
API 之鼠标跟踪 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class MyWindow(QWidget): 5 def mouseMoveEvent(self, event): 6 print("鼠标移动了") 9 #1,创建app 10 app = QApplication(sys.argv) 12 #2,控件的操作: 13 #创建控件 14 window = MyWindow() 16 window.setMouseTracking(True) #设置跟踪 17 print(window.hasMouseTracking()) #查看鼠标是否处于跟踪状态 21 #设置控件 22 window.setWindowTitle("鼠标操作") 23 window.resize(500,500) 26 #展示控件 27 window.show() 29 #3,进入消息循环 30 sys.exit(app.exec_())设置鼠标跟踪
下面看下传来的参数event中的东西:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class MyWindow(QWidget): 6 # def mouseMoveEvent(self, QMouseEvent): 7 # pass 8 def mouseMoveEvent(self, event): 9 # print("鼠标移动了",event.globalPos()) # globalPos() 是整个屏幕为准 10 print("鼠标移动了",event.localPos()) # globalPos() 是控件本身为准 13 #1,创建app 14 app = QApplication(sys.argv) 16 #2,控件的操作: 17 #创建控件 18 window = MyWindow() 20 window.setMouseTracking(True) #设置跟踪 21 print(window.hasMouseTracking()) #查看鼠标是否处于跟踪状态 25 #设置控件 26 window.setWindowTitle("鼠标操作") 27 window.resize(500,500) 30 #展示控件 31 window.show() 33 #3,进入消息循环 34 sys.exit(app.exec_())View Code
鼠标相关的案例 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class Window(QWidget): 6 def mouseMoveEvent(self, event): 7 print("鼠标移动",event.localPos()) 8 label = self.findChild(QLabel) 9 # label.move(300,300) 10 # label.move(event.localPos()) # 这样直接放是不行的 11 # print(event.localPos()) #PyQt5.QtCore.QPointF 12 # QPointF 里面有x() y() 13 label.move(event.localPos().x(),event.localPos().y()) 16 #1,创建app 17 app = QApplication(sys.argv) 20 #2,控件的操作: 21 #创建控件 22 window = Window() 25 #设置控件 26 window.setWindowTitle("鼠标相关的案例") 27 window.resize(500,500) 28 window.setMouseTracking(True) #设置鼠标跟踪,这样鼠标一进去就会调用它的方法 29 #mouseMoveEvent() 了 32 #自定义鼠标 33 pixmap = QPixmap("d:/icon.png").scaled(50,50) 34 cursor = QCursor(pixmap) 35 window.setCursor(cursor) 37 label = QLabel(window) 38 label.setText("Life is short,I learn Python!") 39 label.move(100,100) 40 label.setStyleSheet("background-color:cyan;") 44 #展示控件 45 window.show() 47 #3,进入消息循环 48 sys.exit(app.exec_())案例(版本一 未封装)
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class Window(QWidget): 6 def __init__(self): 7 super().__init__() 8 #设置控件 9 self.setWindowTitle("鼠标相关的案例") 10 self.resize(500,500) 11 self.setMouseTracking(True) 12 self.setMyCursor() 13 self.setLabel() 16 def setMyCursor(self): 17 pixmap = QPixmap("d:/icon.png").scaled(50,50) 18 cursor = QCursor(pixmap) 19 self.setCursor(cursor) 20 def setLabel(self): 21 self.label = QLabel(self) 22 self.label.setText("Life is short,I learn Python!") 23 self.label.move(100,100) 24 self.label.setStyleSheet("background-color:cyan;") 27 def mouseMoveEvent(self, event): 28 print("鼠标移动",event.localPos()) 29 self.label.move(event.localPos().x(),event.localPos().y()) 32 #1,创建app 33 app = QApplication(sys.argv) 36 window = Window() 39 #展示控件 40 window.show() 42 #3,进入消息循环 43 sys.exit(app.exec_())案例(版本二 采用封装)
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("父子关系的学习") 14 window.resize(500,500) 16 label1 = QLabel(window) 17 # label1.setParent(window) 也可以设置父亲 18 label1.setText("标签1") 20 label2 = QLabel(window) 21 label2.setText("标签2") 22 label2.move(100,100) 24 label3 = QLabel(window) 25 label3.setText("标签3") 26 label3.move(200,200) 28 print(window.childAt(101,105)) # 窗口 window 查看101,105 处是否有控件 输出:<PyQt5.QtWidgets.QLabel object at 0x0000021076265A68> 30 print(window.childAt(300,300)) # 窗口 window 查看300,300 处是否有控件 输出:None 33 #展示控件 34 window.show() 36 #3,进入消息循环 37 sys.exit(app.exec_())利用ChildrenAt() 来查看一个位置是否有子控件
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("父子关系的学习") 14 window.resize(500,500) 16 label1 = QLabel(window) 17 # label1.setParent(window) 也可以设置父亲 18 label1.setText("标签1") 20 label2 = QLabel(window) 21 label2.setText("标签2") 22 label2.move(100,100) 24 label3 = QLabel(window) 25 label3.setText("标签3") 26 label3.move(200,200) 28 print(window.childrenRect()) # 查看所有子控件的矩形区域 输出:PyQt5.QtCore.QRect(0, 0, 300, 230) 30 #展示控件 31 window.show() 33 #3,进入消息循环 34 sys.exit(app.exec_())利用childrenRect() 来获取所有子控件的矩形区域
父子关系的案例 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Label(QLabel): 5 def mousePressEvent(self, QMouseEvent): 6 self.setStyleSheet("background-color:red;") 9 #1,创建app 10 app = QApplication(sys.argv) 13 #2,控件的操作: 14 #创建控件 15 window = QWidget() 18 #设置控件 19 window.setWindowTitle("父子关系案例") 20 window.resize(500,500) 22 for i in range(10): 23 label = Label(window) 24 label.setText("标签"+str(i)) 25 label.move(30*i ,30*i) 28 #展示控件 29 window.show() 31 #3,进入消息循环 32 sys.exit(app.exec_())通过自定义Label()类来实现
下面是不通过自定义类照样实现这个功能:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, event): 6 local_x = event.x() 7 local_y = event.y() 8 sub_widget = self.childAt(local_x,local_y) 9 if sub_widget: # 排除sub_widget 是None 10 sub_widget.setStyleSheet("background-color:red;") 12 #1,创建app 13 app = QApplication(sys.argv) 16 #2,控件的操作: 17 #创建控件 18 window = Window() 21 #设置控件 22 window.setWindowTitle("父子关系案例") 23 window.resize(500,500) 25 for i in range(10): 26 label = QLabel(window) 27 label.setText("标签"+str(i)) 28 label.move(30*i ,30*i) 31 #展示控件 32 window.show() 34 #3,进入消息循环 35 sys.exit(app.exec_())不通过自定义标签类照样解决问题
它主要的作用就是调整z轴顺序:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("层级控制") 14 window.resize(500,500) 17 label1 = QLabel(window) 18 label1.setText("标签1") 19 label1.resize(200,200) 20 label1.setStyleSheet("background-color:red;") 22 label2 = QLabel(window) 23 label2.setText("标签2") 24 label2.resize(200,200) 25 label2.setStyleSheet("background-color:green;") 26 label2.move(100,100) 28 #展示控件 29 window.show() 31 #3,进入消息循环 32 sys.exit(app.exec_())View Code
现在如果想让早出现的红色在上面:
一共有三种方法:
1,将红色的升上去
2,将绿色的降下去
3,将绿色放在红色下面
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("层级控制") 14 window.resize(500,500) 17 label1 = QLabel(window) 18 label1.setText("标签1") 19 label1.resize(200,200) 20 label1.setStyleSheet("background-color:red;") 22 label2 = QLabel(window) 23 label2.setText("标签2") 24 label2.resize(200,200) 25 label2.setStyleSheet("background-color:green;") 26 label2.move(100,100) 28 label1.raise_() # 让label1 升到最高 30 #展示控件 31 window.show() 33 #3,进入消息循环 34 sys.exit(app.exec_())将label1 升到最高
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("层级控制") 14 window.resize(500,500) 17 label1 = QLabel(window) 18 label1.setText("标签1") 19 label1.resize(200,200) 20 label1.setStyleSheet("background-color:red;") 22 label2 = QLabel(window) 23 label2.setText("标签2") 24 label2.resize(200,200) 25 label2.setStyleSheet("background-color:green;") 26 label2.move(100,100) 28 label2.lower() # 将label2 降到最下层 31 #展示控件 32 window.show() 34 #3,进入消息循环 35 sys.exit(app.exec_())将label2 降下去
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("层级控制") 14 window.resize(500,500) 17 label1 = QLabel(window) 18 label1.setText("标签1") 19 label1.resize(200,200) 20 label1.setStyleSheet("background-color:red;") 22 label2 = QLabel(window) 23 label2.setText("标签2") 24 label2.resize(200,200) 25 label2.setStyleSheet("background-color:green;") 26 label2.move(100,100) 28 label2.stackUnder(label1) # 将label2 放在label1 的下面 30 #展示控件 31 window.show() 33 #3,进入消息循环 34 sys.exit(app.exec_())将label2 放在label1 的下面
现在需求是点击谁,让谁跑到上面:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class MyLabel(QLabel): 5 def mousePressEvent(self, QMouseEvent): 6 self.raise_() 9 #1,创建app 10 app = QApplication(sys.argv) 13 #2,控件的操作: 14 #创建控件 15 window = QWidget() 18 #设置控件 19 window.setWindowTitle("层级控制") 20 window.resize(500,500) 23 label1 = MyLabel(window) 24 label1.setText("标签1") 25 label1.resize(200,200) 26 label1.setStyleSheet("background-color:red;") 28 label2 = MyLabel(window) 29 label2.setText("标签2") 30 label2.resize(200,200) 31 label2.setStyleSheet("background-color:green;") 32 label2.move(100,100) 34 label2.stackUnder(label1) # 将label2 放在label1 的下面 36 #展示控件 37 window.show() 39 #3,进入消息循环 40 sys.exit(app.exec_())点谁,谁出现在最上层
如果一个控件没有父控件,那么它就是顶层窗口。
API之图标:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("顶层窗口相关操作") 14 window.resize(500,500) 16 icon = QIcon("d:/icon.png") 17 window.setWindowIcon(icon) #设置图标 19 print(window.windowIcon()) #获取图标 23 #展示控件 24 window.show() 26 #3,进入消息循环 27 sys.exit(app.exec_())设置图标以及获取图标
API之标题 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("顶层窗口相关操作") 14 window.resize(500,500) 16 window.setWindowTitle(" ") #设置标题 17 print(window.windowTitle()) #获取标题 21 #展示控件 22 window.show() 24 #3,进入消息循环 25 sys.exit(app.exec_())View Code
API之不透明度 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("顶层窗口相关操作") 14 window.resize(500,500) 16 window.setWindowOpacity(0.5) # 设置为半透明 17 print(window.windowOpacity()) # 获取不透明度 20 #展示控件 21 window.show() 23 #3,进入消息循环 24 sys.exit(app.exec_())View Code
API之窗口状态 :
无状态是正常的状态。是默认的状态,
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("顶层窗口相关操作") 14 window.resize(500,500) 16 print(window.windowState() == Qt.WindowNoState) # True 说明默认是无状态 18 window.setWindowState(Qt.WindowMinimized) #最小化 19 window.setWindowState(Qt.WindowMaximized) #最大化 有标题栏 20 window.setWindowState(Qt.WindowFullScreen) #最小化 标题栏都没了 #这时要通过任务管理器结束进程 24 #展示控件 25 window.show() 27 #3,进入消息循环 28 sys.exit(app.exec_())顶层窗口的状态---无状态,最小化,最大化,和全屏
活动窗口:是当有多个窗口时,让活跃的窗口处在最顶层。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("顶层窗口相关操作") 14 window.resize(500,500) 16 print(window.windowState() == Qt.WindowNoState) # True 说明默认是无状态 18 window.setWindowState(Qt.WindowMinimized) #最小化 19 window.setWindowState(Qt.WindowMaximized) #最大化 有标题栏 20 # window.setWindowState(Qt.WindowFullScreen) #最小化 标题栏都没了 #这时要通过任务管理器结束进程 22 window2 = QWidget() 24 window2.show() 27 #展示控件 28 window.show() 29 window2.setWindowState(Qt.WindowActive) 31 #3,进入消息循环 32 sys.exit(app.exec_())View Code
API之最大化和最小化 :
我们可以通过窗口状态来设置最大和最小,但是一般常用的是用这些:
showFull showMax showMin
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("顶层窗口相关操作") 14 window.resize(500,500) 17 #展示控件 18 # window.show() 19 window.showMaximized() #展示最大,这时上面的window.show() 也可以不用要 20 # window.showFullScreen() 21 # window.showMinimized() 24 #3,进入消息循环 25 sys.exit(app.exec_())View Code
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class Window(QWidget): 6 def mousePressEvent(self, QMouseEvent): 7 if self.isMaximized(): 8 self.showNormal() 9 else: 10 self.showMaximized() 12 #1,创建app 13 app = QApplication(sys.argv) 16 #2,控件的操作: 17 #创建控件 18 window = Window() 21 #设置控件 22 window.setWindowTitle("顶层窗口相关操作") 23 window.resize(500,500) 26 #展示控件 27 window.show() 31 #3,进入消息循环 32 sys.exit(app.exec_())通过判定窗口的状态实现点击窗口切换最大和正常
API之窗口标志 :
可以通过它设置窗口的外观。
这里如果是我们只要求有一个最大化的按钮,这又该如何去搞呢?
这主要是通过 顶层窗口外观标志 来设置:
顶层窗口的案例 :
第一个需求是:去掉标题栏
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget(flags=Qt.FramelessWindowHint) 10 # def __init__(self, parent=None, flags, Qt_WindowFlags=None, Qt_WindowType=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 11 # pass 12 # 在创建窗口的时候就可以对外观标志进行设置了, 15 #设置控件 16 window.setWindowTitle("顶层窗口操作案例") 17 window.resize(500,500) 23 #展示控件 24 window.show() 26 #3,进入消息循环 27 sys.exit(app.exec_())初始化窗口的时候就设置flags
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 10 window.setWindowFlags(Qt.FramelessWindowHint) #通过方法设置flags 13 #设置控件 14 window.setWindowTitle("顶层窗口操作案例") 15 window.resize(500,500) 21 #展示控件 22 window.show() 24 #3,进入消息循环 25 sys.exit(app.exec_())通过setWindowFlags设置flags
第二个需求:让窗口变为半透明,
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget(flags=Qt.FramelessWindowHint) 10 window.setWindowOpacity(0.5) 14 #设置控件 15 window.setWindowTitle("顶层窗口操作案例") 16 window.resize(500,500) 19 #展示控件 20 window.show() 22 #3,进入消息循环 23 sys.exit(app.exec_())View Code
第三个需求:自定制标题栏,
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget(flags=Qt.FramelessWindowHint) 10 window.setWindowOpacity(0.9) 14 #设置控件 15 window.setWindowTitle("顶层窗口操作案例") 16 window.resize(500,500) 20 #添加三个子控件 - 窗口的右上角 21 close_btn = QPushButton(window) 22 close_btn.setText("关闭") #暂时以文本呈现 23 close_btn.resize(40,25) 24 close_btn_width = close_btn.width() 25 window_width = window.width() 26 close_btn_x = window_width - close_btn_width 27 close_btn_y = 0 28 close_btn.move(close_btn_x,close_btn_y) 30 max_btn = QPushButton(window) 31 max_btn.setText("最大") 32 max_btn.resize(40,25) 33 max_btn_x = close_btn_x -max_btn.width() 34 max_btn_y = 0 35 max_btn.move(max_btn_x,max_btn_y) 37 mini_btn = QPushButton(window) 38 mini_btn.setText("最小") 39 mini_btn.resize(40,25) 40 mini_btn_x = max_btn_x -mini_btn.width() 41 mini_btn_y = 0 42 mini_btn.move(mini_btn_x,mini_btn_y) 46 #展示控件 47 window.show() 49 #3,进入消息循环 50 sys.exit(app.exec_())View Code
继续第三个操作,实现三个按钮的功能:
监听按钮有两个思路,一个是按信号和槽,一个是监听事件,修改它的方法。
信号会更好一点,它是事件的高级封装,一般能用信号和槽的都用信号和槽。
按钮按下会发出信号pressed。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget(flags=Qt.FramelessWindowHint) 10 window.setWindowOpacity(0.9) 14 #设置控件 15 window.setWindowTitle("顶层窗口操作案例") 16 window.resize(500,500) 20 #添加三个子控件 - 窗口的右上角 21 close_btn = QPushButton(window) 22 close_btn.setText("关闭") #暂时以文本呈现 23 close_btn.resize(40,25) 24 close_btn_width = close_btn.width() 25 window_width = window.width() 26 close_btn_x = window_width - close_btn_width 27 close_btn_y = 0 28 close_btn.move(close_btn_x,close_btn_y) 30 max_btn = QPushButton(window) 31 max_btn.setText("最大") 32 max_btn.resize(40,25) 33 max_btn_x = close_btn_x -max_btn.width() 34 max_btn_y = 0 35 max_btn.move(max_btn_x,max_btn_y) 37 mini_btn = QPushButton(window) 38 mini_btn.setText("最小") 39 mini_btn.resize(40,25) 40 mini_btn_x = max_btn_x -mini_btn.width() 41 mini_btn_y = 0 42 mini_btn.move(mini_btn_x,mini_btn_y) 44 def close_window_slot(): 45 window.close() 47 def max_normal_window_slot(): # 最大化或者正常 48 if window.isMaximized(): 49 window.showNormal() 50 max_btn.setText("最大") 51 else: 52 window.showMaximized() 53 max_btn.setText("恢复") 55 def mini_window_slot(): 56 window.showMinimized() 58 close_btn.pressed.connect(close_window_slot) 59 max_btn.pressed.connect(max_normal_window_slot) 60 mini_btn.pressed.connect(mini_window_slot) 65 #展示控件 66 window.show() 68 #3,进入消息循环 69 sys.exit(app.exec_())实现三个按钮的功能
下面在继续做之前,先做个重构,重构指的就是重新改变代码的结构,一般都是 指封装起来,这样更方便修改维护和继续开发,
如下重构:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class Window(QWidget): 6 def __init__(self,*args,**kwargs): 7 super().__init__(*args,**kwargs) 8 self.setWindowOpacity(0.9) 9 self.setWindowTitle("顶层窗口操作案例") 10 self.resize(500,500) 11 self.setup_ui() 14 def setup_ui(self): 15 self.btn_width = 40 16 self.btn_height = 25 17 self.top_margin = 0 18 self.add_close_max_mini_contrl() 20 def add_close_max_mini_contrl(self): 21 #添加三个子控件 - 窗口的右上角 22 self.close_btn = QPushButton(self) 23 self.close_btn.setText("关闭") #暂时以文本呈现 24 self.close_btn.resize(self.btn_width,self.btn_height) 25 close_btn_width = self.close_btn.width() 26 window_width = self.width() 27 close_btn_x = window_width - close_btn_width 28 close_btn_y = self.top_margin 29 self.close_btn.move(close_btn_x,close_btn_y) 31 self.max_btn = QPushButton(self) 32 self.max_btn.setText("最大") 33 self.max_btn.resize(self.btn_width,self.btn_height) 34 max_btn_x = close_btn_x -self.max_btn.width() 35 max_btn_y = self.top_margin 36 self.max_btn.move(max_btn_x,max_btn_y) 38 self.mini_btn = QPushButton(self) 39 self.mini_btn.setText("最小") 40 self.mini_btn.resize(self.btn_width,self.btn_height) 41 mini_btn_x = max_btn_x -self.mini_btn.width() 42 mini_btn_y = self.top_margin 43 self.mini_btn.move(mini_btn_x,mini_btn_y) 44 #1,创建app 45 app = QApplication(sys.argv) 47 #2,控件的操作: 49 window = Window(flags=Qt.FramelessWindowHint) 51 def close_window_slot(): 52 window.close() 53 def max_normal_window_slot(): # 最大化或者正常 54 if window.isMaximized(): 55 window.showNormal() 56 window.max_btn.setText("最大") 57 else: 58 window.showMaximized() 59 window.max_btn.setText("恢复") 60 def mini_window_slot(): 61 window.showMinimized() 63 window.close_btn.pressed.connect(close_window_slot) 64 window.max_btn.pressed.connect(max_normal_window_slot) 65 window.mini_btn.pressed.connect(mini_window_slot) 68 #展示控件 69 window.show() 71 #3,进入消息循环 72 sys.exit(app.exec_())重构之后的代码
下面继续开发,但是要先解决bug ,因为这时按钮不会随着窗口的变大而改变位置。
要解决它。
分两步:监听窗口大小的变化,然后重新计算下按钮的位置。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class Window(QWidget): 6 def __init__(self,*args,**kwargs): 7 super().__init__(*args,**kwargs) 8 self.setWindowOpacity(0.9) 9 self.setWindowTitle("顶层窗口操作案例") 10 self.resize(500,500) 11 self.setup_ui() 14 def setup_ui(self): 15 self.btn_width = 40 16 self.btn_height = 25 17 self.top_margin = 0 18 self.add_close_max_mini_contrl() 20 def add_close_max_mini_contrl(self): 21 #添加三个子控件 - 窗口的右上角 22 self.close_btn = QPushButton(self) 23 self.close_btn.setText("关闭") #暂时以文本呈现 24 self.close_btn.resize(self.btn_width,self.btn_height) 26 self.max_btn = QPushButton(self) 27 self.max_btn.setText("最大") 28 self.max_btn.resize(self.btn_width,self.btn_height) 30 self.mini_btn = QPushButton(self) 31 self.mini_btn.setText("最小") 32 self.mini_btn.resize(self.btn_width,self.btn_height) 34 def resizeEvent(self, QResizeEvent): 35 print("窗口大小发生变化") 36 close_btn_width = self.close_btn.width() 37 window_width = self.width() 38 close_btn_x = window_width - close_btn_width 39 close_btn_y = self.top_margin 40 self.close_btn.move(close_btn_x,close_btn_y) 42 max_btn_x = close_btn_x -self.max_btn.width() 43 max_btn_y = self.top_margin 44 self.max_btn.move(max_btn_x,max_btn_y) 46 mini_btn_x = max_btn_x -self.mini_btn.width() 47 mini_btn_y = self.top_margin 48 self.mini_btn.move(mini_btn_x,mini_btn_y) 50 #1,创建app 51 app = QApplication(sys.argv) 53 #2,控件的操作: 55 window = Window(flags=Qt.FramelessWindowHint) 57 def close_window_slot(): 58 window.close() 59 def max_normal_window_slot(): # 最大化或者正常 60 if window.isMaximized(): 61 window.showNormal() 62 window.max_btn.setText("最大") 63 else: 64 window.showMaximized() 65 window.max_btn.setText("恢复") 66 def mini_window_slot(): 67 window.showMinimized() 69 window.close_btn.pressed.connect(close_window_slot) 70 window.max_btn.pressed.connect(max_normal_window_slot) 71 window.mini_btn.pressed.connect(mini_window_slot) 74 #展示控件 75 window.show() 77 #3,进入消息循环 78 sys.exit(app.exec_())View Code
第四个需求:支持拖拽用户去移动:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 5 class Window(QWidget): 6 def __init__(self,*args,**kwargs): 7 super().__init__(*args,**kwargs) 8 self.setWindowOpacity(0.5) 9 self.setWindowTitle("顶层窗口操作案例") 10 self.resize(500,500) 11 self.setup_ui() 12 self.move_flags = False # 主要是为了防止,鼠标追踪导致出现问题 13 # self.setMouseTracking(True) 14 def setup_ui(self): 15 self.btn_width = 40 16 self.btn_height = 25 17 self.top_margin = 0 18 self.add_close_max_mini_contrl() 19 def add_close_max_mini_contrl(self): 20 #添加三个子控件 - 窗口的右上角 21 self.close_btn = QPushButton(self) 22 self.close_btn.setText("关闭") #暂时以文本呈现 23 self.close_btn.resize(self.btn_width,self.btn_height) 25 self.max_btn = QPushButton(self) 26 self.max_btn.setText("最大") 27 self.max_btn.resize(self.btn_width,self.btn_height) 29 self.mini_btn = QPushButton(self) 30 self.mini_btn.setText("最小") 31 self.mini_btn.resize(self.btn_width,self.btn_height) 32 def resizeEvent(self, QResizeEvent): 33 print("窗口大小发生变化") 34 close_btn_width = self.close_btn.width() 35 window_width = self.width() 36 close_btn_x = window_width - close_btn_width 37 close_btn_y = self.top_margin 38 self.close_btn.move(close_btn_x,close_btn_y) 40 max_btn_x = close_btn_x -self.max_btn.width() 41 max_btn_y = self.top_margin 42 self.max_btn.move(max_btn_x,max_btn_y) 44 mini_btn_x = max_btn_x -self.mini_btn.width() 45 mini_btn_y = self.top_margin 46 self.mini_btn.move(mini_btn_x,mini_btn_y) 47 def mousePressEvent(self, event): 48 if event.button() == Qt.LeftButton: 49 self.move_flags = True 50 self.mouse_x = event.globalX() 51 self.mouse_y = event.globalY() 53 self.window_x = self.x() 54 self.window_y = self.y() 55 def mouseMoveEvent(self, event): 56 if self.move_flags: 57 self.move_x = event.globalX() -self.mouse_x 58 self.move_y = event.globalY() -self.mouse_y 59 self.move(self.window_x + self.move_x,self.window_y +self.move_y) 60 def mouseReleaseEvent(self, event): 61 self.move_flags = False 63 #1,创建app 64 app = QApplication(sys.argv) 66 #2,控件的操作: 68 window = Window(flags=Qt.FramelessWindowHint) 70 def close_window_slot(): 71 window.close() 72 def max_normal_window_slot(): # 最大化或者正常 73 if window.isMaximized(): 74 window.showNormal() 75 window.max_btn.setText("最大") 76 else: 77 window.showMaximized() 78 window.max_btn.setText("恢复") 79 def mini_window_slot(): 80 window.showMinimized() 82 window.close_btn.pressed.connect(close_window_slot) 83 window.max_btn.pressed.connect(max_normal_window_slot) 84 window.mini_btn.pressed.connect(mini_window_slot) 87 #展示控件 88 window.show() 90 #3,进入消息循环 91 sys.exit(app.exec_())
至于里面的图标,可以自己替代!
API之是否可用 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("交互状态") 14 window.resize(500,500) 17 btn = QPushButton(window) 18 btn.setText("按钮") 19 btn.pressed.connect(lambda :print("点击按钮")) 20 btn.setEnabled(False) #将它设置为不可用 21 print(btn.isEnabled()) # 查看它是否可用 24 #展示控件 25 window.show() 27 #3,进入消息循环 28 sys.exit(app.exec_())View Code
API之是否显示/隐藏 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def paintEvent(self, event): #窗口绘制事件 6 print("窗口被绘制了") 7 return super().paintEvent(event) 9 #1,创建app 10 app = QApplication(sys.argv) 12 #2,控件的操作: 13 #创建控件 14 window = Window() 16 #设置控件 17 window.setWindowTitle("交互状态") 18 window.resize(500,500) 20 #展示控件 21 window.show() # 如果此时没有window.show()就不会触发paintEvent() 了 23 #3,进入消息循环 24 sys.exit(app.exec_())window.show() 触发paintEvent()
其实show() 并不是最底层的函数,它只是调用 了下面的函数,setVisible(bool)
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def paintEvent(self, event): #窗口绘制事件 6 print("窗口被绘制了") 7 return super().paintEvent(event) 9 #1,创建app 10 app = QApplication(sys.argv) 12 #2,控件的操作: 13 #创建控件 14 window = Window() 16 #设置控件 17 window.setWindowTitle("交互状态") 18 window.resize(500,500) 20 #展示控件 21 # window.show() 22 window.setVisible(True) # 其实是window.show()调的它 24 #3,进入消息循环 25 sys.exit(app.exec_())底层的setVisible()
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def paintEvent(self, event): #窗口绘制事件 6 print("窗口被绘制了") 7 return super().paintEvent(event) 9 #1,创建app 10 app = QApplication(sys.argv) 12 #2,控件的操作: 13 #创建控件 14 window = Window() 16 #设置控件 17 window.setWindowTitle("交互状态") 18 window.resize(500,500) 20 #展示控件 21 # window.show() 22 # window.setVisible(True) 23 window.setHidden(False) #它也可以绘制window 26 #3,进入消息循环 27 sys.exit(app.exec_())用setHidden() 来绘制窗口
而且,绘制的时候肯定是先绘制顶层窗口,然后再绘制里面的子控件。下面来验证这一点:
肯定要监听子控件的绘制事件了,所以就要重写它的类的绘制方法了。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def paintEvent(self, event): #窗口绘制事件 6 print("窗口被绘制了") 7 return super().paintEvent(event) 9 class Btn(QPushButton): 10 def paintEvent(self, event): 11 print("里面控件被绘制了") 12 return super().paintEvent(event) 15 #1,创建app 16 app = QApplication(sys.argv) 18 #2,控件的操作: 19 #创建控件 20 window = Window() 22 #设置控件 23 window.setWindowTitle("交互状态") 24 window.resize(500,500) 26 btn = Btn(window) 27 btn.setText("按钮") 29 #展示控件 30 # window.show() 31 # window.setVisible(True) 32 window.setHidden(False) #它也可以绘制window 34 #3,进入消息循环 35 sys.exit(app.exec_()) 37 ''' 38 输出: 39 窗口被绘制了 40 里面控件被绘制了 41 '''View Code
现在的要求是点击按钮之后,将其隐藏:
这里指的隐藏是当重新绘制时,不绘制按钮而已。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def paintEvent(self, event): #窗口绘制事件 6 print("窗口被绘制了") 7 return super().paintEvent(event) 9 class Btn(QPushButton): 10 def paintEvent(self, event): 11 print("里面控件被绘制了") 12 return super().paintEvent(event) 15 #1,创建app 16 app = QApplication(sys.argv) 18 #2,控件的操作: 19 #创建控件 20 window = Window() 22 #设置控件 23 window.setWindowTitle("交互状态") 24 window.resize(500,500) 26 btn = Btn(window) 27 btn.setText("按钮") 28 btn.pressed.connect(lambda :btn.setVisible(False)) #点击之后,就会把它给隐藏了, 29 # 后面的绘制就不会显示它了,但是这个对象还是存在的 31 #展示控件 32 # window.show() 33 # window.setVisible(True) 34 window.setHidden(False) #它也可以绘制window 36 #3,进入消息循环 37 sys.exit(app.exec_())点击触发,给按钮设置隐藏标记,重新绘制时便不会绘制它了
注意事项:
有时候给setVisable 传True 也不一定能绘制成功,因为绘制都是按照先父控件,后子控件来的,所以,如果直接绘制子控件,这肯定是不行的。
如下证明:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("交换状态") 14 window.resize(500,500) 16 btn = QPushButton(window) 17 btn.setText("按钮") 19 btn.setVisible(True) #就算给子控件设置了 TRUE ,因为它的父控件没有被绘制,所以 它也没被绘制 22 #展示控件 23 # window.show() 25 #3,进入消息循环 26 sys.exit(app.exec_())View Code
isVisable 和 isHidden 的区别 :
isVisible 和 isHidden的区别:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 btn = QPushButton(window) 15 btn.move(100,100) 16 btn.setText("按钮") 18 window.show() #此时: 输出: False / True 20 print(btn.isHidden()) #是否被设置隐藏 21 print(btn.isVisible()) #到此是否可见 24 #展示控件 26 #3,进入消息循环 27 sys.exit(app.exec_())View Code
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 btn = QPushButton(window) 15 btn.move(100,100) 16 btn.setText("按钮") 20 print(btn.isHidden()) #是否被设置隐藏 21 print(btn.isVisible()) #到此是否可见 23 window.show() #此时: 输出: False / False 25 #展示控件 27 #3,进入消息循环 28 sys.exit(app.exec_())View Code
它强调的是如果父控件显示(不管是否真的显示父控件),它是否跟着显示。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 btn = QPushButton(window) 15 btn.move(100,100) 16 btn.setText("按钮") 18 # window.show() 20 #它这句话的意思是 如果 父控件显示的时候,子控件是否被显示 21 print(btn.isVisibleTo(window)) #就算是父控件不显示也不影响它 ,它只是如果父控件显示,它就显示 24 #展示控件 26 #3,进入消息循环 27 sys.exit(app.exec_())View Code
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 btn = QPushButton(window) 15 btn.move(100,100) 16 btn.setText("按钮") 18 # window.show() 20 btn.setVisible(False) # 如果加上它的话,下面的打印就要是False 了 22 #它这句话的意思是 如果 父控件显示的时候,子控件是否被显示 23 print(btn.isVisibleTo(window)) #就算是父控件不显示也不影响它 ,它只是如果父控件显示,它就显示 26 #展示控件 28 #3,进入消息循环 29 sys.exit(app.exec_())View Code
API之是否编辑 :
被编辑的时候显示文件名字带* 。
【*】 设置标题的时候,* 会被隐藏,直到设置setWindowModified(True) ,它会 被显示。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态[*]") 12 window.resize(500,500) 15 window.show() 17 #3,进入消息循环 18 sys.exit(app.exec_())看不到 *
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态[*]") 12 window.resize(500,500) 13 window.setWindowModified(True) # 此时* 就会被显示了,但是[] 不会被显示的 16 window.show() 18 #3,进入消息循环 19 sys.exit(app.exec_())
而且[* ] 可以放在字符串的任意位置,都是可以的。
而且,中括号内部只能放* ,其他符号都是不行的。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态[$]") 12 window.resize(500,500) 13 window.setWindowModified(True) # 此时* 就会被显示了,但是[] 不会被显示的 16 window.show() 18 #3,进入消息循环 19 sys.exit(app.exec_())其他字符不行
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态[*]") 12 window.resize(500,500) 13 window.setWindowModified(True) 14 print(window.isWindowModified()) # 查看是否被被编辑的状态 16 window.show() 18 #3,进入消息循环 19 sys.exit(app.exec_())查看当前窗口是否被处于被编辑的状态
API之是否活跃窗口 :
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 window2 = QWidget() 15 window2.show() 17 window.show() 19 print(window2.isActiveWindow()) # False 20 print(window.isActiveWindow()) # True 23 #3,进入消息循环 24 sys.exit(app.exec_())View Code
是否,某一个窗口在最上面,它 就是处于活跃状态呢?
不一定,如下代码(它只是显示在最上面)
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 window2 = QWidget() 15 window2.show() 17 window.show() 19 window2.raise_() #将window2 提到最外层 ,但是它仍然不是出于活跃的状态 21 print(window2.isActiveWindow()) # False 22 print(window.isActiveWindow()) # True 25 #3,进入消息循环 26 sys.exit(app.exec_())View Code
API之关闭 :
它其实是调用之前的setVisable() 方法。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 btn = QPushButton(window) 15 btn.setText("按钮") 17 #隐藏这个按钮的四种方法 18 # btn.setVisible(False) 19 # btn.setHidden(True) 20 # btn.hide() 21 btn.close() 23 window.show() 25 #3,进入消息循环 26 sys.exit(app.exec_())四种隐藏方法
一般情况下,它们四个都只是隐藏,而不释放控件。
需要注意的是,close() 是可以通过设置,隐藏的时候将它释放的
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 6 #2,控件的操作: 7 #创建控件 8 window = QWidget() 10 #设置控件 11 window.setWindowTitle("交互状态") 12 window.resize(500,500) 14 btn = QPushButton(window) 15 btn.setText("按钮") 16 btn.destroyed.connect(lambda :print("按钮被释放了")) 18 #隐藏这个按钮的四种方法 19 # btn.setVisible(False) 20 # btn.setHidden(True) 21 # btn.hide() 22 btn.setAttribute(Qt.WA_DeleteOnClose,True) # 这再调用close()就会释放按钮了 23 btn.close() 25 window.show() 27 #3,进入消息循环 28 sys.exit(app.exec_())这时就释放了
这里只需要记住,它只是结合close() 来用的,对于其他的三个隐藏方法,一般不可用。
交互状态的案例 :
首先 :创建文本框和按钮和标签:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("交互状态的的案例") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 #添加三个子控件 14 label = QLabel(self) 15 label.setText("标签") 16 label.move(50,50) 18 lineEdit = QLineEdit(self) 19 lineEdit.setText("文本框") 20 lineEdit.move(50,100) 22 btn = QPushButton(self) 23 btn.setText("登录") 24 btn.move(50,150) 28 if __name__ == '__main__': 29 app =QApplication(sys.argv) 31 window = Window() 33 window.show() 35 sys.exit(app.exec_())View Code
继续 :标签被隐藏,文本框和按钮被显示,按钮显示不可用。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("交互状态的的案例") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 #添加三个子控件 14 label = QLabel(self) 15 label.setText("标签") 16 label.move(50,50) 17 label.hide() #异常标签 19 lineEdit = QLineEdit(self) 20 lineEdit.setText("文本框") 21 lineEdit.move(50,100) 23 btn = QPushButton(self) 24 btn.setText("登录") 25 btn.move(50,150) 26 btn.setEnabled(False) #设置它不可用 29 if __name__ == '__main__': 30 app =QApplication(sys.argv) 32 window = Window() 34 window.show() 36 sys.exit(app.exec_())View Code
这里使用textChanged信号。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("交互状态的的案例") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 #添加三个子控件 14 label = QLabel(self) 15 label.setText("标签") 16 label.move(50,50) 17 label.hide() #异常标签 19 lineEdit = QLineEdit(self) 20 # lineEdit.setText("文本框") 21 lineEdit.move(50,100) 23 btn = QPushButton(self) 24 btn.setText("登录") 25 btn.move(50,150) 26 btn.setEnabled(False) #设置它不可用 28 def textChanged_slot(arg): 29 print("文本框内容改变了",arg) 31 lineEdit.textChanged.connect(textChanged_slot) 32 #而且此时,会给我们传递出一个参数,这个参数 33 # 就是每次改变之后文本框内剩余的内容,我们可以用槽函数来接收 34 if __name__ == '__main__': 35 app =QApplication(sys.argv) 37 window = Window() 39 window.show() 40 sys.exit(app.exec_())监听文本框的变化,并获取里面的内容
通过它就能实现有内容登录窗口可用,没内容则不可用。如下:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("交互状态的的案例") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 #添加三个子控件 14 label = QLabel(self) 15 label.setText("标签") 16 label.move(50,50) 17 label.hide() #异常标签 19 lineEdit = QLineEdit(self) 20 # lineEdit.setText("文本框") 21 lineEdit.move(50,100) 23 btn = QPushButton(self) 24 btn.setText("登录") 25 btn.move(50,150) 26 btn.setEnabled(False) #设置它不可用 28 def textChanged_slot(arg): 29 print("文本框内容改变了",arg) 30 if len(arg): 31 btn.setEnabled(True) 32 else: 33 btn.setEnabled(False) 35 lineEdit.textChanged.connect(textChanged_slot) 36 #而且此时,会给我们传递出一个参数,这个参数 37 # 就是每次改变之后文本框内剩余的内容,我们可以用槽函数来接收 38 if __name__ == '__main__': 39 app =QApplication(sys.argv) 41 window = Window() 43 window.show() 44 sys.exit(app.exec_())View Code
这里的判断可以被优化:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("交互状态的的案例") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 #添加三个子控件 14 label = QLabel(self) 15 label.setText("标签") 16 label.move(50,50) 17 label.hide() #异常标签 19 lineEdit = QLineEdit(self) 20 # lineEdit.setText("文本框") 21 lineEdit.move(50,100) 23 btn = QPushButton(self) 24 btn.setText("登录") 25 btn.move(50,150) 26 btn.setEnabled(False) #设置它不可用 28 def textChanged_slot(arg): 29 print("文本框内容改变了",arg) 30 # if len(arg): 31 # btn.setEnabled(True) 32 # else: 33 # btn.setEnabled(False) 34 btn.setEnabled(len(arg)) 36 lineEdit.textChanged.connect(textChanged_slot) 37 #而且此时,会给我们传递出一个参数,这个参数 38 # 就是每次改变之后文本框内剩余的内容,我们可以用槽函数来接收 39 if __name__ == '__main__': 40 app =QApplication(sys.argv) 42 window = Window() 44 window.show() 45 sys.exit(app.exec_())
当输入的内容为Zcb 的时候,已经隐藏的标签显示登录成功。
这分两步:
1,获取文本框的内容。
2,判定是否是Zcb
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def __init__(self): 6 super().__init__() 7 self.setWindowTitle("交互状态的的案例") 8 self.resize(400,400) 9 self.set_ui() 12 def set_ui(self): 13 #添加三个子控件 14 label = QLabel(self) 15 label.setText("标签") 16 label.move(50,50) 17 label.hide() #隐藏标签 20 lineEdit = QLineEdit(self) 21 # lineEdit.setText("文本框") 22 lineEdit.move(50,100) 24 btn = QPushButton(self) 25 btn.setText("登录") 26 btn.move(50,150) 27 btn.setEnabled(False) #设置它不可用 29 def textChanged_slot(arg): 30 print("文本框内容改变了",arg) 31 # if len(arg): 32 # btn.setEnabled(True) 33 # else: 34 # btn.setEnabled(False) 35 btn.setEnabled(len(arg)) 37 lineEdit.textChanged.connect(textChanged_slot) 39 def check_slot(): 40 #1,获取文本框的内容 41 content = lineEdit.text() 42 #2,判断 43 label.show() 44 if content == "Zcb": 45 label.setText("登录成功!") 46 else: 47 label.setText("登录失败!") 49 label.adjustSize() # 注:它一定要放在设置文本的后面。 51 btn.pressed.connect(check_slot) #用信号clicked 也可以 53 if __name__ == '__main__': 54 app =QApplication(sys.argv) 56 window = Window() 58 window.show() 59 sys.exit(app.exec_())
API之状态提示:
它一般是在窗口的下方的一个横条。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("信息提示") 14 window.resize(500,500) 16 #当鼠标停留在窗口控件之后,在状态栏展示提示信息,但是前提是要有状态栏 17 window.setStatusTip("这时窗口") 21 #展示控件 22 window.show() 24 #3,进入消息循环 25 sys.exit(app.exec_())此时没有提示文本,因为没有状态栏
我们这里换个控件类别,换成个组合控件。换QWidget 为 QMainWindow .
所有组合控件,就是有很多常用的部分,例如,菜单栏,编辑区域,有状态栏。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 9 window = QMainWindow() #组合控件 12 #设置控件 13 window.setWindowTitle("信息提示") 14 window.resize(500,500) 16 #当鼠标停留在窗口控件之后,在状态栏展示提示信息,但是前提是要有状态栏 17 window.setStatusTip("这是窗口") 21 #展示控件 22 window.show() 24 #3,进入消息循环 25 sys.exit(app.exec_())这时并没有任何现象,因为QMainWindow 是采用懒加载的方式
所谓的懒加载指的是,当用的时候才会加载上去。
这时就可以看到当鼠标放上去的时候的提示信息了。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 9 window = QMainWindow() #组合控件 10 window.statusBar() 12 #设置控件 13 window.setWindowTitle("信息提示") 14 window.resize(500,500) 16 #当鼠标停留在窗口控件之后,在状态栏展示提示信息,但是前提是要有状态栏 17 window.setStatusTip("这是窗口") 20 #展示控件 21 window.show() 23 #3,进入消息循环 24 sys.exit(app.exec_())View Code
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 9 window = QMainWindow() #组合控件 10 window.statusBar() 12 #设置控件 13 window.setWindowTitle("信息提示") 14 window.resize(500,500) 16 #当鼠标停留在窗口控件之后,在状态栏展示提示信息,但是前提是要有状态栏 17 window.setStatusTip("这是窗口") 19 print(window.statusTip()) #获取提示信息 21 #展示控件 22 window.show() 24 #3,进入消息循环 25 sys.exit(app.exec_())获取提示信息
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 9 window = QMainWindow() #组合控件 10 window.statusBar() 12 #设置控件 13 window.setWindowTitle("信息提示") 14 window.resize(500,500) 16 #当鼠标停留在窗口控件之后,在状态栏展示提示信息,但是前提是要有状态栏 17 window.setStatusTip("这是窗口") 19 label = QLabel(window) 20 label.setText("hello world") 21 label.setStatusTip("这是标签") 24 #展示控件 25 window.show() 27 #3,进入消息循环 28 sys.exit(app.exec_())给标签添加状态提示
API之工具提示 :
17 label = QLabel(window) 18 label.setText( " hello world " ) 19 label.setToolTip( " 这是个标签 " ) # 将鼠标停在上面的时候,在旁边会有提示 20 print (label.toolTip()) # 获取工具提示 22 # 展示控件 23 window.show() 25 # 3,进入消息循环 26 sys.exit(app.exec_())注意:工具提示的展示 时间是有限的,具体时长我们可以控制。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 9 window = QMainWindow() #组合控件 10 window.statusBar() 12 #设置控件 13 window.setWindowTitle("信息提示") 14 window.resize(500,500) 17 label = QLabel(window) 18 label.setText("hello world") 19 label.setToolTip("这是个标签") #将鼠标停在上面的时候,在旁边会有提示 20 print(label.toolTip()) #获取工具提示 22 label.setToolTipDuration(2000) # 显示2s 25 #展示控件 26 window.show() 28 #3,进入消息循环 29 sys.exit(app.exec_())控制显示时长
API之这是啥提示:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 9 window = QMainWindow() #组合控件 10 window.statusBar() 11 window.setWindowFlags(Qt.WindowContextHelpButtonHint) #换个带问号的窗口样式 14 #设置控件 15 window.setWindowTitle("信息提示") 16 window.resize(500,500) 19 label = QLabel(window) 20 label.setText("hello world") 22 label.setToolTipDuration(2000) # 显示2s 23 label.setWhatsThis("这是啥,这是帮助信息") #它的使用方法是:先点? ,然后再带这个标签 24 print(label.whatsThis()) 26 #展示控件 27 window.show() 29 #3,进入消息循环 30 sys.exit(app.exec_())点? 号,之后再点控件
单个控件的角度:
API 之 setFocus():
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("焦点控制") 14 window.resize(500,500) 16 lineEdit1 = QLineEdit(window) 17 lineEdit1.move(50,50) 19 lineEdit2 = QLineEdit(window) 20 lineEdit2.move(100,100) 21 lineEdit2.setFocus() #先让第二个获取焦点 24 lineEdit3 = QLineEdit(window) 25 lineEdit3.move(150,150) 27 #展示控件 28 window.show() 30 #3,进入消息循环 31 sys.exit(app.exec_())用setFocus() 获取焦点。
API 之 setFocusPolicy(Policy) :
设置策略,(获取焦点的策略)
API之clearFocus() :
清除焦点,此时tab 和点击都不行了,只能通过setFocus()代码来实现。
父控件的角度 :
如何获取当前窗口中,所有子控件中获取焦点的那个控件:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 3 #1,创建app 4 app = QApplication(sys.argv) 7 #2,控件的操作: 8 #创建控件 9 window = QWidget() 12 #设置控件 13 window.setWindowTitle("焦点控制") 14 window.resize(500,500) 16 lineEdit1 = QLineEdit(window) 17 lineEdit1.move(50,50) 19 lineEdit2 = QLineEdit(window) 20 lineEdit2.move(100,100) 22 lineEdit3 = QLineEdit(window) 23 lineEdit3.move(150,150) 25 # print(window.focusWidget()) # 获取当前窗口的获取焦点的子控件,此时不行 为None 28 #展示控件 29 window.show() 31 print(window.focusWidget()) # 获取当前窗口的获取焦点的子控件,此时也不行 None 33 #这说明因为获取焦点是后面的事情, 35 #3,进入消息循环 36 sys.exit(app.exec_())View Code
这时是不行的,它说明焦点是后面获取的。
下面验证上述观点:
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, event): 6 print(self.focusWidget()) #点击时获取它的子控件中获取焦点的那个 8 #1,创建app 9 app = QApplication(sys.argv) 12 #2,控件的操作: 13 #创建控件 14 window = Window() 17 #设置控件 18 window.setWindowTitle("焦点控制") 19 window.resize(500,500) 21 lineEdit1 = QLineEdit(window) 22 lineEdit1.move(50,50) 24 lineEdit2 = QLineEdit(window) 25 lineEdit2.move(100,100) 27 lineEdit3 = QLineEdit(window) 28 lineEdit3.move(150,150) 31 #展示控件 32 window.show() 36 #3,进入消息循环 37 sys.exit(app.exec_())这时就不打印出None 了
同时它也说明,焦点是在show() 的后面加上去的。
4 class Window(QWidget): 5 def mousePressEvent(self, event): 6 # self.focusNextChild() #在子控件中切换焦点 7 # self.focusPreviousChild() #反序 8 self.focusNextPrevChild(True) # True 是前面的Next false 是后面的Prev 10 # 1,创建app 11 app = QApplication(sys.argv) 14 # 2,控件的操作: 15 # 创建控件 16 window = Window() 19 # 设置控件 20 window.setWindowTitle( " 焦点控制 " ) 21 window.resize(500,500 ) 23 lineEdit1 = QLineEdit(window) 24 lineEdit1.move(50,50 ) 26 lineEdit2 = QLineEdit(window) 27 lineEdit2.move(100,100 ) 29 lineEdit3 = QLineEdit(window) 30 lineEdit3.move(150,150 ) 33 # 展示控件 34 window.show() 38 # 3,进入消息循环 39 sys.exit(app.exec_()) 在子控件中切换焦点它是个静态方法,用类对象去调用。
1 from PyQt5.Qt import * #刚开始学习可以这样一下导入 2 import sys 4 class Window(QWidget): 5 def mousePressEvent(self, event): 6 # self.focusNextChild() #在子控件中切换焦点 7 # self.focusPreviousChild() #反序 8 self.focusNextPrevChild(True) #True 是前面的Next false 是后面的Prev 10 #1,创建app 11 app = QApplication(sys.argv) 14 #2,控件的操作: 15 #创建控件 16 window = Window() 19 #设置控件 20 window.setWindowTitle("焦点控制") 21 window.resize(500,500) 23 lineEdit1 = QLineEdit(window) 24 lineEdit1.move(50,50) 26 lineEdit2 = QLineEdit(window) 27 lineEdit2.move(100,100) 29 lineEdit3 = QLineEdit(window) 30 lineEdit3.move(150,150) 33 Window.setTabOrder(lineEdit1,lineEdit3) 34 Window.setTabOrder(lineEdit3,lineEdit2) 35 #tab 切换 1 3 2 38 #展示控件 39 window.show() 43 #3,进入消息循环 44 sys.exit(app.exec_())Tab 切换 顺序是1 3 2
QWidget结束,见下一个QAbstractButton: https://www.cnblogs.com/zach0812/p/11360978.html