我有一个带CancelEvent
参数的 WinApi 函数,但我不知道我必须在那里传递什么?
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
我正在 Windows 10 上使用 python 3.6。该功能正常工作,进度对话框也是如此。我使用 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)
我唯一遇到的问题:cancelevent 需要大约 2 秒才能执行,以便同时 dism_progress_callback 强制窗口再次弹出,尽管我调用self.progdialog.cancel()
它关闭了窗口......希望你能关注我。你有什么建议我可以控制这个吗?
已解决:
我得到了最终解决方案:我之前调用self.progdialog.canceled.disconnect()
过self.progdialog.canceled.connect(self.dism_cancel_event)
覆盖 cancelled() 信号并阻止调用 cancel()。