QApplication instance causing python shell to be sluggish - python

My IPython shell becomes sluggish after I instantiate a QApplication object. For example, even from a fresh start, the following code will make my shell sluggish enough where I have to restart it.
from PyQt4 import QtGui
app = QtGui.QApplication([])
As soon as that is submitted, my typing becomes lagged by 2 or 3 seconds. My computer is not fantastic, but I still have plenty of available memory, and it's only the python shell that seems to be affected. I've tried both the default python interpreter and the ipython interpreter with the same results. Any suggestions?
Update: I also tried running a standalone pyqt "Hello World" program in ipython using the %run magic command and when control was returned to ipython after I closed the resulting "Hello World" window, it had the same effect; the shell became sluggish and my typing starting lagging by 2-3 seconds.

This may help:
QtCore.pyqtRemoveInputHook()
When the QtCore module is imported for the first time it installs a
Python input hook (ie. it sets the value of Python's PyOS_InputHook
variable). This allows commands to be entered at the interpreter
prompt while the application is running. It is then possible to
dynamically create new Qt objects and call the methods of any existing
Qt object.
The input hook can cause problems for certain types of application,
particularly those that provide a similar facility through different
means. This function removes the input hook installed by PyQt.
The input hook can be restored using the pyqtRestoreInputHook()
function.
http://www.riverbankcomputing.com/static/Docs/PyQt4/html/qtcore.html#pyqtRemoveInputHook

Related

Run a module in IDLE (Python 3.4) without Restart

It appears that, in the past, IDLE did not restart (clean the environment) when you ran a script (module). Today, however, this is the case. But for prototyping I would like the environment (assigned variables, imported modules, functions, ...) to survive running different modules (files).
Example: I am working on a function, let's call it f7(), that requires a certain environment. The environment is built in another script (file), say, env1.py. After env1.py has been run, I can built on all imported modules, defined functions and assigned variables, when working at the command line of IDLE. But I cannot run another file, where my f7() resides! I would have to redefine f7() at the interpreter's command line. Which I of course do not do, because f7() is very lengthy. The only thing that remains is to include f7() in env1.py. And restart it after every change to f7(). As a consequence, I have to wait each time until env1.py has finished. Which is a waste of time, because every time it runs, it does the same. I only change f7()...
Can I tell IDLE not to restart (clean environment) each time I run a module (file) in IDLE? If not, what alternatives to IDLE are capable of something like this??
It seems IDLE behaves the same on Windows, Ubuntu, Raspbian. I am using Python 3.X on each of these systems.
I am not aware that IDLE ever didn't restart when running a editor file, so that would have to have been several years ago. I will think about it as a new feature though.
EDIT: Added in June 2019: On the editor Run menu, Run... Customized opens a dialog with [X] Restart. Uncheck that box and the restart is skipped.
END EDIT
In the meanwhile, you can do this for the specific scenario you gave. Load env1.py into an editor window and run it. When >>> appears, enter or paste the def statement for f7 and run it. (Paste after loading the file with f7 and copy.) Test by calling f7. To edit the definition of f7, recall it to the current >>> line. Either click on the previous definition and hit Enter or use the history keyboard shortcuts (for me on Windows, Alt-P for Previous, Alt-N for Next). In either case, edit and re-run. Do the same with test statements. I recall and edit statements routinely.

Using os.system() in Python is open a program, can't see window of launched program

I am trying to launch a program/GUI from within a python code.
From the terminal, I can get the program to launch by simply typing the program name. A few lines get outputted to the terminal, and then a separate window opens with the GUI.
I tried to emulate this in python by running
os.system("<program name>")
The typical output lines, as mentioned above, get printed to the console, but no window opens up with the GUI.
Can os.system() be used to execute programs that have their own separate window?
From the Python manual:
[os.system] is implemented by calling the Standard C function
system()
That being said, you shouldn't have any problems launching a GUI application with os.system. I've just tried it myself and it works fine.
It also mentions in the manual that:
The subprocess module provides more powerful facilities for spawning
new processes and retrieving their results; using that module is
preferable to using this function.
Maybe that's worth a try. Do any other GUI applications work when you spawn them with os.system?
Here is a solution using subprocess
import subprocess
subprocess.Popen("notepad.exe")
Or if you want to run a python program with a specific interpreter:
subprocess.Popen('{0} {1}'.format(PythonInterpreterPath,PythonFilePath.py))

How to stop console from poping up when command is called from python GUI?

I have made a GUI for my application. All scripts are in Python (2.7) and the GUI is created with Tkinter. I work on Linux, but I needed this app to be executable on Windows. So I've used py2exe, to create an executable. After a while it is working almost perfectly, but I have the following problem:
Somewhere in the application, I need to call external programs, namely ImageMagick and LaTeX. I use the commands convert, pdflatex, simply by importing os module and running os.system(build), where build = 'convert page.pdf page.gif'etc. When those commands are called from the *.exe application the console pops up (meaning a console window opens up for a split of a second and closes again). Is there a way, to prevent this behaviour?
It does not interrupt the application, but it is ugly and not a desired behaviour.
[Note] I chose not to add any samples, since there are lots of files and other content, which, I think, is not related to the problem. I could however try to post minimal (not)working example. But maybe it is not needed.
Thanks!
import subprocess
subprocess.Popen("application.exe", shell = True)

