2009年4月23日

[PyQt 教學] Part 4: Layout Management

[PyQt 教學] Part 3: 起步走

看看 Qt 中精美的 widget 們:Qt Widget Gallery

平常使用作業系統圖形介面時,就已經摸過不少了;而在 Qt 中也可以看到這些老朋友們。從 PushButtonCheckBoxProgressBarSpinBox 乃至精美的 CalendarWidget,應有盡有。認識老朋友的名字,對於日後呼叫會有幫助。

先召喚個 QPushButton 出來:

#!/usr/bin/env python

import sys
from PyQt4.QtGui import *

app = QApplication(sys.argv)

button = QPushButton("H&ello!")
button.resize(200, 75)
button.move(500, 400)
button.setWindowTitle("Hello World")
button.show()

app.exec_()


和之前的範例差不多,只是主角從 QWidget 變成 QPushButton。它帶一個字串參數初始化顯示的文字,並調用一些從 QWidget 繼承來的 memfunc。

注意字串參數的樣子,以及 e 下面那條底線;試著按按看 Alt + E。這是 Qt 設定 action focus 的簡便方法。

( 現在這按鈕啥 p 也做不了,我們下一篇再回頭調教它。)


Qt 的排版系統:

#!/usr/bin/env python

import sys
from PyQt4.QtGui import *

app = QApplication(sys.argv)

ok = QPushButton("&OK")
cancel = QPushButton("&Cancel")

layout = QHBoxLayout()
layout.addWidget(ok)
layout.addWidget(cancel)

widget = QWidget()
widget.setLayout(layout)
widget.show()

app.exec_()


......我想這其中的邏輯應該一看就懂,夠直覺了 =.=

QHBoxLayoutQVBoxLayout 掌管基本排版:就像裝箱一樣,用 addWidget() 依序塞入 widget。最後再將它設為空容器 QWidget 的 layout。被裝箱的 widget 不必再額外調用 show()


每個 widget 都有其所屬的 parent ( constructor 預設參數 parent = None )。指定了 parent 之後,就由 parent 掌管、限制該 child 的顯示。當 parent 解構時,child 們也會一同升天。

Layout 系統也是類似的:Layout class 調用 addWidget(w) 之後,就會成為 w 的 parent。另一個 widget 調用 setLayout(layout) 時,成為 layout 的 parent,並把 layout 的 child 們全部接管過去。

parent 的意義,除了接管 child 的資源以外,還決定了 widget 是否為 top-level window。像 w = QWidget() 這樣建構時不帶參數的語法,由於並沒指定 w 的 parent,所以 w 本身成為 top-level window,擁有標題列和邊框。通常我們只需要一個 top-level window,並會把一堆小 widget 塞進裡面顯示。

上例中 widget instance 最終成為所有子元件的 parent,並由它成為 top-level window。


再看看稍微進階一些的排版:

#!/usr/bin/env python

import sys
from PyQt4.QtGui import *

app = QApplication(sys.argv)

lineEdit = QLineEdit()
go = QPushButton("&GO")
h1 = QHBoxLayout()
h1.addWidget(lineEdit)
h1.addWidget(go)

ok = QPushButton("&OK")
cancel = QPushButton("&Cancel")

h2 = QHBoxLayout()
h2.addStretch(1)
h2.addWidget(ok)
h2.addWidget(cancel)

layout = QVBoxLayout()
layout.addLayout(h1)
layout.addLayout(h2)

widget = QWidget()
widget.setLayout(layout)
widget.show()

app.exec_()


比起前一個例子,多了些 widget 以及 addLayout()。像這樣把 layout 塞入 layout,就可以實現層層堆砌的複雜排版。另外還有 addStretch(),塞入空白的可伸縮空間。

拖拉邊框,可以看到 Qt 怎樣自動調整 widget 們的大小並管理定位。一般來說,交給 Qt 內部 Layout 系統來排列 widget 就夠了,很是省心 (>ω<)♪♪

其它排版用的 layout class 還有 QGridLayoutQFormLayout 等,和一堆 container class。有興趣的話再去查文檔吧!

[PyQt 教學] Part 5: Signals & Slots mechanism

沒有留言:

張貼留言