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