Getting the content of a window to a text file - python

I'm trying to use HwndWrapper.Texts() which supposedly "Returns the text for each item of this control" but it only returns the tile which is u'Fight plan settings dialog', why is this happening?
The code is this:
prog=application.Application()
prog.connect_(path=r'D:\Thesis\Euroscope\Euroscope.exe')
w_handle = pywinauto.findwindows.find_windows(title=u'Fight plan setting dialog', class_name='#32770')[0]
window = prog.window_(handle=w_handle)
c=prog.Fightplansettingsdialog.Texts()
Here is a screen of the window I'm trying to copy from:
http://imageshack.us/photo/my-images/802/newpicturewe.png/
I spent the afternoon reading the pywinauto documentation and i can't manage to find a way to get the content of a window like the one before into a text file(except clicking and copying each item with DoubleClick() and then Ctrl+C with TypeKeys which is way too long). Any ideas?
Edit: Also, I found out that PrintControlIdentifiers can't be easily saved to a strings file. Doing c=prog.PrintControlIdentifiers() returns None when i ask for c. Any way around this?
Thank you

You may get all texts from a window by running through all children.
all_texts = []
for child in window.Children():
all_texts.extend(child.Texts())
all_texts = filter(lambda t:t, all_texts) # clear empty texts
By the way, it seems the window should be called 'Flight plan...' :-)
PS.
I am happy to help a virtual controller!
UKHH - MDN91

Related

How can I make sikulix type the text I've extracted from an image?

