【发布时间】:2017-12-17 14:30:15
【问题描述】:
我有一个带有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.connect(self.dism_cancel_event) 之前调用了self.progdialog.canceled.disconnect() 以覆盖cancel() 信号并阻止cancel() 的调用。
【问题讨论】:
-
请将您的解决方案作为答案发布在下面,而不是将其包含在您的问题中。
标签: windows winapi events pyqt dism