之前用过Qt进行Python GUI程序开发,这次想试试别的方法,使用Python内置了的tkinter进行GUI开发,遇到了一个很奇怪的问题。
filedialog.askdirectory()方法
直接运行没啥问题,可以打开窗口给用户选择想要指定的文件夹,而且可以自动适应win10的Dark Mode。
放到自己的代码当中去以后,就没法正常打开窗口了。
具体用法是写了个函数调用这个方法,绑定到某个已有窗口的button(基本上就是button初始化时command=filedialog.askdirectory()),点击button后GUI无响应。
查了半天发现应该是代码里用到了pywinauto引起了一些和tkinter的冲突。
用pywinauto主要是为了用到win32api去获取显示分辨率,方便在不同分辨率的显示器上设置合适的GUI字体大小。

from pywinauto import win32api from pywinauto.win32defines import ENUM_CURRENT_SETTINGS, DISPLAY_DEVICE_ATTACHED_TO_DESKTOP, DISPLAY_DEVICE_PRIMARY_DEVICE # get primary display height display_height = 0 for i in range(10): try: device = win32api.EnumDisplayDevices(DevNum=i) except: break if (device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) and (device.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE): settings = win32api.EnumDisplaySettings(device.DeviceName, ENUM_CURRENT_SETTINGS) display_height = int(settings.PelsHeight) break
解决方案
在import pywinauto前设置一下
import sys # set coinit_flags (there will be a warning message printed in console by pywinauto, you may ignore that) sys.coinit_flags = 2 # COINIT_APARTMENTTHREADED
你问我为什么这么设置?那啥,我该去搬砖了。
pywinauto的开发人员是这么回复的:https://github.com/pywinauto/pywinauto/issues/517#issuecomment-448130496
一些其他信息
为了让tk GUI在win10高分辨率显示器上能清晰的显示,设置了一个额外的参数

from ctypes import windll # on Windows Server and early Windows this setting will fail windll.shcore.SetProcessDpiAwareness(2)
环境:
Windows 10
Python 3.9.2
Python Package Graph by Pipenv:
autopep8==1.5.6
- pycodestyle [required: >=2.7.0, installed: 2.7.0]
- toml [required: Any, installed: 0.10.2]
pywinauto==0.6.8
- comtypes [required: Any, installed: 1.1.9]
- pywin32 [required: Any, installed: 300]
- six [required: Any, installed: 1.15.0]