Qt使用統一的坐標系統來定位窗口部件的位置和大小。

以屏幕的左上角為原點即(0, 0)點,從左向右為x軸正向,從上向下為y軸正向,這整個屏幕的坐標系統就用來定位頂層窗口;
此外,窗口內部也有自己的坐標系統,它依然以左上角作為原點,從左向右為x軸正向,從上向下為y軸正向,原點、x軸、y軸圍成的區域叫做Client Area(客戶區),在客戶區的周圍則是標題欄(Windows Title)和邊框(Frame)。
有了Qt坐標系統的一些基礎概念,那麼具體該如何來進行窗口部件的定位呢?QWidget類,也就是所有窗口組件的父類都提供了成員函數來在坐標系統中進行定位。

從上圖可以看出這些成員函數有三類:
——QWidget直接提供的成員函數:x()、y()獲得窗口左上角的坐標,width()、height()獲得客戶區的寬和高
——QWidget的geometry()提供的成員函數:x()、y()獲得客戶區左上角的坐標,width()、height()獲得客戶區的寬和高
——QWidget的frameGeometry()提供的成員函數:x()、y()獲得窗口左上角的坐標,width()、height()獲得包含客戶區、標題欄和邊框在內的整個窗口的寬和高
測試程序:
1 #ifndef WIDGET_H
2 #define WIDGET_H
3
4 #include <QtGui/QWidget>
5
6 class Widget : public QWidget
7 {
8 Q_OBJECT
9 public:
10 Widget();
11 ~Widget();
12 };
13
14 #endif // WIDGET_H
1 #include "Widget.h"
2
3 Widget::Widget()
4 {
5
6 }
7
8 Widget::~Widget()
9 {
10
11 }
1 #include <QtGui/QApplication>
2 #include <QPushButton>
3 #include <QDebug>
4 #include "Widget.h"
5
6 int main(int argc, char *argv[])
7 {
8 QApplication a(argc, argv);
9 Widget w;
10 QPushButton b(&w);
11
12 b.setText("Button");
13 b.resize(100, 40);
14 b.move(20, 20); //以Client Area左上角為(0, 0)點
15
16 w.resize(800, 500); //不同操作系統可能對窗口最小寬度有規定,若設置寬度小於規定值,則會以規定值進行顯示
17 w.move(200, 200); //以屏幕左上角為(0, 0)點
18 w.show();
19
20 qDebug() << "QWidget";
21 qDebug() << w.x();
22 qDebug() << w.y();
23 qDebug() << w.width();
24 qDebug() << w.height();
25
26 qDebug() << "QWidget::geometry";
27 qDebug() << w.geometry().x();
28 qDebug() << w.geometry().y();
29 qDebug() << w.geometry().width();
30 qDebug() << w.geometry().height();
31
32 qDebug() << "QWidget::frameGeometry";
33 qDebug() << w.frameGeometry().x();
34 qDebug() << w.frameGeometry().y();
35 qDebug() << w.frameGeometry().width();
36 qDebug() << w.frameGeometry().height();
37
38 return a.exec();
39 }
輸出結果:

在上面這個程序中,有兩點需要補充說明:
第一,geometry()和frameGeometry()提供的坐標函數必須在show()調用之後使用才有效,否則會得到無效的數據;
第二,不同的操作系統可能對窗口的最小寬度有所規定,在使用void resize(int width, int height)設置頂層窗口大小時,若width小於規定的最小寬度,則會以規定的最小寬度進行顯示,經個人測試,這個最小寬度對於win7 x64為116,對於win8.1 x64為160,因此在編寫跨平台的程序時,有時候可能需要考慮到這個特性。
說到跨平台,這裡還有一個問題:在不同的平台中(如windows和linux),窗口的外觀式樣是不一樣的,這種差異體現在邊框的寬度不一樣、標題欄的寬度和高度不一樣。Qt之所以在坐標系統相關的函數中,提供三組不同的函數出來,正是為了實現跨平台。
因為圖形用戶界面一般都是以像素為單位進行定位的,因此若想以跨平台的方式精確定位,就必須考慮到不同平台標題欄和邊框的大小差異,QWidget圍繞標題欄和邊框提供的三組既相互聯系又相互區別的函數,就可以解決這個問題。