python/pyqt - передает CancelEvent в функцию C++

У меня есть функция WinApi с CancelEvent параметр, но я не знаю, что я должен передать там?

HRESULT WINAPI DismUnmountImage(
  _In_     PCWSTR                 MountPath,
  _In_     DWORD                  Flags,
  _In_opt_ HANDLE                 CancelEvent,
  _In_opt_ DISM_PROGRESS_CALLBACK Progress,
  _In_opt_ PVOID                  UserData
);

https://msdn.microsoft.com/en-us/library/windows/desktop/hh824802(v=vs.85).aspx

Я работаю с Python 3.6 на Windows 10. Функция работает правильно, диалог прогресса тоже. Я использовал виджет QProgressDialog для отображения состояния прогресса, мне нужно только реализовать CancelEvent. Определение:

from ctypes import *
import win32con, win32api

def UnmountImage(self, MountPath, Flags=DISM_DISCARD_IMAGE, CancelEvent=None, Progress=None, UserData=None):
    self.hDism.DismUnmountImage.restype = HRESULT
    try:
        return self.hDism.DismUnmountImage(MountPath, Flags, CancelEvent, Progress, UserData)
    except OSError as e:
        print("DismUnmountImage failed: %s\nErrorCode: %s" % (e.strerror, e))
        return self.GetLastErrorMessage()

И часть pyqt:

def canceled(self):
    print("canceled")

@pyqtSlot(QVariant)
def unmount_image(self, json_data):
    dism_progress_callback = dism_manager.DISM_PROGRESS_CALLBACK(self.dism_progress_callback)
    data = json.loads(json_data)

    self.progdialog = QProgressDialog("", "Cancel", 0, 100, None)
    self.progdialog.setWindowTitle("Unmounting Image...")
    self.progdialog.setModal(True)
    self.progdialog.canceled.connect(self.canceled)
    self.progdialog.show()

    for image in data:
        dism_manager.UnmountImage(MountPath=image['MountPath'], Progress=dism_progress_callback, CancelEvent=self.progdialog.winId())

Я пытался передать дескриптор qtWindow, но я получаю сообщение об ошибке ..can't convert parameter 3.., Чего ожидает функция? Дескриптор окна? Я действительно понятия не имею, и я не знаком с C++.

Кстати: QProgressdialog - это окно с QProgress и QButton. Когда я нажимаю на кнопку Отмена, мой def canceled(self): метод испускается, и окно будет закрыто на секунду, а затем прогресс продолжается.

РЕДАКТИРОВАТЬ:
После предложений zett42 я придумал это:

DISM_CANCEl_EVENT = CreateEvent(None, False, False, None)

А также:

def canceled(self):
    print("canceled")
    SetEvent(dism_manager.DISM_CANCEl_EVENT)

    ...
for image in data:
    dism_manager.UnmountImage(MountPath=image['MountPath'], Progress=dism_progress_callback, CancelEvent=dism_manager.DISM_CANCEl_EVENT)

Я получаю это сообщение об ошибке:ctypes.ArgumentError: argument 3: <class 'TypeError'>: Don't know how to convert parameter 3

Ты хоть представляешь, чего мне не хватает?

EDIT2:
Я понял:

def canceled(self):
    self.progdialog.cancel()
    SetEvent(self.cancel_event)

self.cancel_event = dism_manager.DISM_CANCEl_EVENT.Detach()

for image in data:
    dism_manager.UnmountImage(MountPath=image['MountPath'], Progress=dism_progress_callback, CancelEvent=self.cancel_event)

Единственная проблема, которая у меня есть: для отмены события требуется около 2 секунд, чтобы dism_progress_callback заставлял окно снова всплывать, хотя я и вызвал self.progdialog.cancel() который закрывает окно... надеюсь, вы можете следовать за мной. Есть ли у вас какие-либо предложения, как я могу это контролировать?


Решено:
Я получил окончательное решение: я позвонил self.progdialog.canceled.disconnect() до self.progdialog.canceled.connect(self.dism_cancel_event) перезаписать сигнал отменен () и предотвратить вызов отмены ().

1 ответ

Функция ожидает дескриптор объекта события, который может быть создан с помощью CreateEvent() C API. В Python вы можете позвонить win32event.CreateEvent(),

В вашей функции def canceled(self) ты должен позвонить win32event.SetEvent(hEvent) передавая дескриптор объекта события, который вы создали для hEvent параметр. Это будет запрашивать отмену UnmountImage(),

Другие вопросы по тегам