QT sizeHint 及 Policy的用法


    Qt 中的 sizeHint 屬性,sizeHint() 如何使用?
    Qt 中的 minimumSizeHint 屬性,minimumSizeHint() 如何使用?
    Qt 中的 sizePolicy 屬性,setSizePolicy()、sizePolicy()如何使用?

        之前一直對這幾個屬性搞不清楚,前幾天仔仔細細地看了文檔解釋並做了一些測試,現在來歸納一下:

        首先我們得知道這幾個屬性保存的值是什麼,它們分別是用來幹什麼的。

      sizeHint
    [From Qt Doc: This property holds the recommended size for the widget. If the value of this property is an invalid size, no size is recommended. The default implementation of sizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise. ] 這個屬性所保存的 QSize 類型的值是一個被推薦給窗口或其它組件(爲了方便下面統稱爲widget)的尺寸,也就是說一個 widget 該有多大,它的一個參考來源就是這個 sizeHint 屬性的值,而這個值由 sizeHint() 函數來確定。但是 widget 的大小的確定還有其它因素作用,下面會講到。現在只需知道 sizeHint() 會返回一個被推薦的尺寸。那麼這個尺寸的取值是怎樣的呢?當它是一個無效值的時候(sizeHint().isValid() 返回 false,QSize 中 width 或者 height 有一個爲複數就會是無效的),什麼作用也沒有;當它是一個有效值的時候,它就成了 widget 大小的一個參考。Qt 中對 sizeHint() 的默認實現是這樣的:當 widget 沒有佈局(layout),返回無效值;否則返回其 layout 的首選尺寸(preferred size)。

       1: QWidget *widget = new QWidget;

       2: widget->show();

       3: qDebug() << widget->width() << "," << widget->height();

       4: qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();

       1: //output:

       2: //1009 , 520

       3: //-1 , –1

    輸出結果中第二行:sizeHint() 返回的是一個無效的 QSize,因爲 widget 沒有佈局。

       1: QWidget *widget = new QWidget;

       2: QHBoxLayout *layout = new QHBoxLayout;

       3: QPushButton *button = new QPushButton("Ggicci");

       4: layout->addWidget(button);

       5: widget->setLayout(layout);

       6: widget->show();

       7: qDebug() << widget->width() << "," << widget->height();

       8: qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();

       9: qDebug() << button->width() << "," << button->height();

    2012-10-26_1729

       1: //output:

       2: //112 , 45

       3: //97 , 45

       4: //90 , 23

    輸出結果中第一行:widget 的實際尺寸 (112, 45);
    輸出結果中第二行:sizeHint() 返回 layout 的首選尺寸(97,45)供 widget 參考;
    輸出結果中第三行:中間 button 的實際大小;
    從輸出結果中可以證明以上說過的兩點:

        1) 在 widget 有 layout 的情況下,其 sizeHint() 函數返回的是有效值作爲其自身實際尺寸的參考;
        2) sizeHint() 返回的值並不一定會作爲 widget 的實際尺寸,因爲 widget 的尺寸的決定還有其它因素作用;

      minimumSizeHint
    [From Qt Doc: This property holds the recommended minimum size for the widget. If the value of this property is an invalid size, no minimum size is recommended. The default implementation of minimumSizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's minimum size otherwise. Most built-in widgets reimplement minimumSizeHint().] Qt 中的 widget 有 size 和 minimumSize 兩個屬性,比較好理解的是上面的 sizeHint 是作爲 size 的參考的,那麼 minimumSizeHint 是作爲 minimumSize 的參考的。minimumSizeHint() 的默認實現同 sizeHint() 基本一樣:在 widget 無 layout 的情況下返回無效值;否則返回 layout 的最小尺寸(minimum size),注意與上面的首選尺寸不同哦!有同學會問 preferred size 和 minimum size 的區別:preferred size 由 layout 的 sizeHint() 函數返回,minimum size 由 layout 的 minimumSize() 函數返回;前者的實現會根據 layout 的種類的變化而變化,比如在 QHBoxLayout 和 QVBoxLayout 中各放置同樣的兩個 QPushButton,兩者的 sizeHint() 返回的值是不一樣的,後者是返回能夠容納下所有包含在 layout 內的組件的最小尺寸。Qt 中大多數內置的 widget 都已經重新實現了 minimumSizeHint()。你可以自己寫自己的 widget 然後重新實現 sizeHint()、minimumSizeHint() 這些函數來達到自己的佈局效果。
    [From Qt Doc: QLayout will never resize a widget to a size smaller than the minimum size hint unless minimumSize() is set or the size policy is set to QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint will be ignored.] layout 永遠也不會把一個 widget 的大小設置到比 minimumSizeHint() 返回的尺寸還小,除非 widget 設置了最小尺寸或者其 sizePolicy 屬性設置了 QSizePolicy::Ignore。如果 widget 通過 setMinimumSize() 設置了最小尺寸,那麼 minimumSizeHint 的作用就會被忽略掉。我們知道如果在一個 layout 裏面添加一些子 widget,然後窗口應用這個 layout 的時候,一般情況下我們是無法縮放到使其中的子 widget 看不見的。如下:

       1: QWidget *widget = new QWidget;

       2: widget->setMinimumSize(10, 10);

       3: QVBoxLayout *layout = new QVBoxLayout;

       4: QPushButton *button = new QPushButton("Ggicci");

       5: layout->addWidget(button);

       6: widget->setLayout(layout);

       7: widget->show();

    這裏同上顯示一個含有 QPushButton 的 QWidget,不過在這裏設置了其最小尺寸爲(10, 10),此時 minimumSizeHint() 將不起作用,也就是我們可以把 widget 縮放到(10, 10),不過這是理論上的哦,親~(在這裏你講看到一個例外),以下就是縮小到了極致:(112,10),同學,是否在思考爲什麼 width 無法縮小到比  112 更小了。其實這是 widget 和 windows 系統的共同問題,第一 widget 默認有 min,max,close 三個按鈕,也就是右上角的最小化、最大化、關閉按鈕,這導致了 width 無法繼續縮小。其實通過 widget->setWindowFlags(Qt::Window | Qt::WindowTitleHint); 可以把 min, max 按鈕給去了,這樣的 widget 的 width 就可以比之前更小一點啦,如下右圖。
    2012-10-26_18192012-10-26_1837

      sizePolicy
    [From Qt Doc: This property holds the default layout behavior of the widget. If there is a QLayout that manages this widget's children, the size policy specified by that layout is used. If there is no such QLayout, the result of this function is used.] 這個屬性保存了該 widget 的默認佈局屬性,如果它有一個 layout 來佈局其子 widgets,那麼這個 layout 的 size policy 將被使用;如果該 widget 沒有 layout 來佈局其子 widgets,那麼它的 size policy 將被使用。默認的 policy 是 Preferred/Preferred。QSizePolicy::Policy 枚舉值有如下幾個:

    Constants
     

    Description
    QSizePolicy::Fixed  widget 的實際尺寸只參考 sizeHint() 的返回值,不能伸展(grow)和收縮(shrink)
    QSizePolicy::Minimum  可以伸展和收縮,不過sizeHint() 的返回值規定了 widget 能縮小到的最小尺寸
    QSizePolicy::Maximum  可以伸展和收縮,不過sizeHint() 的返回值規定了 widget 能伸展到的最大尺寸
    QSizePolicy::Preferred  可以伸展和收縮,但沒有優勢去獲取更大的額外空間使自己的尺寸比 sizeHint() 的返回值更大
    QSizePolicy::Expanding  可以伸展和收縮,它會儘可能多地去獲取額外的空間,也就是比 Preferred 更具優勢
    QSizePolicy::MinimumExpanding  可以伸展和收縮,不過sizeHint() 的返回值規定了 widget 能縮小到的最小尺寸,同時它比 Preferred 更具優勢去獲取額外空間
    QSizePolicy::Ignored  忽略 sizeHint() 的作用

    Y8IDK

從上圖中可以看出 Preferred 雖然可以收縮得比 sizeHint() 更小,但是最小由 minimumSizeHint() 限制

        QSizePolicy::Fixed

       1: QWidget *widget = new QWidget;

       2: QHBoxLayout *layout = new QHBoxLayout;

       3: QPushButton *button = new QPushButton("Ggicci");

       4: //button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

       5: layout->addWidget(button);

       6: widget->setLayout(layout);

       7: widget->show();

    在第4行代碼註釋掉的情況下:QPushButton 默認的 sizePolicy 是垂直方向 Fixed,水平方向 Preferred,故水平方向會伸展2012-10-26_2030
    沒有註釋掉的情況下:
    2012-10-26_2035
    
        QSizePolicy::Preferred 和 QSizePolicy::Expanding 的區別:兩者都可以伸展和收縮,但是區別在於誰可以伸展地更牛B

       1: QWidget *widget = new QWidget;

       2: QHBoxLayout *layout = new QHBoxLayout;

       3: QPushButton *button1 = new QPushButton("Ggicci");

       4: QPushButton *button2 = new QPushButton("Mingjie Tang");

       5: button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

       6: button2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

       7: layout->addWidget(button1);

       8: layout->addWidget(button2);

       9: widget->setLayout(layout);

      10: widget->show();

    兩者一樣牛B(在水平方向上,垂直方向不構成額外空間競爭關係):
    2012-10-26_2042

       1: QWidget *widget = new QWidget;

       2: QHBoxLayout *layout = new QHBoxLayout;

       3: QPushButton *button1 = new QPushButton("Ggicci");

       4: QPushButton *button2 = new QPushButton("Mingjie Tang");

       5: button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);

       6: button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

       7: layout->addWidget(button1);

       8: layout->addWidget(button2);

       9: widget->setLayout(layout);

      10: widget->show();

    button2更牛B(在水平方向上構成競爭關係):
    2012-10-26_2047
        有了上述的樣例,QSizePolicy::Minimum, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored 就比較好理解了吧,親

發佈了92 篇原創文章 · 獲贊 11 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章