Signals and Slots PyQt - pyqt

I came across some new way of connecting signals and slots in PyQt. Please have a look at this link. How to capture output of Python's interpreter and show in a Text widget?. Here the textWritten(signal)=self.normalOutputWritten(function) are connected directly. It is working. Can someone elaborate on this new way of connections.
Rephrasing the question:
How to capture output of Python's interpreter and show in a Text widget?.
In the above link, testWritten is defined as pyqtSignal and self.normalOutput is the slot function. Usually, we connect using the old or new styles but here they just used the '=' symbol. It is working. Please explain this new way.

When you create some PyQt object, you can set properties and connect signals uising keyword arguments to __init__(), e.g.:
button = QtGui.QPushButton(clicked=on_click, text='My button', checkable=True)
For more info see:
PyQt Support for Qt Properties
Frequently overlooked (and practical) PyQt4 features

Related

pywinuto - click_input() function clicks on random node of tree view

I'm trying to automate the mmc (snap in console) type desktop app. Where I need to expand the tree.
Try 1 -
But when I do use expand() function it generates error popup which says that "the child nodes does not exists". After this script simply stops with no error message on console unless ok button is clicked on error popup. This I suspect because when tree node expanded it triggers some event which brings child nodes under it and somehow pywinauto is not getting Childs of this node. Please note that this error popup does not come up when the step is done manually.
Try 2 -
When I tried with select() then too same behavior observed as above. It generated same error popup.
Try 3 -
I tried click() and click_input() functions and it clicks on random tree node but not on the tree node on which it is called.
The all above trials are of my application which is not public.
For reproducing this issue I have tried it on common application available on windows OS. And we can see that the 3rd is still reproducible.
Reference code -
import time
from pywinauto.application import Application
from pywinauto import Desktop
app = Application().start(r'cmd.exe /c "C:\Windows\system32\perfmon.msc"', wait_for_idle=False)
app = Application(backend="win32").connect(title='Performance Monitor', timeout=10)
main_wind = app.window(best_match='MMCMainFrame', top_level_only=False)
console_wind = main_wind.child_window(best_match="MDIClients").child_window(best_match='MMCChildFrm').child_window(class_name="MMCViewWindow")
tree = console_wind.TreeView # print_control_identifiers()
children = tree.get_item(["Performance","Data Collector Sets"]).expand().get_child("System").expand().get_child('System Diagnostics')
print(children.text())
# below line will select the System Diagnostics
children.select()
time.sleep(4)
# Below line should click on System Diagnostics but it does NOT and same happens for click() function
children.click_input()
Any help will be really helpful in knowing why this click() and click_input() clicks on random tree node and Why expand() and select() method generates the non functional error popup?
Please mention if there is concrete workaround to this.
versions -
Windows OS 10, build 20H2
Python 3.10.4
comtypes 1.1.11
pip 22.0.4
pywin32 303
pywinauto 0.6.8
setuptools 61.2.0
six 1.16.0
wheel 0.37.1
TIA..
I have referenced some stack overflow and github issue tracker as for this problem as below but nothing works.
Treeview problem
select() for TreeView items (and similar) leads error if this selection calls other dialogs etc
Python: Click by coordinate inside a window
This was all because of incorrect backend API used for snap in control application. Unfortunately my POC I did on win32 API where it worked because I was doing some initial steps manually hence the problem I was facing(explained in try1) was not there and everything was working perfectly fine.
As soon as I switched the backend to UIA it gave me different identifiers for the controls that I used previously. Now I used this identifiers and started using UIA documentation and everything started working smoothly.
Also in my investigation there is no proper way to identify the backend API for the desktop application unless you try both and figure out which works for you.
Suggestion to readers - If you are using win32 API as backend there are different api methods available for that in the documentation. and for UIA backend different. read documentation carefully.
You can try the uispy tool and find that perfmon.msc can be automated with uia

Unable to use win32com constants to automate powerpoint

I am new to python, trying to automate powerpoint using win32com. I am unable to import or use constants in my scripts. I have ran makepy to create libraries. below is the error messages & script. Can someone tell me how to import constants ?
Script :
import win32com.client
Application =win32com.client.gencache.EnsureDispatch("PowerPoint.Application")
Presentation = Application.Presentations.Add()
Base = Presentation.Slides.Add(1, ppLayoutBlank)
Error messages :
Traceback (most recent call last):
File "ppt.py", line 14, in
Base = Presentation.Slides.Add(1, ppLayoutBlank)
NameError: name 'ppLayoutBlank' is not defined
The INTEROP method you have chosen depends on the application interface to which you are connecting.
Not defined usually means that there is no such variable, but Python more often raises NameError in such cases. So what is exactly happening here is a little unclear.
So, depends on the version of PPoint on how to communicate with it.
I advise you to use pywinauto instead and go for "brute_force", i.e. emulate key presses and/or clicks etc. on right buttons, menues etc.
Because the names of thous is little less likely to change trough out the versions than a COM interface.
Microsoft has a nasty habit of changing just a little bit the interface, and then a program stops working.
If you want to insist on win32com, you will have to read PPoint's documentation for a specific version (or Office version), and for win32com for your Python version.
You should see whether you should start a COM Client or is there some other MS tweak you need to employ.
I'm under Linux now and cannot test here, but try to
import win32com.client.constants
... and then look for the constants defined in that module.
See also How to use win32com.client.constants with MS Word?.