Apple Python launcher is acting on command key bindings

I've written a Python utility that uses tkinter. I'm running it on a Macintosh. When it is executed, it runs within an apple-supplied Python launcher program (/Library/Frameworks/Python.framework/Versions/3.2/Resources/Python.app).
My code installs its own menus and I bind to the usual Macintosh command-key equivalents for my edit menu (Command-x, command-c, command-x, command-a, command-z) and for quitting (command-q). My problem is that the Python launcher program is responding to the command key bindings. This is inconvenient for things like pasting because it gets done twice. It's a real problem with quitting because the launcher program kills my program before I can save changed files.
Is there some way I can stop the Python launcher program from acting on command key equivalents? I attempted this: "rootWindow.unbind ('<Command-Key-q>')", but to no avail. The launcher program quits before my code can clean up.
I'm using CPython 3.2 on OS X 10.6.6.
Instead of overriding Tkinter's default key bindings, consider re-mapping Tcl's "exit" command to a custom function. (This is called every time you hit command-q or use the "quit" menu item.)
def save_and_exit():
save_changed_files()
sys.exit()
self.createcommand('exit', save_and_exit)
Besides that, I would recommend removing your copy/paste custom keybinds and letting the library do the work for you. If you're still hell-bent on overriding the defaults, Effbot has a nice tutorial on Tkinter events and bindings.
Is there a specific reason why you are using Python.app for launching? This .app is most likely the reason for misbehaving shortcuts.
If I have understood correctly, this launcher is just a wrapper for default python (/usr/bin/python) with special imports.
If you run from terminal (-v is the key here):
/Library/Frameworks/Python.framework/Versions/5.1.1/Resources/Python.app/Contents/MacOS/Python -v
You will see what it imports at the beginning. Adding these lines to your main file should make the command line launching the same as with the .app.
Note also that python.app is in version 5.1.1.
br,
Juha
First off, /Library/Frameworks/Python.framework/Versions/3.2/Resources/Python.app is not Apple-supplied. Most likely you installed Python 3.2 using one of the python.org installers here or from some third-party distributor or possibly you built a framework version from source. In any case, Python.app is a dummy application bundle included in each framework version. Its purpose is to ensure that when you invoke python, even from a command line, it is seen by OS X as a full-fledged GUI application. This is particularly important when using tkinter. The default menus and keybindings you see are supplied by Tcl/Tk, not tkinter. As you've discovered, the right way to go about changing these are to remap the default menus. Be aware that there are currently at least three major variants of Tk available on Mac OS X: Aqua Carbon Tk, Aqua Cocoa Tk, and X11 Tk. There are important details, especially with regards to Mac OS X 10.6, about Python and Tcl/Tk on Mac OS X at the python.org website.

How to switch to a python subprocess created by IPython (on OS X)?

When I use IPython along with the -wthread option, it spawns a python subprocess, which appears as a Mac OS X application.
My problem is that when I send commands to that application (for example plotting with matplotlib), the window is updated behind all my other windows. I would like to be able to call a python command to switch this python window to the front (I do that manually with ⌘-tab, but I have to find the python application first, and there might be several ones).
Is there a python script to detect which application IPython has spawned, and how to then automatically switch to it in OS X?
(I'm stating the problem in OS X, but the issue should be similar on other systems).
Edit: let me break this down in two problems:
how to know which Mac OS X application python is running in? (probably possible with some IPython witchery)
how to tell Mac OS X to put the focus on that application? (maybe using applescript)
Could be either:
Making a new python script that tracks grandchild processes of another script might be tricky. The IPython documentation has an example to monitor spawned processes by pid; JobControl. JobControl only kills the processes but I imagine adding a command to change window focus would be fairly easy.
From what I've read, the Tk gui does not properly set window focus on macs. If your 'matplotlib' or otherwise uses the Tk gui, this may be the problem. -source-
I am not very familiar with OS X, so either run with those, clarify your situation or let me know if I'm too far off.
Here is my full solution, with an IPython magic function.
Install appscript (see this question about switching apps programmatically in OS X), and put the following code in a script called activate.py in your ~/.ipython folder.
import appscript
import sys
appscript.app(pid=int(sys.argv[1])).activate()
Now, edit your ~/.ipython/ipy_user_conf.py configuration file and define the magic function:
def wxactivate(self, arg):
import wx
pid = wx.GetProcessId()
ip = self.api
import os
here = os.path.dirname(__file__)
import subprocess
subprocess.Popen([os.path.join(here, 'activate.py'), str(pid)])
Now you just have to register this magic IPython function by putting the following somewhere in that same configuration file:
ip.expose_magic('wxactivate', wxactivate)
Now, after you run IPython -wthread, you can call %wxactivate and you will switch to the corresponding Python application!
(note that the reason why one has to run the call to appscript's activate() in another process in not clear to me; it may have to do with some threading problem... any explanation would be appreciatated)

Categories