添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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 16 window.show() 20 # 3,进入消息循环 21 sys.exit(app.exec_()) QWidget 的初始化函数的参数parent

当一个控件没有父控件的时候,它会被包装成一个框架(有标题栏啊,等等......)

但是,我们可以通过init函数中第二个参数flags 来设置的, 后面再讲(待放链接)

(二):QWidget控件之大小位置:

关于控件的坐标系统:

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

(三):QWidget控件之最大和最小尺寸:

直接上案例(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_())
一旦限制之后,通过代码也是无法修改的

(四):QWidget控件之内容边距:

内容区域:(文本区域)

内容区域默认是整个标签,可以通过获取内容区域来查看:

 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 '''
查看内容边距的设置

(五):QWidget控件之事件消息:

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() 来设置只能鼠标左键按下才能移动

(六):QWidget控件之鼠标相关:

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_())
设置鼠标跟踪
#设置鼠标跟踪,这样鼠标一进去就会调用它的方法mouseMoveEvent() 了

下面看下传来的参数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_())
案例(版本二 采用封装)

(七):QWidget控件之父子关系:

 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() 来查看一个位置是否有子控件
利用parentWidget() 查看父控件
 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_())
不通过自定义标签类照样解决问题

(八):QWidget控件之层级控制:

它主要的作用就是调整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_())
点谁,谁出现在最上层

(九):QWidget控件之顶层窗口相关:

如果一个控件没有父控件,那么它就是顶层窗口。

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_())

至于里面的图标,可以自己替代!

(十):QWidget控件之交互状态:

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_())

(十一):QWidget控件之信息提示:

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_())
点? 号,之后再点控件

(十二):QWidget控件之焦点控制:

单个控件的角度:

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控件之其他:

四:QWidget 信号:

QWidget结束,见下一个QAbstractButton: https://www.cnblogs.com/zach0812/p/11360978.html