PySide——Python圖形化界面
PySide——Python圖形化界面入門教程(四)
PySide——Python圖形化界面入門教程(四)
——創建自己的信號槽
——Creating Your Own Signals and Slots
原文鏈接:http://pythoncentral.io/pysidepyqt-tutorial-creating-your-own-signals-and-slots/
你不必局限於Qt widget提供的信號,你可以使用Signal類來創建自己的信號。下面是一個定義的簡單例子:
1 from PySide.QtCore import Signal 2 tapped = Signal()
然后,當對象需要觸發信號的條件滿足時,你可以使用信號的emit方法,來發出信號調用關聯的槽。
thing.tapped.emit()
這樣做有兩個優點:第一,允許用戶和你定義的對象隨意交互;第二,讓你的對象使用更加靈活,讓自己的代碼定義動作行為的影響。
一個簡單的PySide信號例子
我們來定義一個簡單的PunchingBag類,它只做一件事情,當punch被調用時,發出punched信號:
1 from PySide.QtCore import QObject, Signal, Slot 2 3 class PunchingBag(QObject): 4 ''' Represents a punching bag; when you punch it, it 5 emits a signal that indicates that it was punched. ''' 6 punched = Signal() 7 8 def __init__(self): 9 # Initialize the PunchingBag as a QObject 10 QObject.__init__(self) 11 12 def punch(self): 13 ''' Punch the bag ''' 14 self.punched.emit()
代碼非常的簡單:PunchingBag繼承自QObject,所以它可以發出信號;它有一個稱為punched的信號,不攜帶任何數據;並且他有一個僅僅發出punched信號的punch方法。
為了讓PunchingBag更豐富一些,我們需要將它的punched信號和一個槽連接。槽簡單的輸出“Bag was punched”。
1 @Slot() 2 def say_punched(): 3 ''' Give evidence that a bag was punched. ''' 4 print('Bag was punched.') 5 6 bag = PunchingBag() 7 # Connect the bag's punched signal to the say_punched slot 8 bag.punched.connect(say_punched) 9 10 # Punch the bag 10 times 11 for i in range(10): 12 bag.punch()
攜帶數據的PySide信號
創建信號可以完成一個非常有用的事情——攜帶數據。例如,你可以創建一個攜帶整數或者字符串的信號:
updated = Signal(int)
updated = Signal(str)
這個數據類型可以是任何Python的類型名或定義了C++類型的字符串。因為教程不假設有任何C++的知識,故我們只使用Python類型。
例子:一個發送信號的圓
我們用x,y和r定義一個圓,x、y是圓中心的坐標,r是半徑。我們想要當圓被改變大小時,發送一個信號resized;當圓被移動時,也發送一個信號moved。雖然我們可以在信號的槽中檢測圓的大小和位置,但是使用信號發送這些信息會更加方便。

from PySide.QtCore import QObject, Signal, Slot
class Circle(QObject):
''' Represents a circle defined by the x and y
coordinates of its center and its radius r. '''
# Signal emitted when the circle is resized,
# carrying its integer radius
resized = Signal(int)
# Signal emitted when the circle is moved, carrying
# the x and y coordinates of its center.
moved = Signal(int, int)
def __init__(self, x, y, r):
# Initialize the Circle as a QObject so it can emit signals
QObject.__init__(self)
# "Hide" the values and expose them via properties
self._x = x
self._y = y
self._r = r
@property
def x(self):
return self._x
@x.setter
def x(self, new_x):
self._x = new_x
# After the center is moved, emit the
# moved signal with the new coordinates
self.moved.emit(new_x, self.y)
@property
def y(self):
return self._y
@y.setter
def y(self, new_y):
self._y = new_y
# After the center is moved, emit the moved
# signal with the new coordinates
self.moved.emit(self.x, new_y)
@property
def r(self):
return self._r
@r.setter
def r(self, new_r):
self._r = new_r
# After the radius is changed, emit the
# resized signal with the new radius
self.resized.emit(new_r)
注意以下幾點:
- Circle繼承自QObject所以可以發送信號
- 同樣的信號可以在不同地方發送
現在我們定義一些連接Circle的信號的槽。還記得我們上次提過的@Slot修飾符(decorator)嗎?現在我們來看看如何接收攜帶了數據的信號。為了接收信號,我們簡單的將其定義為與信號一樣的結構。
1 # A slot for the "moved" signal, accepting the x and y coordinates 2 @Slot(int, int) 3 def on_moved(x, y): 4 print('Circle was moved to (%s, %s).' % (x, y)) 5 6 # A slot for the "resized" signal, accepting the radius 7 @Slot(int) 8 def on_resized(r): 9 print('Circle was resized to radius %s.' % r)
非常的簡單直觀。更多信息可以參考Python decorators,或者來學習這篇文章Python Decorators Overview。最后我們完成這個Circle,連接信號槽,移動並改變它的大小。

c = Circle(5, 5, 4)
# Connect the Circle's signals to our simple slots
c.moved.connect(on_moved)
c.resized.connect(on_resized)
# Move the circle one unit to the right
c.x += 1
# Increase the circle's radius by one unit
c.r += 1
當運行腳本的時候,你的結果應該是:

Circle was moved to (6, 5). Circle was resized to radius 5.
現在我們對信號和槽有了更深入的了解,可以准備使用一些更高級的widgets了。下一個教程開始討論QListWidget和QListView,兩種創建表框(list box)控件的方法。
By Ascii0x03
轉載請注明出處:http://www.cnblogs.com/ascii0x03/p/5500933.html