How to, in Python, ignore certain/all keypresses while function executing in program on Macintosh

I would like to know, how would I, in Python, be able to ignore certain/all keypresses by the user while a certain function in the program is executing? Cross platform solutions are preferred, but if that is not possible, then I need to know how to do this on Macintosh. Any help is greatly appreciated! :)
EDIT: Right now, I am processing keypresses through the turtle module's onkey() function since I did create a program using turtle. I hope this helps avoid any confusion, and again, any help is greatly appreciated! :)
You might want to modify your question to show how you're currently processing key-presses. For example is this a command-line program and you're using curses?
You could use os.uname to return the os information or sys.platform, if that isn't available. The Python documentation for sys.platform indicates that 'darwin' is returned for OSX apple machines.
If the platform is darwin then you could, in your code, ignore whatever key-presses you want to.
Edit (Update due to changed question):
If you want to ignore key-presses when a certain function is being called you could either use a lock to stop the key-press function call and your particular function being executed together.
Here is an example of using a lock, this may not run, but it should give you a rough idea of what's required.
import _thread
a_lock = _thread.allocate_lock()
def certainFunction():
with a_lock:
print("Here's the code that you don't want to execute at the same time as onSpecificKeyCall()")
def onSpecificKeyCall():
with a_lock:
print("Here's the code that you don't want to execute at the same time as certainFunction()")
Or, depending on the circumstances, when the function which you don't want interrupting with a key press is called, you could call onkey() again, with the specific key to ignore, to call to a function that doesn't do anything. When your particular function has finished, you could call onkey() again to bind the key press to the function that processes the input.
I found similar problems, maybe it will help you with your problem:
globally capture, ignore and send keyevents with python xlib, recognize fake input
How do I 'lock the keyboard' to prevent any more keypresses being sent on X11/Linux/Gnome?
https://askubuntu.com/questions/160522/python-gtk-event-ignore

Can I alter Python source code while executing?

What I mean by this is:
I have a program. The end user is currently using it. I submit a new piece of source code and expect it to run as if it were always there?
I can't find an answer that specifically answers the point.
I'd like to be able to say, "extend" or add new features (rather than fix something that's already there on the fly) to the program without requiring a termination of the program (eg. Restart or exit).
Yes, you can definitely do that in python.
Although, it opens a security hole, so be very careful.
You can easily do this by setting up a "loader" class that can collect the source code you want it to use and then call the exec builtin function, just pass some python source code in and it will be evaluated.
Check the package
http://opensourcehacker.com/2011/11/08/sauna-reload-the-most-awesomely-named-python-package-ever/ . It allows to overcome certain raw edges of plain exec. Also it may be worth to check Dynamically reload a class definition in Python

Application to accept arguments while running

I am using visual studio 2008 and MFC. I accept arguments using a subclass of CCommandLineInfo and overriding ParseParam().
Now I want to pass these arguments to the application while running. For example "test.exe /start" and then to type in the console "test.exe /initialize" to be initialized again.
is there any way to do that?
Edit 1: Some clarifications. My program starts with "test.exe /start". I want to type "test.exe /initialize" and initialize the one and only running process (without closing/opening). And by initialize I mean to read a different XML file, to change some values of the interface and other things.
I cannot think of an easy way to accomplish what you're asking about.
However, you could develop your application to specifically receive commands, and given those commands take any actions you wanted based upon receiving them. Since you're already using MFC, you can do this rather easily. Create a Window (HWND) for your application and register it. It doesn't have to be visible (this won't necessarily make you application a GUI application). Implement a WndProc, and define specific messages that you will receive based on WM_USER + <xxx>.
First and obvious question is why you want to have threads, instead of processes.
You may use GetCommandLine and CommandLineToArgvW to get the fully formatted command line. Detect the arguments, and the call CreateProcess or ShellExecute passing /watever to spawn the process. You may also want to use GetModuleBaseName to get the name of your own EXE.

Resources