zoukankan      html  css  js  c++  java
  • 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。虽然我们可以在信号的槽中检测圆的大小和位置,但是使用信号发送这些信息会更加方便。

     1 from PySide.QtCore import QObject, Signal, Slot
     2  
     3 class Circle(QObject):
     4     ''' Represents a circle defined by the x and y
     5         coordinates of its center and its radius r. '''
     6     # Signal emitted when the circle is resized,
     7     # carrying its integer radius
     8     resized = Signal(int)
     9     # Signal emitted when the circle is moved, carrying
    10     # the x and y coordinates of its center.
    11     moved = Signal(int, int)
    12  
    13     def __init__(self, x, y, r):
    14         # Initialize the Circle as a QObject so it can emit signals
    15         QObject.__init__(self)
    16  
    17         # "Hide" the values and expose them via properties
    18         self._x = x
    19         self._y = y
    20         self._r = r
    21  
    22     @property
    23     def x(self):
    24         return self._x
    25  
    26     @x.setter
    27     def x(self, new_x):
    28         self._x = new_x
    29         # After the center is moved, emit the
    30         # moved signal with the new coordinates
    31         self.moved.emit(new_x, self.y)
    32  
    33     @property
    34     def y(self):
    35         return self._y
    36     @y.setter
    37     def y(self, new_y):
    38         self._y = new_y
    39         # After the center is moved, emit the moved
    40         # signal with the new coordinates
    41         self.moved.emit(self.x, new_y)
    42  
    43     @property
    44     def r(self):
    45         return self._r
    46  
    47     @r.setter
    48     def r(self, new_r):
    49         self._r = new_r
    50         # After the radius is changed, emit the
    51         # resized signal with the new radius
    52         self.resized.emit(new_r)
    View Code

    注意以下几点:

    • 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,连接信号槽,移动并改变它的大小。

     1 c = Circle(5, 5, 4)
     2  
     3 # Connect the Circle's signals to our simple slots
     4 c.moved.connect(on_moved)
     5 c.resized.connect(on_resized)
     6  
     7 # Move the circle one unit to the right
     8 c.x += 1
     9  
    10 # Increase the circle's radius by one unit
    11 c.r += 1
    View Code

    当运行脚本的时候,你的结果应该是:

    Circle was moved to (6, 5).
    Circle was resized to radius 5.
    View Code

    现在我们对信号和槽有了更深入的了解,可以准备使用一些更高级的widgets了。下一个教程开始讨论QListWidget和QListView,两种创建表框(list box)控件的方法。

    By Ascii0x03

    转载请注明出处:http://www.cnblogs.com/ascii0x03/p/5500933.html

  • 相关阅读:
    VS2017 C# winform 项目使用 sqlite (二)
    VS2017 C# winform 项目使用 sqlite (一)
    JS权威指南笔记(171页)-this关键字的作用域
    量化交易之下单函数和context对象
    量化交易策略基本框架
    初始量化交易
    金融量化之Tushare模块
    Python之基础算法介绍
    数据分析之Matplotlib和机器学习基础
    数据分析之Pandas
  • 原文地址:https://www.cnblogs.com/ascii0x03/p/5500933.html
Copyright © 2011-2022 走看看