之前用過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]