《Qt編程的藝術》——5.1 手動佈局

在傳統的GUI設計中,每個控件(Widget)都要手動地綁定在窗口之上的一個點上(也就是說,這個控件被指定成了給定GUI元素的父對象),同時還要指定這個控件的高度和寬度。作爲所有圖形元素的基礎類,QWidget類提供了setGeometry()方法。這個方法需要4個整型參數:前兩個參數指定相對於父控件(parent widget)的x、y座標,後面兩個參數指定控件的高度和寬度。在目前情況下,父控件的最終顯示大小可能還未定。
 
作爲一個例子,我們可以看一下一個繼承自QWidget的窗口(如圖5.1):

// manually/window.cpp
#include <QtGui>
#include "window.h"
Window::Window(QWidget *parent) : QWidget(parent)
{
    setFixedSize(640,480);
    QTextEdit *txt =new QTextEdit(this);
    txt->setGeometry(20, 20, 600,400);
    QPushButton *btn=new QPushButton(tr("&Close"),this);
    btn->setGeometry(520,440,100, 20);
}


setFixedSize()方法指示窗口接收一個固定的再也不能改變的大小。之後,我們放置了一個編輯窗口(一個QTextEdit控件)和一個按鈕。
 
從這些setGeometry()調用中可以明顯地看出,要猜出這些控件的正確放置位置,是相當困難的。用這種方式建立佈局,就是不停地選擇候選數值、編譯、然後調整數值,來增強顯示效果,就是這樣一種循環。如果控件(widget)或對話框(dialog)要做出調整的話,這種方式顯得太笨拙了:舉例說,如果你想在佈局的中間位置添加一個新的按鈕,所有放在它下面的元素的位置都要做出調整。
 
現在,也許有人會說,在實踐中這不是問題,因爲Qt Designer大力簡化了上述位置調整的工作。但是我要說,任何GUI Designer都不能解決所有問題,除非採用自動佈局。
 
無法解決的所有問題中的一個就是,當一個控件(widget)變大或縮小時,它要做出相應的變化:在一個不靈活的佈局中且沒有附加的幫助的情況下,這些元素——比如上例中的編輯窗口(editor window)——總是保持相同的大小。儘管它可能會根據屏幕大小做出一定適應,或者向用戶提供選項,來選擇其大小,但這仍然是個問題。
 
要讓對話框的大小可以靈活調整,我們可以將setFixSize()調用換成resize()方法,這個方法也需要兩個整型參數,或者一個QSize參數。這個方法只調整大小,卻並不鎖定它。用戶現在可以通過鼠標改變對話框的大小,儘管窗口裏的控件仍保持原來的位置、大小不變。
 
作爲一種選擇,你可以重新實現QWidget的resizeEvent()方法:當控件大小改變時,Qt總是調用這個方法。你可以編代碼,在每次resizeEvent調用時,計算出窗口元素的新的大小和位置。但是在大多數情況下,這個步驟都太麻煩了,還需要手工計算控件(widget)的比例。
 
除此之外,重新實現resizeEvent()還會在國際化上遇到一個特別的問題:在地區化的軟件上,一個標籤控件(Label)的大小取決於它顯示的語言。一個英語中叫Close的按鈕,若按照德語來翻譯,叫做Schließen,變長了不少。這樣,除非有預先的解決方案,否則多餘的部分只能被切掉了。
 
如果我們採用這種方案,最終,我們只能打補丁。要根本解決潛在的問題,我們不能避免使用自動佈局。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章