背景
在与PyQt不同的样式中,SIP用于为基于Qt (来源)的自定义库生成本机绑定。我试图诊断一个与信号有关的问题,这些信号提供了自定义类型在传递到它们各自的插槽时未被转换的参数,并且正在寻找要尝试的东西的指针。代码是开源的,我鼓励任何人自己尝试代码,但是对于那些想要稍微简洁/简洁的描述的人,我在这里做了最好的尝试。
问题
让我们从Python代码开始,它使用导致问题的生成模块(交互示例)。这里是MainWindow构造函数中的标准信号/插槽连接代码,完整的源代码可以在mainwindow.py中找到。
class MainWindow(QMainWindow):
def __init__(self, argv, parent=None):
# ... snipped other setup code ...
# connect slot that shows a message in the status bar when a graph is clicked:
self.customPlot.plottableClick.connect(self.graphClicked)QCustomPlot和plottableClick信号的定义在sip/core.sip中。注意,plottableClick信号提供了一个QCPAbstractPlottable*对象作为第一个参数。
class QCustomPlot : public QWidget
{
// ... snipped other methods of QCustomPlot type ...
signals:
void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);现在让我们看一下时隙方法,它可以观察到问题所在。当调用插槽时,会引发异常,因为plottable是有效的PyObject,但它没有类型成员,导致对interface1D的调用失败:
def graphClicked(self, plottable, dataIndex):
dataValue = plottable.interface1D().dataMainValue(dataIndex) # fails because plottable has no member method called "interface1D"QCPAbstractPlottable的绑定显示定义了成员。
class QCPAbstractPlottable : public QCPLayerable /Abstract/
{
// ... snipped other methods here ...
virtual QCPPlottableInterface1D *interface1D();另外,生成的绑定在调用QCustomPlot的成员函数(如返回QList的QCustomPlot.selectedPlottables() )时会正确地转换类型。这使我相信,这个问题是信号特有的。
问题
在对这个问题进行了几天的讨论之后,它开始看起来好像SIP没有它需要的信息来认识到,在库中定义的类型是在传递给一个信号时可以转换的类型。
查看PyQt5源代码,我发现了一些示例,其中将库中定义的类型作为信号参数传递,例如QWidget::mousePressEvent接受QMouseEvent*,这与我试图在自己的信号中复制的模式相同。但是,我找不到任何特殊的SIP胶水代码来提示代码生成器如何转换类型。
我做错了什么?
发布于 2018-12-12 18:37:20
事实证明,答案很简单,诀窍是使用%转换子类码指令。在这里,您可以使用任何形式的rtti (可能是qobject_cast、dynamic_cast或任何其他机制)对从对象中推断类型的逻辑进行手工编码,然后将sipType变量设置为正确的值(更详细的解释请参见链接文档)。
https://stackoverflow.com/questions/53740922
复制相似问题