I want to make my program take a screenshot of a region, read the text on the image (I've completed this part) and type it out with keypresses (This is the part I need help with)
So far I have this:
a=find(This is where I put my screenshot).text()
print a
This takes a screenshot, reads it for text and prints the text in the message box.
How do I turn that output into keypresses?
switchApp("textedit") # put the target window to foreground
for x in a:
type(x)
RaiMan from SikuliX (you might have to learn some Python basics and look into the SikuliX docs)

Use "Relink to File" button in Photoshop using Python

I would like to relink a Photoshop Smart Object to a new file using Python.
Here's a screenshot of the button that's used in Photoshop to perform this action - "Relink to File":
I've found some solutions in other programming languages but couldn't make them work in Python, here's one for example: Photoshop Scripting: Relink Smart Object
Editing Contents of a Smart Object would also be a good option, but I can't seem to figure that one out either.
Here's a screenshot of the button to Edit Contents of a Smart Object:
So far I have this:
import win32com.client
psApp = win32com.client.Dispatch('Photoshop.Application')
psDoc = psApp.Application.ActiveDocument
for layer in psDoc.layers:
if layer.kind == 17: # layer kind 17 is Smart Object
print(layer.name)
# here it should either "Relink to File" or "Edit Contents" of a Smart Object
I have figured out a workaround! I simply ran JavaScript in Python.
This is the code to Relink to File.... You could do a similar thing for Edit Contents but I haven't tried it yet, as relinking works better for me.
Keep in mind the new_img_path must be a raw string as far as I'm aware, for example:
new_img_path = r"C:\\Users\\miha\\someEpicPic.jpg"
import photoshop.api as ps
def js_relink(new_img_path):
jscode = r"""
var desc = new ActionDescriptor();
desc.putPath(stringIDToTypeID('null'), new File("{}"));
executeAction(stringIDToTypeID('placedLayerRelinkToFile'), desc, DialogModes.NO);
""".format(new_img_path)
JavaScript(jscode)
def JavaScript(js_code):
app = ps.Application()
app.doJavaScript(js_code)

yview_moveto going to incorrect position when used after updating ScrolledText contents

I am making a software that involves making a text editor that the contents are being updated very often (every time the user types something it syncs the values in the text with something else)
The way that I do this is by saving the cursor position and scrollbar position and text (it is a ScrolledText widget)
self.scroll_data = self.text.yview()
text = self.text.get("1.0", tkinter.END)[:-1]
cursor = self.text.index(tkinter.INSERT)
After putting the text through the function that syncs it, I now have the string that should be in the ScrolledText widget (self.text)
Now That I have the text That should be in the widget I do this to put the text in and have it look to the user like nothing happened by replacing the text and resetting the cursor position and scroll bar position
self.text.delete("1.0", tkinter.END)
self.text.insert("1.0", self.mod.get_text()) # self.mod.get_text() is the text that we want
self.text.mark_set("insert", str(cursor))
self.text.yview_moveto(self.scroll_data[0])
I then call self.root.update() because I want the window the show the changes.
This is where I am having the problem, for some reason, because I am moving the scrollbar after resetting the text but not updating, it causes a weird bug where the scrollbar inches up whenever I type something. This doesn't happen every single time I tried it in the past but even old version are having this issue for me right now.
I way I found that somewhat fixes the issue is to call self.root.update() on the line before self.text.yview_moveto(self.scroll_data[0]) but that causes a visual glitch where the text jumps to the top for a short period of time every time you type a character.
Because it goes to the correct scrolling position when I do that it leads me to believe that it is a problem with calling yview_moveto before updating the screen after deleting and setting text.
This script is an example of the bug in action:
import tkinter
import tkinter.scrolledtext
root = tkinter.Tk()
x = tkinter.scrolledtext.ScrolledText(root)
x.pack()
last_text = ""
while True:
text = x.get("1.0", tkinter.END)[:-1]
changed = text != last_text
if changed:
text = "a" + text
scroll_data = x.yview()
cursor = x.index(tkinter.INSERT)
x.delete("1.0", tkinter.END)
x.insert("1.0", text)
x.mark_set("insert", cursor)
x.yview_moveto(scroll_data[0])
last_text = text
root.update()
If anyone knows how to solve this issue I would greatly appreciate if you would share your solution with me so I can ensure a smooth user experience for anyone using my tool
(this is a link to the github repo with my project https://github.com/hippolippo/Unity-Mod-Maker)
EDIT: I found out that the reason this happens is because some of the lines of text get automatically pushed to the next line because they are too long to fit on the screen. I still don't have a solution however

How to create PDFOutline programmatically

I'm having trouble trying to create Table of Contents objects in a PDF file. I'm not sure whether I've understood the process from Apple's limited documentation.
I'm using python, but cogent examples in any language are welcome to explain how it's supposed to work. The code creates a new PDF document, but there's no outline item visible in Preview. I've tried just using myOutline as the root object, but that doesn't work either.
pdfURL = NSURL.fileURLWithPath_(infile)
myPDF = Quartz.PDFDocument.alloc().initWithURL_(pdfURL)
if myPDF:
# Create Destination
myPage = myPDF.pageAtIndex_(1)
pagePoint = Quartz.CGPointMake(0,0)
myDestination = Quartz.PDFDestination.alloc().initWithPage_atPoint_(myPage, pagePoint)
# Create Outline
myOutline = Quartz.PDFOutline.alloc().init()
myOutline.setLabel_("Interesting")
myOutline.setDestination_(myDestination)
# Create a root Outline and add the first outline as a child
rootOutline = Quartz.PDFOutline.alloc().init()
rootOutline.insertChild_atIndex_(myOutline, 0)
# Add the root outline to the document and save
myPDF.setOutlineRoot_(rootOutline)
myPDF.writeToFile_(outfile)
EDIT: Actually, the outline IS getting saved to the new file: I can read it programmatically, and it appears in Acrobat as a Bookmark; however, it doesn't show up in Preview's Table of Contents (yes, I checked for the "Hide" thing). If I add another Bookmark in Acrobat, then both show up in Preview.
So I guess that either I'm still doing something wrong which doesn't quite 'finish' the PDFOutline data properly, and Acrobat is being kind; or there's a massive bug in PDFKit that means you can't write PDFOutlines properly. I get the same behaviour on Mountain Lion, FWIW.
This does appear to be a bug in Preview. It will not list the Table of Contents if it contains ONLY ONE child entry.
If I add more Outlines with the code above, then all of them appear in Preview. If use other software to remove all but one entries in the Table of Contents, then Preview will not show any.

Printing main window in PyQt

I need to be able to save the main window of a pyqt app in a PS or similar file format so that I can send it to a printer. I would just make a built in screen shot function but my main window exceeds the size of my screen. Anyone know of a way to capture the window in it's entirety or is there a prebuilt class that could do this?
QPixmap has the static method grabWidget.
Pointing this method at your window will give you a pixmap that you can save to a file or use for printing.
If calling from inside your main window class:
sshot = QPixmap.grabWidget(self)
sshot.save('sshot.png')
QPixmap.grabWiget has been deprecated. We can instead use QWidget.grab() function instead to capture window. However, it only captures the currently visible parts of the screen which can be a problem when you have a window with a scroll area. So the only method/hack that worked for me was to use ScrollArea's page step functionality paired with widget grab.
# Get total pages in window
page_count = self.scrollArea.verticalScrollBar().maximum() / self.scrollArea.verticalScrollBar().pageStep()
image_list = []
# iterate through each page step
for i in range(int(round(page_count)) + 1):
step = self.scrollArea.verticalScrollBar().pageStep() * i
self.scrollArea.verticalScrollBar().setValue(step)
# capture and save each image
self.scrollArea.grab().save(f"page - {i}.jpg", quality=100)
# convert all images to Pillow Image() to later convert to pdf
image_list.append(Image.open(f"report_page - {i}.jpg"))
# save as pdf file
pdf_file_name = f'pdf_file.pdf'
image_list[0].save(pdf_file_name, "PDF", resolution=100.0, save_all=True, append_images=image_list[1:])
# delete images if not neccessary
for i in range(len(image_list)):
os.unlink(f"page - {i}.jpg")
P.s. Please let me know if there a more elegant solution to this problem

Categories