Как испустить PyQt-сигнал из CFFI-обратного вызова - PullRequest
0 голосов
/ 26 июня 2019

Я сейчас немного застрял. Это скорее вопрос «как правильно подойти к этой проблеме», поскольку я даже не знаю, что именно ввести в Google.

Я получил научную камеру от torlabs, которая предоставляет только C DLL в качестве API. Я написал класс Python, чтобы обернуть API, используя CFFI, который прошел очень хорошо. API поддерживает регистрацию метода обратного вызова, который вызывается, когда доступен новый кадр камеры. Используя CFFI, можно зарегистрировать методы python как обратные вызовы, которые вызываются DLL.

Моя конечная цель теперь состоит в том, чтобы отображать кадры в PyQt-приложении. Поэтому я подумал, что мог бы использовать обратный вызов кадра для передачи сигнала, который подключен к pyqt-сокету для рисования следующего кадра.

Проблема в том, что обратный вызов должен обеспечивать соответствующий интерфейс, который будет вызываться API, что, конечно, имеет смысл. Но чтобы испустить PyQt-сигнал, мне нужно вызвать emit () для объекта, который является производным от QObject.

Как я могу получить свой общий метод обратного вызова для удержания такого объекта?

Поскольку я хочу отделить класс обработки камеры от части с графическим интерфейсом, я действительно не хочу делать глобальный QObject в классе камеры или что-то в этом роде, чтобы у меня был элемент для вызова (я действительно не хочу в этом отношении у меня есть какой-либо объект-объект внутри класса камеры, поскольку я хочу сделать его как можно более универсальным, если это имеет смысл)

Для проверки я написал небольшой метод обратного вызова, который просто печатает небольшое сообщение при вызове и использовал предоставленный метод set_callback. Я также пытался отобразить кадры с помощью matplotlib, но это не очень хорошо работало, так как matplotlib не любит вызываться из другого потока. Я просто не знаю, как правильно обращаться с данными, полученными в методе обратного вызова.

Это требуемый тип обратного вызова и функция для установки обратного вызова.

typedef void(*TL_CAMERA_FRAME_AVAILABLE_CALLBACK)(void* sender, unsigned short* image_buffer, int frame_count, unsigned char* metadata, int metadata_size_in_bytes, void* context);

typedef int(*TL_CAMERA_SET_FRAME_AVAILABLE_CALLBACK)(void* tl_camera_handle, TL_CAMERA_FRAME_AVAILABLE_CALLBACK handler, void* context);

В Python я могу затем создать метод обратного вызова и назначить его

from _Thorlabscam import lib, ffi

@ffi.def_extern()
def python_frame_callback(sender, buffer, framecount, metadata, metasize, context):
    print("Frame acquired!")
    # How can I process all the nice data I have at this point?

lib.tl_camera_set_frame_available_callback(camHandle, frame_callback, ffi.NULL)

Мне очень жаль этого плохо сформулированного вопроса, но я не знаю, как объединить эти две концепции для совместной работы. Я мог бы опрашивать камеру с помощью некоторой петли, но я хочу сделать ее управляемой событиями, потому что я считаю, что она «чище» (и я просто хочу, чтобы она работала для моего личного удовлетворения :)) Спасибо всем

...