【发布时间】:2020-06-16 11:08:40
【问题描述】:
问题:
当我单击运行的按钮时,我的 python gui (tkinter) 冻结:filename = filedialog.askdirectory()
当我在另一个脚本中有from pywinauto import application 时,这只发生。如果我注释掉 pywinauto 导入,askdirectory 工作得很好。没有冻结,窗口按预期弹出。发生这种情况时,我没有看到任何错误。
抱歉,顺便说一句,我想提供尽可能多的细节。让我知道是否需要更多以及您在寻找什么。理想情况下,我希望使用 askdirectory,但我认为我可以只使用 askopenfilename 并从中获取目录。
Python 版本:
Python 3.4.4
Windows 版本:
Windows Server 2012 R2(无法更改)
我尝试过的事情:
1. 通过教程进行基本线程处理(每次仍然卡住,代码示例在底部)
2. 注释掉代码部分以缩小问题范围。
3. 尝试使用 PyCharms 调试器,但如果出现错误,我没有看到它。
4.不同的IDE。
以下代码块:
如果你愿意的话,我已经按照它们如何交互的顺序将代码块放在下面。它从第一个开始,然后到第二个(中间),最后到第三个。
问题:
有没有办法让我检查错误?
我在这里做错了什么导致这种情况发生吗?
为什么 askopenfilename 可以正常工作,但 askdirectory 不行?
包含冻结窗口的文件:
from InstallMenu import MainMenu
from tkinter import *
from tkinter import filedialog
"""
This is where it freezes. If I change askdirectory to openaskfilename it
works without any issues. If I comment out the from pywinauto import
application from opusite.py, askdirectory works without issue.
"""
def chooseInstallFolder(installFolderPath):
filename = filedialog.askdirectory()
installFolderPath.config(text=filename)
def submitFolder(installFolderApp, installFolderPath, setObj):
installFolderApp.destroy()
MainMenu(installFolderPath, setObj)
def chooseInstall(setObj):
installFolderApp = Tk()
installFolderApp.title("Find Install Folder")
installFolderApp.geometry("300x200")
#Gui items
pickAFolder = Label(installFolderApp, text = "Select your Install Folder")
pickInstallerButton = Button(installFolderApp, text="Browse", command = lambda : chooseInstallFolder(installFolderPath))
installFolderPath = Label(installFolderApp, text = " ")
submit = Button(installFolderApp, text="Submit", command = lambda : submitFolder(installFolderApp, installFolderPath, setObj))
#Packing
pickAFolder.pack()
installFolderPath.pack()
pickInstallerButton.pack()
submit.pack()
installFolderApp.mainloop()
上面的提交按钮转到的菜单脚本:
我已将 iParcPro 注释掉,因为它使用相同的导入导致冻结。
import opusite
#from iParcPro import *
from Sql import *
from tkinter import *
def OPUSiteInstall(installFolderPath):
opusite.OPUSiteInstall(installFolderPath, setObj)
opusite.rs485Install(installFolderPath, setObj)
def MainMenu(installFolderPath, setObj):
menuWindow = Tk()
menuWindow.title("Auto Installer Menu")
menuWindow.geometry("325x250")
#Create variables
ChooseAButton = Label(menuWindow, text = "Choose an option")
OPUSiteButton = Button(menuWindow, text="OPUSite Install", height = 1,
width
= 15, command = lambda : OPUSiteInstall(installFolderPath, setObj))
#Pack
ChooseAButton.pack()
OPUSiteButton.pack()
menuWindow.mainloop()
包含似乎冻结此导入的代码:
import pyautogui as ag
"""
This import here freezes it. If I comment out just the import, the
askdirectory works fine.
"""
from pywinauto import application
def OPUSiteInstall(installFolderPath, setObj):
path = installFolderPath + '\\OPUSite\\AMI.OPUSite.Setup.msi'
app = application.Application().Start(r'msiexec.exe /i ' + path)
Wizard = app['OPUSite Setup']
Wizard.NextButton.Wait('enabled', 50000)
Wizard.NextButton.Click()
Wizard['I &accept the terms in the License
Agreement'].Wait('enabled').CheckByClick()
Wizard.NextButton.Click()
Wizard.NextButton.Click()
ag.typewrite(setObj.databaseName)
ag.press('tab')
ag.press('space')
ag.press('tab')
ag.press('tab')
ag.typewrite(setObj.password)
ag.press('tab')
ag.typewrite(setObj.password)
ag.press('tab')
ag.typewrite(setObj.password)
Wizard.NextButton.Click()
Wizard.Install.Click()
Wizard.Finish.Wait('visible', 50000)
Wizard.Finish.Click()
def rs485Install(installFolderPath, setObj):
path = installFolderPath + '\\OPUSite\\AMI.RS485AdapterSvc.Setup.msi'
app = application.Application().Start(r'msiexec.exe /i ' + path)
Wizard = app['RS485Adapter Setup']
Wizard.NextButton.Wait('enabled', 50000)
Wizard.NextButton.Click()
Wizard['I &accept the terms in the License
Agreement'].Wait('enabled').CheckByClick()
Wizard.NextButton.Click()
Wizard.NextButton.Click()
Wizard.Install.Click()
Wizard.Finish.Wait('visible', 50000)
Wizard.Finish.Click()
这是我尝试过的线程。它不起作用:
from InstallMenu import MainMenu
from tkinter import *
from tkinter import filedialog
import threading
def chooseInstallFolder(installFolderPath):
def callback(installFolderPath):
filename = filedialog.askdirectory()
installFolderPath.config(text=filename)
t = threading.Thread(target=callback, args=(installFolderPath,))
t.start()
def submitFolder(installFolderApp, installFolderPath, setObj):
installFolderApp.destroy()
MainMenu(installFolderPath, setObj)
def chooseInstall(setObj):
installFolderApp = Tk()
installFolderApp.title("Find Install Folder")
installFolderApp.geometry("300x200")
#Gui items
pickAFolder = Label(installFolderApp, text = "Select your Install
Folder")
pickInstallerButton = Button(installFolderApp, text="Browse", command =
lambda : chooseInstallFolder(installFolderPath))
installFolderPath = Label(installFolderApp, text = " ")
submit = Button(installFolderApp, text="Submit", command = lambda :
submitFolder(installFolderApp, installFolderPath, setObj))
#Packing
pickAFolder.pack()
installFolderPath.pack()
pickInstallerButton.pack()
submit.pack()
installFolderApp.mainloop()
【问题讨论】:
-
在
from pywinauto import Application之前尝试import sys; sys.coinit_flags = 0。它允许使用comtypes包对 COM 对象进行多线程处理。 -
我之前添加了您的建议,所以现在看起来是这样。
import pyautogui as ag import sys; sys.coinit_flags = 0 from pywinauto import application我的 chooseInstallFolder 设置类似于我原来帖子中的线程示例。我仍然遇到同样的冻结问题。 -
好的,这可能是基本的线程问题,因为 Python 是单线程的,线程按时间分开运行。在 Python 3.5+ 中使用新的 async/await 语法可以实现真正的并行线程。
标签: python-3.x tkinter freeze pywinauto