Get the name of a window using Windows API - python

I am new to python and I am trying to write a script that exits out of a loop when a certain window closes. I am having problems getting the code to work properly it won't even enter the loop. I think this is because I am not properly getting the window name. I was wondering if there are any good tutorials on the Win32Gui extension that would help me to understand how it works.
Edit
Here is what I have, it is doing what it is suppose to do, but I am sure there is an easier way of doing it.
def answerCalls(local, network):
t = 0
count = 0
while t == 0:
time.sleep(1)
if win32gui.GetWindowText(win32gui.GetForegroundWindow()) == "Incoming Call":
time.sleep(10)
getApplicationPos("Incoming Call")
clickOnElement(******.IncomingCall_AnswerButton())
time.sleep(10)
if win32gui.GetWindowText(win32gui.GetForegroundWindow()) == "Video Call":
count += 1
writeFile("Answering Calls", count, local)
uploadToServer(local, network)

The following example (Python 3) gets a list of the titles of all the windows:
import win32gui
def enum_window_titles():
def callback(handle, data):
titles.append(win32gui.GetWindowText(handle))
titles = []
win32gui.EnumWindows(callback, None)
return titles
titles = enum_window_titles()

Related

Python Pyautogui: Why doesn't he right click in my code?

I have made a script that checks 100 times whether an image can be detected. He clicks it if it is seen in the last if statement. But a few things are going wrong here.
1: He doesn't right-click what I do.
2: after clicking my script closes immediately!
What did I do wrong? and how do I fix this?
This is my code
import os
import pyautogui
import time
import subprocess
def openprogram():
#opens program
subprocess.call(["cmd", "/c", "start", "/max", "D:\FarmHelper3.exe"])
def inloggen():
#searches for image 100 times to login
for _ in range(100):
time.sleep(1)
coords = pyautogui.locateOnScreen('images/login.png')
#if he has not found the photo within the program
if coords == None:
print ("Geen login gevonden")
#if the picture is found
if coords != None:
print ("Login gevonden")
pyautogui.rightClick(coords)
openprogram()
inloggen()

Trying to ensure that correct window is active right now

I'm trying to assert that the currently needed browser window is opened via selenium.
My approach is to compare titles of the windows to each other, and if title doesn't match - switch to the next window and repeat procedure. But right now check of the last window (which is correct) doesn't happen.
Method for collecting all opened browser windows:
def collect_windows(self):
windows = []
try:
for handle in self.driver.window_handles:
windows.append(handle)
return windows
except:
self.log.error(format_exc())
Method that runs through the list and checks titles of the windows:
def switch_window(self, window_title=''):
windows_list = self.collect_windows()
try:
for window in windows_list:
title = self.driver.title
if window_title not in title:
self.driver.switch_to.window(window)
self.log.info(f"Switched to window: {window_title}")
except:
self.log.error(format_exc())
Instead of comparing titles compare the window handles
def get_current_window_handle(self):
return self.driver.current_window_handle
def switch_window(self, current_handle):
for handle in self.driver.window_handles:
if handle != current_handle:
self.driver.switch_to.window(handle)
self.log.info(f"Switched to window: {self.driver.title}")
return
current_window_handle = get_current_window_handle()
# open new window
switch_window(current_window_handle)

Python PDB won't stop

I have a [large] program which has suddenly started having an issue somewhere in an infinite loop. I cannot find this loop.
I did:
import pdb
pdb.run ( 'main()' )
So when the program enters the infinite loop, I hit control-C and...... it doesn't do anything. In fact, when I don't use pdb, control-C doesn't work either.
I'm not overriding the signals. Even if I do, control-C does nothing.
I ran this in lldb to see if the problem was somewhere in C++-land, and it's not - it's definitely frozen executing python crap (on thread #7 if that matters).
How do I get pdb to actually break on control-c?
Here's a simple 'debugger' that counts the number of times each line is passed over and raises an error when a line is hit too many times. Hopefully it can help find the loop if there really is one.
from bdb import Bdb
from collections import Counter
class LoopDetector(Bdb):
def __init__(self, maxhits):
Bdb.__init__(self)
self.counter = Counter()
self.maxhits = maxhits
def do_clear(self, arg):
pass
def user_line(self, frame):
filename = frame.f_code.co_filename
lineno = frame.f_lineno
key = (filename, lineno)
self.counter[key] += 1
if self.counter[key] >= self.maxhits:
raise ValueError('Too many hits at %s:%s' % key)
LoopDetector(1000).set_trace()
x = 1
y = x + 2
for i in range(200):
y += i
while True: # An exception gets raised here
y -= 1
print 'Does not get here'
This has to be done once per thread since it only affects the current thread.
Take a look in the PDB docs
You should add a breakpoint in you function (main in your example) using pdb.set_trace()
Then you can run the function using the command line (e.g python myprog.py) and the program will stop where you set the breakpoint.
import pdb
def main():
i = 0
while i<10:
print i
if i == 8:
pdb.set_trace()
i += 1
In the example above the the program will stop for debugging when i==8

win32gui get window content (internet explorer_server)

For the extraction of text from a chat window I started off by gathering the window handles.
I managed doing this by the following code:
import time, win32gui
def callback(hwnd, IEServers):
if win32gui.GetClassName(hwnd) == 'Internet Explorer_Server':
IEServers.append(hwnd)
print "IE server found:", hwnd
time.sleep(3)
mainHwnd = win32gui.GetForegroundWindow()
IEServers = []
win32gui.EnumChildWindows(mainHwnd, callback, IEServers)
for serv in IEServers:
print win32gui.GetClassName(serv)
Next thing I want to do is get the content (inner html?) as a string.
I believe it can be done via a IHTMLDocument2 object.
Info: http://support.microsoft.com/kb/q249232
How to do this?
You can try something like this. Maybe not exactly what you want but should get you on your way:
import time, win32gui
import win32com.client
time.sleep(2)
mainHwnd = win32gui.GetForegroundWindow()
s = win32com.client.Dispatch("Shell.Application")
for w in s.Windows():
if int(w.Hwnd) == mainHwnd:
print w.LocationURL
print w.Document.body.innerText
print w.Document.body.innerHTML
break
I think innerText is what you want, but I included several attributes so you can take your pick. This will only work with IE, of course.

How to start a "drawing loop" in PyQt?

Often times when we're drawing a GUI, we want our GUI to update based on the data changing in our program. At the start of the program, let's say I've drawn my GUI based on my initial data. That data will be changing constantly, so how can I redraw my GUI constantly?
The best way that I have found to do this is to run your core program in a QThread and use signals to communicate with your gui. Here is an example where I update a progress dialog as my main program does some stuff.
Here is a code excerpt from a project that I was working on. The basic idea is that I am adding a number of files to a library object and updating the progress as the files are added.
The action is started by the Library class. The tread that does the actual work is in the AddFilesThread.
Let me know if this is helpful. If you need I can try to put together a working example instead of a code excerpt.
If you want to see the full code that I used go here: hystrix_library.py. The diaglog class that I used is in that file. I can't say that this is necessarily the best way to do things, but it works well and is fairly easy to read.
class Library(QtCore.QObject):
"""
This class is used to store information on the libraries.
"""
def __init__(self):
QtCore.QObject.__init__(self)
def importUrls(self, url_list):
# Create a progress dialog
self.ui_progress = AddUrlsProgressDialog()
self.ui_progress.show()
self.ui_progress.raise_()
# Create the add files thread object.
self.add_files_thread = AddFilesThread()
# Connect the thread to the dialog.
self.connect(self.add_files_thread
,QtCore.SIGNAL('updateDialog')
,self.ui_progress.setDialog)
self.connect(self.add_files_thread
,QtCore.SIGNAL('updateValue')
,self.ui_progress.setValue)
self.connect(self.add_files_thread
,QtCore.SIGNAL('finished')
,self.ui_progress.setFinished)
self.connect(self.add_files_thread
,QtCore.SIGNAL('canceled')
,self.ui_progress.closeNow)
# Connect the dialog to the thread
self.connect(self.ui_progress
,QtCore.SIGNAL('cancel')
,self.add_files_thread.cancelRequest)
# Start the thread
self.add_files_thread.start()
class AddFilesThread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self, parent)
self.cancel_request = False
def __del__(self):
self.wait()
def run(self):
try:
self.main()
except:
print 'AddFilesThread broke yo.'
self.cancelNow(force=True)
traceback.print_exc()
def main(self):
num_added = 0
for local_path in self.path_list:
# First Setup the dialog
status_label = 'Finding files to add . . .'
dialog_update = (status_label, (0,0), 0)
self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)
# Do a recursive search.
all_files = hystrix_file.getFiles()
num_files = len(all_files)
if self.cancelNow():
return
status_label = '%d files found.\nExtracting tags . . .' %(num_files)
dialog_update = (status_label, (0,num_files), 0)
self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)
num_added = 0
for index, filename in enumerate(all_files):
try:
metadata = hystrix_tags.getMetadata(filename)
# Here I would add the metadata to my library.
except:
traceback.print_exc()
print('Could not extract Metadata from file.')
continue
# This should be sent to a progress widget
if index % 1 == 0:
self.emit(QtCore.SIGNAL('updateValue'), index)
# Check if a cancel signal has been recieved
if self.cancelNow():
return
status_label = 'Finished. Added %d files.' %(num_added)
dialog_update = ( status_label, (0,num_added), num_added)
self.emit(QtCore.SIGNAL('updateDialog'), dialog_update)
self.emit(QtCore.SIGNAL('finished'))
def cancelRequest(self):
self.cancel_request = True
def cancelNow(self, force=False):
if self.cancel_request or force:
self.emit(QtCore.SIGNAL('canceled'))
return True
else:
return False
You could create a thread to update the GUI constantly, just pass to it references to the graphical widgets that need to be updated

Categories