Фон
В стиле, не отличном от PyQt, SIP используется для генерации собственных привязок для пользовательской библиотеки, основанной на Qt ( Source ).Я пытаюсь диагностировать проблему, связанную с сигналами, которые предоставляют параметры для пользовательских типов, которые не преобразуются при передаче в соответствующие слоты, и ищу указатели для того, чтобы попробовать.Код с открытым исходным кодом, и я призываю всех, кто попробует его, попробовать себя, но для тех, кто хочет получить немного более краткое / искаженное описание, я сделал здесь лучшую попытку.
Проблема
Давайте начнем с кода 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, таких как QCustomPlot.selectedPlottables (), которая возвращает QList.Это заставляет меня поверить, что проблема связана с сигналами.
Вопрос
После нескольких дней стуча головой об этой проблеме, она начинает выглядетьво многом как SIP не имеет информации, необходимой для распознавания того, что типы, определенные в библиотеке, являются типами, которые она может преобразовывать при передаче в сигнал.
Глядя на исходный код PyQt5, я нашел примерыгде типы, определенные в библиотеке, передаются в качестве параметров сигнала, например, QWidget :: mousePressEvent принимает QMouseEvent *, который является тем же шаблоном, который я пытаюсь воспроизвести в своем собственном сигнале.Однако я не могу найти никакого специального кода SIP-клея, который бы подсказал генератору кода, как преобразовать тип.
Что я сделал не так?