PySide——Python圖形化界面


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。雖然我們可以在信號的槽中檢測圓的大小和位置,但是使用信號發送這些信息會更加方便。

  View Code

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,連接信號槽,移動並改變它的大小。

  View Code

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

當運行腳本的時候,你的結果應該是:

  View Code
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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM