qr7*_*3J9 5 python ctypes pywinauto kivy
我有一个kivy应用程序,可以使用pywinauto模块与其他窗口进行交互。该应用程序在Linux(未使用pywinauto)上运行良好,但是在Windows中,我收到以下错误消息,该应用程序甚至无法启动:
C:\Program Files (x86)\Python36_64\lib\site-packages\pywinauto\__init__.py:80: UserWarning: Revert to STA COM threading mode
warnings.warn("Revert to STA COM threading mode", UserWarning)
[INFO ] [GL ] NPOT texture support is available
[INFO ] [Base ] Start application main loop
Traceback (most recent call last):
File ".\application.py", line 368, in <module>
Application().run()
File "C:\Program Files (x86)\Python36_64\lib\site-packages\kivy\app.py", line 826, in run
runTouchApp()
File "C:\Program Files (x86)\Python36_64\lib\site-packages\kivy\base.py", line 477, in runTouchApp
EventLoop.start()
File "C:\Program Files (x86)\Python36_64\lib\site-packages\kivy\base.py", line 164, in start
provider.start()
File "C:\Program Files (x86)\Python36_64\lib\site-packages\kivy\input\providers\wm_touch.py", line 68, in start
self.hwnd, GWL_WNDPROC, self.new_windProc)
ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type
Run Code Online (Sandbox Code Playgroud)
我认为这是pywinauto的问题,原因是我有以下几行内容,并且在Linux上运行良好:
if SYSTEM == "Windows":
import win32gui
import win32process
import wmi
from pywinauto import application
import pywinauto
Run Code Online (Sandbox Code Playgroud)
我也注释掉了pywinauto导入行,它开始了。可能与此问题有关。我真的不知道要包含什么代码,因为它可以在其他操作系统上工作。
我的问题是:如何在同一应用程序中同时具备kivy和pywinauto的功能?
我能够使用以下方式重现该行为:
附带说明一下,我之前没有使用过这两个软件包中的任何一个,我pip install专门为完成此任务而编辑它们。
由于我不知道如何重现该行为,因此我只从[GitHub]复制了MCVE :pywinauto / pywinauto-ctypes.ArgumentError @ click_input(您在问题中也分享了此内容),并对其进行了少许修改(仅是为了解决错误) ,没有样式,改进...等等。
code.py:
import random
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
import pywinauto # @TODO - cfati: moved after Kivy import(s), as it works otherwise (https://github.com/pywinauto/pywinauto/issues/419#issuecomment-488258224)
class DemoLayout(BoxLayout): pass
Builder.load_string("""
#: import datetime datetime.datetime
<DemoLayout>:
padding: 75
Button:
on_press: print(f"PRESSED @ {datetime.now()}")
""")
class Demo(App):
def build(self):
self.root = DemoLayout()
def on_start(self):
title = f"__KIVY_APP__{random.getrandbits(128)}"
Window.set_title(title)
hwnd = pywinauto.findwindows.find_window(title=title)
app = pywinauto.Application()
app.connect(handle=hwnd)
window = app.window(handle=hwnd).wrapper_object()
window.click_input(button="left", pressed="", coords=(100, 100), double=False, absolute=False)
Demo().run()
Run Code Online (Sandbox Code Playgroud)
输出:
Run Code Online (Sandbox Code Playgroud)[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q055928463]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py [INFO ] [Logger ] Record log in C:\Users\cfati\.kivy\logs\kivy_19-05-01_83.txt [INFO ] [Kivy ] v1.10.1 [INFO ] [Python ] v3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] [INFO ] [Factory ] 194 symbols loaded [INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil, img_gif (img_ffpyplayer ignored) [INFO ] [Window ] Provider: sdl2 [INFO ] [GL ] Using the "OpenGL" graphics system [INFO ] [GL ] GLEW initialization succeeded [INFO ] [GL ] Backend used <glew> [INFO ] [GL ] OpenGL version <b'4.5.0 - Build 23.20.16.4973'> [INFO ] [GL ] OpenGL vendor <b'Intel'> [INFO ] [GL ] OpenGL renderer <b'Intel(R) HD Graphics 530'> [INFO ] [GL ] OpenGL parsed version: 4, 5 [INFO ] [GL ] Shading version <b'4.50 - Build 23.20.16.4973'> [INFO ] [GL ] Texture max size <16384> [INFO ] [GL ] Texture max units <32> [INFO ] [Window ] auto add sdl2 input provider [INFO ] [Window ] virtual keyboard not allowed, single mode, not docked e:\Work\Dev\VEnvs\py_064_03.07.03_test0\lib\site-packages\pywinauto\__init__.py:80: UserWarning: Revert to STA COM threading mode warnings.warn("Revert to STA COM threading mode", UserWarning) [INFO ] [Text ] Provider: sdl2 [INFO ] [Base ] Start application main loop Traceback (most recent call last): File "code.py", line 36, in <module> Demo().run() File "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\lib\site-packages\kivy\app.py", line 826, in run runTouchApp() File "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\lib\site-packages\kivy\base.py", line 477, in runTouchApp EventLoop.start() File "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\lib\site-packages\kivy\base.py", line 164, in start provider.start() File "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\lib\site-packages\kivy\input\providers\wm_touch.py", line 68, in start self.hwnd, GWL_WNDPROC, self.new_windProc) ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type
在继续之前,我想指出:
从后者可以看出,SetWindowLongPtrW的第三个参数可以是DWORD,HANDLE,函数指针,具体取决于第二个参数值:基本上是一个void*可以映射到任何东西的参数。
两个模块都通过ctypes调用此函数:
Pywinauto([GitHub]:pywinauto / pywinauto-(0.6.6)pywinauto / pywinauto / win32functions.py):
try:
SetWindowLongPtr = ctypes.windll.user32.SetWindowLongPtrW
SetWindowLongPtr.argtypes = [win32structures.HWND, ctypes.c_int, win32structures.LONG_PTR]
SetWindowLongPtr.restype = win32structures.LONG_PTR
except AttributeError:
SetWindowLongPtr = SetWindowLong
Run Code Online (Sandbox Code Playgroud)Kivy([GitHub]:kivy / kivy-(1.10.1)kivy / kivy / input / providers / wm_common.py):
try:
windll.user32.SetWindowLongPtrW.restype = WNDPROC
windll.user32.SetWindowLongPtrW.argtypes = [HANDLE, c_int, WNDPROC]
SetWindowLong_wrapper = windll.user32.SetWindowLongPtrW
except AttributeError:
windll.user32.SetWindowLongW.restype = WNDPROC
windll.user32.SetWindowLongW.argtypes = [HANDLE, c_int, WNDPROC]
SetWindowLong_wrapper = windll.user32.SetWindowLongW
Run Code Online (Sandbox Code Playgroud)说明:
windll.user32.SetWindowLongPtrW就像我们在64位上一样),但是它们的功能有所不同这就是为什么我必须在Kivy之后移动Pywinauto导入,以便Kivy尝试使用Pywinauto的原型来调用该函数,否则它将起作用。可以采取其他方法,但是我没有费心找到Pywinauto会调用该函数的情况,因为它不相关。
查看2个ctypes原型和C个原型(来自MS URL),结果表明:
我修改了Kivy装置,然后修改了tadaa!(这是复活节兔子!:)):
注意:此处遇到一个(较简单的)变体:[SO]:如何防止pynput和ctypes冲突?
@ EDIT0:
我提交了[GitHub]:kivy / kivy-SetWindowLongPtrW ctypes原型错误,该错误已合并。但是,不确定何时将在市场上出售它(PyPI,所以您可以简单地选择pip install它)。
或者,您可以下载补丁,然后在本地应用更改。检查[SO]:从鼠标右键单击PyCharm Community Edition中的上下文菜单运行/调试Django应用程序的UnitTests?(@CristiFati的答案)(修补utrunner部分),介绍如何在Win上应用修补程序(基本上,每行以一个“ +”号开头的行都进入,而每行以一个“-”号开头的行都熄灭)。我正在使用Cygwin,顺便说一句。
或者,您可以下载3个修改后的文件并覆盖现有文件。
无论如何,请先备份它们!另外,我不知道这些更改如何适应较旧的版本Kivy版本。
| 归档时间: |
|
| 查看次数: |
482 次 |
| 最近记录: |