侦测与控制视窗
这篇教学如何在 PyQt5 侦测视窗的位置、尺寸与缩放行为,并透过对应的方法,进一步控制视窗的尺寸和位置,最后还会介绍视窗相对应的事件,当视窗事件发生时,就能进行对应的动作。
快速导览:
- PyQt6 版本参考:PyQt6 教学 - 侦测与控制视窗
- 因为 Google Colab 不支援 PyQt5,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda )。
侦测视窗
在 PyQt5 里建立最底层的视窗 Widget 元件之后,只要套用对应的侦测方法,就可以侦测视窗的属性,下方列出常用的侦测方法:
| 方法 | 说明 |
|---|---|
| x() | 视窗在屏幕里的 x 座标。 |
| y() | 视窗在屏幕里的 y 座标。 |
| width() | 视窗的宽度。 |
| height() | 视窗的高度。 |
| windowTitle() | 视窗的标题。 |
以下方的程序码执行后,会打开一个空白的视窗,并使用 QLabel 印出视窗的相关信息。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
label = QtWidgets.QLabel(Form)
label.setGeometry(10,10,200,200)
label.setText(f'''
x: {Form.x()}
y: {Form.y()}
w: {Form.width()}
h: {Form.height()}
t: {Form.windowTitle()}
''')
Form.show()
sys.exit(app.exec_())
控制视窗
在 PyQt5 里建立最底层的视窗 Widget 元件之后,只要套用对应的控制方法,就可以控制与设定视窗,下方列出常用的控制方法:
| 方法 | 参数 | 说明 |
|---|---|---|
| setWindowTitle() | str | 视窗标题。 |
| resize() | width(int), height(int) | 改变视窗尺寸。 |
| move() | x(int), y(int) | 设定视窗位置。 |
| setGeometry() | x(int), y(int), width(int), height(int) | 设定视窗位置与尺寸。 |
| setFixedWidth() | hwidth(int) | 固定视窗宽度。 |
| setFixedHeight() | height(int) | 固定视窗高度。 |
| setFixedSize() | width(int), height(int) | 固定视窗尺寸。 |
| showMinimized() | 视窗最小化。 | |
| showMaximized() | 视窗最大化。 | |
| showFullscreen() | 视窗全屏幕。 | |
| showNormal() | 视窗恢复原本尺寸。 |
下方的例子执行后,会建立三颗按钮,并将三颗按钮的点击行为绑定 lambda 匿名函数,使得点击按钮时会进行最大化视窗、恢复视窗以及移动视窗的效果。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
btn1 = QtWidgets.QPushButton(Form)
btn1.setGeometry(10,10,100,30)
btn1.setText('最大化')
btn1.clicked.connect(lambda: Form.showMaximized()) # 最大化
btn2 = QtWidgets.QPushButton(Form)
btn2.setGeometry(110,10,100,30)
btn2.setText('恢復大小')
btn2.clicked.connect(lambda: Form.showNormal()) # 恢復原本大小
btn3 = QtWidgets.QPushButton(Form)
btn3.setGeometry(10,50,100,30)
btn3.setText('移動視窗')
btn3.clicked.connect(lambda: Form.move(100, 100)) # 移動到 (100, 100)
Form.show()
sys.exit(app.exec_())
视窗置中、取得屏幕信息
在控制视窗位置与尺寸时,有时需要获取电脑屏幕的信息,使用 QtWidgets.QApplication.desktop() 之后,就能透过下列的方法取得电脑屏幕的尺寸。
| 方法 | 说明 |
|---|---|
| width() | 电脑屏幕的宽度。 |
| height() | 电脑屏幕的高度。 |
下方的程序码执行后,会根据电脑屏幕的尺寸,以及视窗的尺寸,换算出视窗置中的座标 ( 座标必须为整数 ),进而让视窗置中显示。
from PyQt5 import QtWidgets,
import sys
app = QtWidgets.QApplication(sys.argv)
screen = QtWidgets.QApplication.desktop()
screen_w = screen.width() # 電腦螢幕寬度
screen_h = screen.height() # 電腦螢幕高度
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
Form_w = Form.width() # 視窗寬度
Form_h = Form.height() # 視窗高度
new_x = int((screen_w - Form_w)/2) # 計算後的 x 座標
new_y = int((screen_h - Form_h)/2) # 計算後的 y 座標
Form.move(new_x, new_y) # 移動視窗
Form.show()
sys.exit(app.exec_())
视窗事件
下方列出常用的视窗事件,可以在视窗显示、关闭、移动、缩放或焦点改变时触发。
| 事件 | 说明 |
|---|---|
| showEvent | 打开视窗。 |
| closeEvent | 关闭视窗。 |
| moveEvent | 移动视窗。 |
| resizeEvent | 视窗尺寸改变。 |
| focusInEvent | 视窗为焦点 ( 需要先使用 setFocus() 方法 )。 |
| focusOutEvent | 视窗失去焦点,用户操作其他视窗 ( 需要先使用 setFocus() 方法 )。 |
下方的程序码执行后,用鼠标改变视窗大小或位置,就能看见后台印出对应的事件内容。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def close(self):
print('close!!')
def move(self):
print('move...')
def resize(self):
print('resize')
def show(self):
print('show')
def focusIn(self):
print('focus in')
def focusOut(self):
print('focus out')
Form.closeEvent = close
Form.moveEvent = move
Form.resizeEvent = resize
Form.showEvent = show
Form.setFocus()
Form.focusInEvent = focusIn
Form.focusOutEvent = focusOut
Form.show()
sys.exit(app.exec_())
改用 class 的写法
上方的程序码,亦可改用 class 的写法表示,注意参数需要有 event。
from PyQt5 import QtWidgets
from PyQt5.QtGui import QKeySequence
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.closeEvent = self.f_close
self.moveEvent = self.f_move
self.resizeEvent = self.f_resize
self.showEvent = self.f_show
self.setFocus()
self.focusInEvent = self.f_focusIn
self.focusOutEvent = self.f_focusOut
def f_close(self, event):
print('close!!')
def f_move(self, event):
print('move...')
def f_resize(self, event):
print('resize')
def f_show(self, event):
print('show')
def f_focusIn(self, event):
print('focus in')
def f_focusOut(self, event):
print('focus out')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec_())
微信扫码关注
抖音扫码关注