几个月前,我写了一个Python GUI应用程序,它读取包含车辆数据的文件。然后,它使用sendkeys模块在温室气体模型应用程序上输入数据。我已经将代码转换为使用pywinauto并使用pywinauto中的应用程序模块来启动温室气体应用程序。
我希望在后台安装温室气体应用窗口,或者在发送数据时将其最小化。我担心如果显示温室气体窗口,用户将尝试关闭窗口或想知道发生了什么。
我在python win32gui模块中使用以下函数来最小化温室气体应用程序窗口:
win32gui.ShowWindow(hndl,win32con.SW_MINIMIZE)
win32gui.SetForegroundWindow(hndl)
当我添加上面的代码时,温室气体应用程序窗口被最小化。不幸的是,pywinauto中的SendKeys模块不会将信息发送到最小化窗口。
这有什么办法吗?谢谢你的帮助。
答案 0 :(得分:3)
TypeKeys()
或SendKeysCtypes()
(当前版本的pywinauto
使用此模块发送击键)模块无法使用。这是因为他们使用SendInput
win API,它只适用于活动应用程序(如果应用程序最小化,应用程序将不会处于活动状态。
那说以下可能有用: 更改编辑文本:
app.Dialog.Edit.SetEditText("Your Text")
单击按钮或复选框等:
app.Dialog.ButtonEtc.Click()
这些可以与后台应用程序一起使用。我试图隐藏窗口 - 但上面没有工作:((因为默认情况下大多数pywinauto试图确保窗口可见+启用。
要获得隐藏窗口,您可以使用:
hidden_win = app.window_(title = "Untitled - Notepad", visible_only = False)
并获得一个子窗口 - 类似于:
edit_control = hidden_win.ChildWindow(visible_only = False, class_name = "Edit")
但不幸的是 - 你在使用pywinauto时有点卡住(因为edit_control.SetEditText(...)
会检查窗口是否可见:()
以下是一些被黑客攻击的代码,这些代码或多或少可以设置编辑文本的值(注意SetEditText& Select都是从pywinauto复制的 - 并稍微改变以便:
他们没有检查控件是否可见
它们是独立的功能
代码:
import win32gui
import win32con
import sys
import os
sys.path.append(os.path.abspath('.'))
print sys.path[-1]
from pywinauto import application
from pywinauto import win32defines
from pywinauto import win32functions
from pywinauto.timings import Timings
import time
import ctypes
#-----------------------------------------------------------
def Select(win, start = 0, end = None):
"Set the edit selection of the edit control"
# if we have been asked to select a string
if isinstance(start, basestring):
string_to_select = start
#
start = win.TextBlock().index(string_to_select)
if end is None:
end = start + len(string_to_select)
if end is None:
end = -1
win.SendMessageTimeout(win32defines.EM_SETSEL, start, end)
# give the control a chance to catch up before continuing
win32functions.WaitGuiThreadIdle(win)
time.sleep(Timings.after_editselect_wait)
# return this control so that actions can be chained.
return win
#-----------------------------------------------------------
def SetEditText(win, text, pos_start = None, pos_end = None):
"Set the text of the edit control"
# allow one or both of pos_start and pos_end to be None
if pos_start is not None or pos_end is not None:
# if only one has been specified - then set the other
# to the current selection start or end
start, end = win.SelectionIndices()
if pos_start is None:
pos_start = start
if pos_end is None:
pos_end = end
# set the selection if either start or end has
# been specified
win.Select(pos_start, pos_end)
else:
Select(win)
# replace the selection with
text = ctypes.c_wchar_p(unicode(text))
win.SendMessageTimeout(win32defines.EM_REPLACESEL, True, text)
win32functions.WaitGuiThreadIdle(win)
time.sleep(Timings.after_editsetedittext_wait)
# return this control so that actions can be chained.
return win
# this may be useful if you just want to send a keydown/keyup combination
def keystroke(hwnd, key):
win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, key, 0)
win32gui.PostMessage(hwnd, win32con.WM_KEYUP, key, 3 < 30)
app = application.Application.start('notepad')
# hide the window
win32gui.ShowWindow(app.window_(title = "Untitled - Notepad", visible_only = False).handle, win32defines.SW_HIDE)
print "See it is hidden :)"
time.sleep(2)
# get tehe edit control and set it's text
edit = app.window_(title = "Untitled - Notepad", visible_only = False).ChildWindow(visible_only = False, class_name = "Edit")
SetEditText(edit, "The edit text has been set")
# show the window again
win32gui.ShowWindow(app.window_(title = "Untitled - Notepad", visible_only = False).handle, win32defines.SW_SHOW)
这是如何改进pywinauto的一个很好的例子(通过提供一个更低级别的库,可以更容易地做这样的事情)