Iam trying to get the HWND of multiple windows called the same, and i thought the easy way would be to rename the one i found and search again, but it seems iam not allowed to rename it the way i want.
This is what i have tryed
import win32gui
import win32api
test = win32gui.FindWindow(0, "notepad")
win32gui.SetWindowText(test, "testname")
I have done this in my old project. may be this could help you. use this example as your reference
def UpdateControl_FromValue(self):
name_val = self.GetOptionValue(self.option_folder_name)
id_val = self.GetOptionValue()
self.in_setting_name = True
if id_val:
self.SetOptionValue("", self.option_folder_name)
opt_processors.FolderIDProcessor.UpdateControl_FromValue(self)
else:
if name_val:
win32gui.SetWindowText(self.GetControl(), name_val)
self.in_setting_name = False
FindWindow can return an invalid handle (eg. when no windows matching the text is found). That could be your issue.
The win32gui module exposes win32gui.EnumWindows (doc) that iterates top level windows. You can provide a custom callback that transform the window title.
In the following sample, I filter windows by title prefix, but you could implement a filter with regex, if that's more suitable for you.
import win32gui
def f(hwnd, more):
title = win32gui.GetWindowText(hwnd)
# print(f"{hwnd} - {title}")
prefix = 'notepad'
if title.startswith(prefix):
win32gui.SetWindowText(hwnd, title[len(prefix):])
win32gui.EnumWindows(f, None)
Related
Need help to select all elements of a listview using send_message. I want this to work in RDP disconnected mode and hence using pywinauto's send_message api.
My code
from pywinauto import win32defines
app = Application().connect(path = pathToAppEXE)
lvitem = win32structures.LVITEMW()
lvitem.mask = win32defines.LVIF_STATE
lvitem.state = 1
lvitem.stateMask = win32defines.LVIS_SELECTED
app.window_(title_re = "Net Position.*").ListView.send_message(win32defines.LVM_SETITEMSTATE,-1,lvitem)
It does nothing. Maybe I am not getting the lvm flags correctly. Need assistance to fix the code.
Method .get_item(...) (see docs) should return _listview_item object with some available methods: some of them don't involve real click.
Maybe Remote Execution Guide is also useful.
I'm trying to make a Python code to render only selected objects in Maya, and want to know how to add selected objects to renderLayerSetup in Maya 2017 ?
I've tried to use some code I found
import maya.app.renderSetup.model.renderSetup as renderSetup
rs = renderSetup.instance()
test = rs.createRenderLayer('render')
scene_Assets = test.createCollection('scene_Assets')
scene_Assets.getSelector().setPattern('name')
but this code required me to use the objects name to add to the collection
I expecting the output to be able to add objects to collection without having to rename all the names.
Bit of an old thread, just stumbled across it as I am googling around for solutions to my own little headache and figured I could probably help. (If anyone has any tips on how to get a hold of the collection objects within a collection please throw me a message. The pattern I can find but not the ones that have been added through add or drag and drop.)
Anyway I am actually a bit new to programming so this might not be the most optimal solution, but it works in Maya 2018.6 (the above answer didn't work for me), so it might help someone:
import maya.app.renderSetup.model.renderSetup as renderSetup
import maya.cmds as mc
rs = renderSetup.instance()
#taking the selection and bring it through a for loop to format it.
selectionLi = mc.ls(sl=1)
selection=""
for each in selectionLi:
selection += each +", "
test = rs.createRenderLayer('render')
scene_Assets = test.createCollection('scene_Assets')
scene_Assets.getSelector().setPattern(str(selection))
this is my code, it works in Maya 2019.1
import maya.app.renderSetup.model.override as override
import maya.app.renderSetup.model.selector as selector
import maya.app.renderSetup.model.collection as collection
import maya.app.renderSetup.model.renderLayer as renderLayer
import maya.app.renderSetup.model.renderSetup as renderSetup
import maya.cmds as cmds
# 連接 render setup,如無,則新建
rs = renderSetup.instance()
# 連接 render layer,如無,則新建
try: rl = rs.getRenderLayer("previewLayer") # 如成功:返回實例;如失敗:拋出異常
except: rl = rs.createRenderLayer("previewLayer")
# 連接對象集合 collection,如無,則新建
try: c1 = rl.getCollectionByName("previewCollection")
except: c1 = rl.createCollection("previewCollection")
# 連接選擇器 selector
sl = c1.getSelector()
# staticSelection
ss = sl.staticSelection
# add the selection to list
ss.add(cmds.ls(sl=1))
# remove all static selection from the list
ss.remove(ss.asList())
I'm using win32com.client from the pywin32 module to accept all tracked changes in a word document (Python 3.6.4 on Windows 10 64 bit).
Specifically the code I'm using is the following:
import win32com.client as win32
word = win32.gencache.EnsureDispatch("Word.Application")
word.Visible = False
doc = word.Documents.Open(PATH TO WORD FILE)
doc.Activate()
word.ActiveDocument.TrackRevisions = False # Maybe not need this
try:
word.WordBasic.AcceptAllChangesInDoc()
except TypeError:
pass
word.ActiveDocument.Save()
doc.Close(False)
word.Application.Quit()
I have two questions.
1.) Is there a better way to accept all changes rather than using the try-except block? Using this method produces a TypeError so a try-except block is required to finish the program.
2.) Do you know how you can delete comments left from users?
Here is a code working with Python 2.7 (I assume it works with Python 3.6.4 as well - I'm not familiar yet with the change between 2.X and 3.X)
#!/usr/bin/env python3
import win32com.client as win32
path_file_name = "YourPath\ToYour\doc.docx"
word = win32.gencache.EnsureDispatch("Word.Application")
word.Visible = False
doc = word.Documents.Open(path_file_name )
doc.Activate()
word.ActiveDocument.TrackRevisions = False # Maybe not need this (not really but why not)
# Accept all revisions
word.ActiveDocument.Revisions.AcceptAll()
# Delete all comments
if word.ActiveDocument.Comments.Count >= 1:
word.ActiveDocument.DeleteAllComments()
word.ActiveDocument.Save()
doc.Close(False)
word.Application.Quit()
Let me know if it works out for you.
Judging by other posts such as Python Window Activation this might not be as simple as I was hoping, but I'm compelled to ask anyway.
In the snippet below, using win32com.client and Application.Presentations.Open(ppt1, ReadOnly=0) will open and activate a powerpoint presentation. Using Application.Presentations.Open(ppt2, ReadOnly=0) will open and activate another powerpoint presentation. As you will see, I can easily reference the former presentation and do SOME things with it, but it will NOT become the active window. How can this be accomplished?
Here's what I've been working with:
# The following requires two existing presentations
# ppt1.pptx and ppt2.pptx in a directory named C:\\pptTest\\
import win32com.client
Application = win32com.client.Dispatch("PowerPoint.Application")
directory = 'C:\\pptTest\\'
ppt_a = 'ppt_a.pptx'
ppt_b = 'ppt_b.pptx'
presentation_a = directory + ppt_a
presentation_b = directory + ppt_b
pres_a = Application.Presentations.Open(presentation_a, ReadOnly=0)
pres_b = Application.Presentations.Open(presentation_b, ReadOnly=0)
pres_a_slide1 = pres_a.Slides.Add(len(pres_a.Slides)+1, 12)
shape_a_1 = pres_a_slide1.Shapes.AddTextbox(Orientation=0x1,Left=100,Top=50,Width=400,Height=100)
shape_a_1.TextFrame.TextRange.Text='PRESENTATION A'
##%%
pres_b_slide1 = pres_b.Slides.Add(len(pres_b.Slides)+1, 12)
shape1 = pres_b_slide1.Shapes.AddTextbox(Orientation=0x1,Left=100,Top=50,Width=400,Height=100)
shape1.TextFrame.TextRange.Text='PRESENTATION B'
Result:
As you can see by the example, I can still reference the first presentation after opening another, but I can't make it the active window. The reason why I'm so interested in this, is that some methods will not work properly unless the presentation I'm editing through Python is also the active window. I'll get into those details as well if that is interesting to anyone.
Thank you for any suggestions!
Several examples, see if that works for you
import win32com.client as win32
file1='C:/test.pptm'
file2='C:/test2.pptm'
PowerPoint=win32.DispatchEx("PowerPoint.Application")
PowerPoint.Visible = True
Presentation1 = PowerPoint.Presentations.Open(file1)
Presentation2 = PowerPoint.Presentations.Open(file2)
PowerPoint.Windows(1).Activate()
PowerPoint.Windows(2).Activate()
print(PowerPoint.ActivePresentation.Name) # to see the name
PowerPoint.Presentations("test.pptm").Windows(1).Activate()
PowerPoint.Presentations("test2.pptm").Windows(1).Activate()
Presentation1.Windows(1).Activate()
Presentation2.Windows(1).Activate()
I dug through some old code and found something where I also had to switch between different open programs :
from win32com.client import Dispatch
autoit = Dispatch("AutoItX3.Control")
def _window_movement_windows(page_title):
autoit.WinSetOnTop(page_title, "", 1)
autoit.WinActivate(page_title, "")
autoit.WinWaitActive(page_title)
An example how to setup AutoIt with python can be found here : Calling AutoIt Functions in Python
When I use python-xlib to grab the currently focused window with get_input_focus(), the window name and class is set correctly for Konsole, but for Chrome and Emacs, they are just empty strings (although the window ID seems valid for all three). Why?
How can I get the title and owner process of these windows? Since I use KDE, using DBUS for these things is an option, but I would prefer a more general solution.
If found a similar question here:
How do I detect the currently focused application?
I modified it ever so slightly to this:
cur_window = the_display.get_input_focus().focus
cur_class = None
while cur_class is None:
cur_name = cur_window.get_wm_name()
cur_class = cur_window.get_wm_class()
if cur_class is None:
cur_window = cur_window.query_tree().parent
and now it works.