如何在Python中处理PyCapsule类型 [英] How to deal with PyCapsule type inside Python

查看:911
本文介绍了如何在Python中处理PyCapsule类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图从

QtGui.QWidget.effectiveWinId() 

win32gui.SetWindowLong()

effectiveWinId()返回:

effectiveWinId() is returning:

<capsule object NULL at 0x027C9BF0>
<class 'PyCapsule'>

并且SetWindowLong()需要一个PyHANDLE(文档说它也应该"也接受整数)

and SetWindowLong() expects a PyHANDLE (doc says it "should" accept an integer also)

TypeError: The object is not a PyHANDLE object

所以我的问题是如何从PyCapsule对象中获取值,或者检查它是否为NULL? PyCapsule似乎是C代码的所有内部API.

So my question is how do I grab the value out of a PyCapsule object and or check if its NULL? It seems PyCapsule is all internal API to the C code.

我还发现了这个错误,它的功能与我想要的Python 2.X PyCObject类似,但在Python 3.x中并不存在:

Also I found this bug that does something similar to what I want with Python's 2.X PyCObject which doesn't exist in Python 3.x here: http://srinikom.github.io/pyside-bz-archive/show_bug.cgi?id=523#c18

推荐答案

好吧,我设法弄清楚了:

Okay I managed to figure it out:

# ...
capsule = self.effectiveWinId()
ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p]
handle = ctypes.pythonapi.PyCapsule_GetPointer(capsule, None)
win32gui.SetWindowLong(handle, win32con.GWL_WNDPROC, self.new_window_procedure)
# ...

这是一个Python类,用于处理覆盖win32窗口过程:

Here is a python class to deal with Overriding the win32 window procedure:

import win32con
import win32gui
import win32api
import ctypes
import pywintypes

def convert_capsule_to_int(capsule):
    ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
    ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p]
    return ctypes.pythonapi.PyCapsule_GetPointer(capsule, None)

class WindowProcedure(object):
    self.handle_WM_DESTROY = False
    def __init__(self, handle):
        if isinstance(handle, int) or isinstance(handle, type(pywintypes.HANDLE())):
            self.handle = handle
        else:
            self.handle = convert_capsule_to_int(handle)
        self.old_proc = win32gui.GetWindowLong(self.handle, win32con.GWL_WNDPROC)
        if not self.old_proc:
            raise RuntimeError("Failed to set/get window procedure!") 
        if not win32gui.SetWindowLong(self.handle, win32con.GWL_WNDPROC, self.new_window_procedure):
            raise RuntimeError("Failed to set/get window procedure!")

    def handle_old_procedure(self, hwnd, msg, wparam, lparam):
        # For some reason the executable would hang after a QtGui.QWidget exit
        # so I'm forcing it here if self.handle_WM_DESTROY is true
        if msg == win32con.WM_DESTROY and self.handle_WM_DESTROY:
            win32gui.DestroyWindow(hwnd)
            return 0
        return win32gui.CallWindowProc(self.old_proc, hwnd, msg, wparam, lparam)

这篇关于如何在Python中处理PyCapsule类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