[PyQt 教學] Part 5: Signals & Slots mechanism ←
到目前為止,我們都是用 procedure-oriented 的方式寫 PyQt code。對於本就是 object-oriented 的 GUI framework 來說,物件導向寫法貌似更加自然,是必需要學會的。
將先前那個 connect 的例子改成 class 型式:( code )#!/usr/bin/env python
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyWidget(QWidget):
def __init__(self, parent = None):
super(MyWidget, self).__init__(parent)
self.createLayout()
self.spinBox.valueChanged.connect(self.slider.setValue)
self.slider.valueChanged.connect(self.spinBox.setValue)
def createLayout(self):
self.spinBox = QSpinBox()
self.spinBox.setPrefix("$")
self.spinBox.setRange(0, 100)
self.slider = QSlider(Qt.Horizontal)
self.slider.setRange(0, 100)
layout = QHBoxLayout()
layout.addWidget(self.spinBox)
layout.addWidget(self.slider)
self.setLayout(layout)
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
app.exec_()
第 7 行:我們定義出 MyWidget 這個新的 class,繼承自外觀空白一片的 QWidget,好讓我們自行塞入東西。內含兩個 memfunc:建構式 __init__() 和自行設計的函式 createLayout()。
第 14 行:開始定義 createLayout()。Python 的 instance method 必帶一個 self 參數。
第 15~20 行:搞出 self.spinBox 和 self.slider 兩個 property,並設定之。
第 22~25 行:設定版面。setLayout() 這個 method 繼承自 QWidget;self.setLayout(layout) 把 layout 設給 MyWidget 自身的版面。( 原本的版面是繼承自 QWidget,空白一片...... )
第 8 行:開始定義建構式。因為我們的 class 不需要寄生在其它 widget 中,所以設定參數 parent = None,以成為 top-level window。
第 9 行:讓 MyWidget 的建構式調用 parent class 的建構式。這個過程是必備的,因為繼承得來的 __init__() 已被覆寫,Python 不會再自動調用 parent class 的建構式;QWidget 未被初始化的話,MyWidget 一開就會瞬間爆炸。
super() 這樣的語法,讓 Python 能自動判別 MyWidget 的 parent class,避免直接寫死在程式碼內。
第 10 行:呼叫 instance method createLayout()
第 11~12 行:建立 connection,讓兩個 widget 能互相影響。
第 30~31 行:建構出 MyWidget 的 instance 並顯示出來。
需要特別注意的地方,就是內部物件到底該不該加前綴 self. 以變成 property 吧!我個人的心得是:取決關鍵在於該物件會不會被跨函式存取。例如 spinBox 和 slider 是在 createLayout() 中建構,但也會在 __init__() 中被存取到,所以必需成為 property。而 layout 用完沒事就可以滾了,所以只活在 createLayout() 中無所謂。
當然啦,程式架構與流程解法並不是唯一的,所以寫成這樣也是可以的,省下一卡車的 self.。怎樣的寫法在各種情境中比較合情合理,就有賴自行判斷了。
平常寫 PyQt 程式,建議都用物件導向的方式,自創 widget class 後再利用之。困難嗎?老樣子,pattern 記起來,轉換就很快了。
下次來寫個稍微有用的玩意兒吧......
感謝blog主寫的詳盡教學<(_ _)>
回覆刪除我把在學PyQt時,關於class這塊讓人比較搞不清楚的部份寫得更詳細一點,如果有人看不懂可以參考:
http://kuanyui.github.io/2014/09/13/learn-python-via-pyqt/#more