2

当我了解 PyQt 时,有三件事让我感到好奇。这是关于第二个的问题,但让我说出所有三个以防万一其他人好奇:

  1. 首先,我们可以在 Python 中继承 C++ 类(可以这么说),覆盖 Python 中的 C++ 方法——并将我们的类传递回 Qt 框架,Qt 框架将调用它们,就像它们是 C++ 一样!
  2. 第二,插槽。在核心 Qt 中,它们是 C++ 类的方法。但是在 PyQt 中,我们可以轻松地将 Python 方法用作插槽,它们会被调用。(它们似乎对 Qt“内省”系统不可见,尽管*)
  3. 第三,信号。在 Qt 中,它们是静态生成的 C++ 代码——那么 PyQt 是如何聪明地允许我们在 Python 中创建它们(a)和(b)基本上是动态的?

我想我理解(1)(对于每个具有virtual方法的类,SIP 生成一个继承它的子类,持有对 Python 对象的引用,以便为每个被覆盖的方法生成的代码首先检查是否存在 Python 方法),以及( 3)知道(2)不应该太难理解。

正如本文所得出的那样,要拥有 (2),我们必须为我们的 Python 类实现该qt_metacall()方法,并通过为我们的 PyQt 类提供相应的 QMetaObject 来将其链接到 Qt“元系统”。

我将不胜感激有关它是如何完成的任何提示,无论是在 PyQt 或 PySide 中,还是在之前使用 Boost::Python 为 PySide 完成的。

特别是,我想知道 PyQt4.QtCore.SLOT() 使用什么作为相应 Python 方法的签名字符串。

PS。正如在相关帖子中所说,“这个问题已经在这个论坛中提出,但我不明白这个概念”。


*) 下面的代码列出了 Qt 对象的插槽;不出所料,Python 对象方法不会显示在此列表中,即使它们是 connect()-ed。(有没有办法列出当前作为插槽工作的 Python 方法?)

def print_object_slots( qt_object, this_class_only = False ):  

    # there was a method called signalNames(), and, I suspect, slotNames(), 
    # but it was removed in Qt 4 [ http://www.qtforum.org/article/33122/method-qmetaobject-signalnames-removed-in-qt4.html#post106693 ]

    mo = qt_object.metaObject()
    nmethods = mo.methodCount()

    first_method_offset = 0  
    if this_class_only :
        first_method_offset = mo.methodOffset() # assert != -1 

    # or use PyQt.QtCore.QMetaMethod.Slot
    type_slot = 2 # [ http://doc.qt.nokia.com/4.6/qmetamethod.html#MethodType-enum ]

    # list the slots 
    for i in xrange( first_method_offset, nmethods ):
        meth = mo.method(i)
        if meth.methodType() == type_slot :

            print meth.signature()

PyQt4.QtCore.pyqtSignal()(使用 1 而不是 2 来列出信号。而且 - 不,也不会列出类( one )的 PyQt 信号。)

4

1 回答 1

0

您可以在现代版本的 PyQt 中使用装饰器。例如:

@QtCore.pyqtSlot()
@QtCore.pyqtSlot('bool')  
def coolSlotActions(self, b=True):
   """ my slot called, with two different signatures """
   pass # do something cool!

PyQt 4.9.4 文档中的更多信息。据我所知,这在 pyside 中不起作用。

于 2012-07-30T02:35:55.850 回答