第十六章 窗口坐标
《快速掌握PyQt5》专栏已整理成书出版,书名为《PyQt编程快速上手》,详情请见该链接。感谢大家一直以来的支持!祝大家PyQt用得越来越顺!
这一章我们来了解一下PyQt5中的坐标体系。
16.1 理解坐标体系
请记住一点:不管从显示屏屏幕还是程序窗口来看,左上角都为原点(0, 0),向右为x轴正向,向下为y轴正向。
针对程序窗口的坐标系:
针对窗口中控件的坐标系:
接着我们来看一下Qt官方文档上关于窗口坐标的一张图:
我们可以把窗口分成三块:标题栏、边框和客户区,这样进行分割后我们才能很好地理解不同的方法所获取到的坐标有什么不同。
以上方法理解如下:
- x()——得到窗口左上角在显示屏屏幕上的x坐标;
- y()——得到窗口左上角在显示屏屏幕上的y坐标;
- pos()——得到窗口左上角在显示屏屏幕上的x和y坐标,类型为QPoint();
- geometry().x()——得到客户区左上角在显示屏屏幕上的x坐标;
- geometry().y()——得到客户区左上角在显示屏屏幕上的y坐标;
- geometry()——得到客户区左上角在显示屏屏幕上的x和y坐标,以及客户区的宽度和长度,类型为QRect();
- width()——得到客户区的宽度;
- height()——得到客户区的长度;
- geometry().width()——得到客户区的宽度;
- geometry().height()——得到客户区的长度;
- frameGeometry().width()——得到窗口的宽度;
- frameGeometry().height()——得到窗口的长度;
补充:
- frameGeometry().x()——即x(),得到窗口左上角在显示屏屏幕上的x坐标;
- frameGeometry().y()——即y(),得到窗口左上角在显示屏屏幕上的y坐标;
- frameGeometry()——即pos(),得到窗口左上角在显示屏屏幕上的x和y坐标,以及窗口的宽度和长度,类型为QRect();
注:通过geometry()和frameGeometry()获取坐标的相关方法需要在窗口调用show()方法之后才能使用,否则获取的将是无用数据。
现在我们来实例化一个QWidget窗口,并调用各个方法打印下它的坐标:
import sys
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = QWidget()
widget.resize(200, 200) # 1
widget.move(100, 100) # 2
# widget.setGeometry(100, 100, 200, 200) # 3
widget.show()
print('-----------------x(), y(), pos()-----------------')
print(widget.x())
print(widget.y())
print(widget.pos())
print('-----------------width(), height()-----------------')
print(widget.width())
print(widget.height())
print('-----------------geometry().x(), geometry.y(), geometry()-----------------')
print(widget.geometry().x())
print(widget.geometry().y())
print(widget.geometry())
print('-----------------geometry.width(), geometry().height()-----------------')
print(widget.geometry().width())
print(widget.geometry().height())
print('-----------------frameGeometry().x(), frameGeometry().y(), frameGeometry(), '
'frameGeometry().width(), frameGeometry().height()-----------------')
print(widget.frameGeometry().x())
print(widget.frameGeometry().y())
print(widget.frameGeometry())
print(widget.frameGeometry().width())
print(widget.frameGeometry().height())
sys.exit(app.exec_())
1. 通过resize(200, 200)方法来设置窗口大小;
2. 通过move(100, 100)方法将窗口移到屏幕坐标为(100, 100)的位置上;
3. 以上两个方法可以单单通过setGeometry(x, y, width, height)方法来完成。
以下是在MacOS系统上的输出结果:
-----------------x(), y(), pos()-----------------
100
100
PyQt5.QtCore.QPoint(100, 100)
-----------------width(), height()-----------------
200
200
-----------------geometry().x(), geometry.y(), geometry()-----------------
100
122
PyQt5.QtCore.QRect(100, 122, 200, 200)
-----------------geometry.width(), geometry().height()-----------------
200
200
-----------------frameGeometry().x(), frameGeometry().y(), frameGeometry(), frameGeometry().width(), frameGeometry().height()-----------------
100
100
PyQt5.QtCore.QRect(100, 100, 200, 222)
200
222
以下是在Windows系统上(win7)的输出结果:
-----------------x(), y(), pos()-----------------
100
100
PyQt5.QtCore.QPoint(100, 100)
-----------------width(), height()-----------------
200
200
-----------------geometry().x(), geometry.y(), geometry()-----------------
108
130
PyQt5.QtCore.QRect(108, 130, 200, 200)
-----------------geometry.width(), geometry().height()-----------------
200
200
-----------------frameGeometry().x(), frameGeometry().y(), frameGeometry(), frameGeometry().width(), frameGeometry().height()-----------------
100
100
PyQt5.QtCore.QRect(100, 100, 216, 238)
216
238
以下是在Linux(Ubuntu)上的输出结果:
-----------------x(), y(), pos()-----------------
100
100
PyQt5.QtCore.QPoint(100, 100)
-----------------width(), height()-----------------
200
200
-----------------geometry().x(), geometry.y(), geometry()-----------------
100
100
PyQt5.QtCore.QRect(100, 100, 200, 200)
-----------------geometry.width(), geometry().height()-----------------
200
200
-----------------frameGeometry().x(), frameGeometry().y(), frameGeometry(), frameGeometry().width(), frameGeometry().height()-----------------
100
100
PyQt5.QtCore.QRect(100, 100, 200, 200)
200
200
我们发现由于显示的窗口样式不同,个别坐标或者大小显示的数值也不相同。
Mac上的窗口样式:
Windows(Win7)上的窗口样式:
Linux(Ubuntu)上的窗口样式:
16.2 小结
1. 窗口可分为标题栏、边框和客户区三个部分。但是从Linux系统上的输出结果来看,在Linux上的窗口并没有将窗口划分为是那个部分,而是始终保持一个整体。Mac上的窗口也没有边框这一部分;
2. move(x, y)和resize(width, height)方法的功能可以单单通过setGeometry(x, y, width, height)方法来实现(我们也可以用该方法实现窗口中各控件的布局)。