I made a simple PyGTK - Glade GUI for an application. I made the button, and the on_button_click calls a bash script.
I would like to show a popup window while the bash script is running, and hide it after it is done. I made the window called runningWindow in Glade and wrote the following code:
def on_button1_clicked(self,widget):
self.glade.get_object("runningWindow").show()
os.system('bash run.sh')
self.glade.get_object("runningWindow").hide()
This code shows nothing while run.sh is running. If I remove the hide() line, the window is displayed correctly, but only AFTER the run.sh process has finished.
The init function that starts the GUI:
def __init__(self):
self.gladefile = "MyFile.glade"
self.glade = gtk.Builder()
self.glade.add_from_file(self.gladefile)
self.glade.connect_signals(self)
self.glade.get_object("MainWindow").show_all()
How can I display the window before the os.system is called?
Thank you for your help!
You probably want to look into the subprocess module, and run your subprocess in a background task.
I couldn't solve the problem, but I could get around it. Maybe others find it useful:
First, one should use subprocess.Popen() instead of subprocess.call(). It puts the subprocess automatically in background, so the running window is displayed. The problem was that if I didn't remove the .hide() command, the window immediately disappeared after popping up. Otherwise, I couldn't hide the window when the run was finished.
To solve this, I created the runningWindow in a new (runningWindow.glade and runningWindow.py) file.
Then I created a wrapper bash script that says:
python runningWindow.py &
pid=$!
bash run.sh
kill pid
And called this bash script with subprocess.Popen() from the main python script.
Related
I put together a simple script to encode movies, now while the script works just fine I am having difficulties on changing the window title on script start instead on when its terminated. since is kind of useless to mark each window after it finished. can I use subprocess to perform such task? so change the title while the script runs?
I am using this in a bash script to change the title:
PS1="\e]2;$1\a\[$1 \W]\$"
if you are running the sub process without invoking any new terminal , you can rename the windows with below code
# your subprocess code here
import sys
sys.stdout.write(b'\33]0;title you want\a')
I am trying to create a py.test plugin to reproduce Pydev for Eclipse behaviour, that you can see on the image below:
Basically, the idea would be to open an empty window during the call to pytest_sessionstart(), to fill it (update list of tests and progress bar) with objects returned by pytest_runtest_makereport(), and to close it with pytest_unconfigure().
I tried to achieve this with Tkinter, by using the following code:
import Tkinter
def pytest_sessionstart(session):
print "Tests are starting"
Tkinter.Tk().mainloop()
print "The window was opened" # This step is never reached
When running the tests, it prints the first sentence, opens the window but doesn't come back to py.test until we close the window.
If I remove the call to mainloop(), the window is opened but instantly destroyed.
I also tried to open the window in a separate thread by doing:
t = threading.Thread(target=Tkinter.Tk().mainloop())
but without success. Anyway, the threading option doesn't seem very good as Tkinter has to run in the main thread, which is not possible in the case of a py.test plugin.
So, does any of you have an idea about how to solve this problem? The only requirement is to keep py.test.
Thank you in advance :)
Tkinter.Tk().mainloop() is a while True loop. You won't be getting out of it. There are two ways to solve your problem in my opinion:
Use pytest inside Tkinter app. You can invoke pytest within the tkinter code like this.
Use pytest in different thread and pipe the output of pytest to Tkinter app.
I am learning python and for GUI model using wxpython, as I am new to programing get stuck every time.
My issue is I have a GUI (main window)with two buttons,when user clicks button1 it opens sub window (seperate python script), I want to close or destroy main window before opening sub window.
self.Destroy()
subprocess.call("python newframe.py",shell=True)
#It will not close main window
What will be the wrong i am trying to do , and please explain what is proper method.
Looking for suggestions thanks .
Sorry for my english .
subprocess.call() wait subprocess to exit. -> button callback will never return until subprogram exit. This keep main window to close. Use subprocess.Popen() which does not wait subprocess.
self.Destroy()
subprocess.Popen('python newframe.py', shell=True)
You shouldn't close the main frame or you'll actually exit the application. Instead you should Hide the main frame and just Show the sub-frame. Then when you close the sub-frame, you can re-show the main frame. I personally think using Pubsub is the easiest way to accomplish this. Here's a link to a tutorial that shows how to do it:
http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
You could also pass a reference to the main frame when you instantiate the sub-frame or call something like GetTopWindow() or GetParent(), but I really recommend Pubsub for this.
If I'm trying to create a window or prompt a file dialog in the IDLE shell, nothing opens and the shell restarts. Is this a bug of some kind? I can't find anything about it. I'm new to PyQt (and Python in general) but had been able to get tutorials to work correctly. The last day or so, if I open IDLE and import PyQt4, QtGui, etc and then run something simple like QFileDialog.getOpenFileName, the shell just restarts. Any ideas?
You need to have a QApplication before you can use anything else from PyQt. Try rereading some of the tutorials you followed, or do a few more. This one for example.
In the first code sample of the above tutorial, pay special attention to these lines (I've included the comments from the tutorial for convenience):
app = QtGui.QApplication(sys.argv)
Every PyQt4 application must create an application object. The
application object is located in the QtGui module. The sys.argv
parameter is a list of arguments from the command line. Python scripts
can be run from the shell. It is a way, how we can control the startup
of our scripts.
and
sys.exit(app.exec_())
Finally, we enter the mainloop of the application. The event handling
starts from this point. The mainloop receives events from the window
system and dispatches them to the application widgets. The mainloop
ends, if we call the exit() method or the main widget is destroyed.
The sys.exit() method ensures a clean exit. The environment will be
informed, how the application ended.
The exec_() method has an underscore. It is because the exec is a
Python keyword. And thus, exec_() was used instead.
It appears you might have forgotten about these. Or maybe you haven't realized that this means that you normally can't use PyQt with a running event loop in the interactive shell. However, there is a trick for that, see here.
I have a Tk python program that creates a list of python files in the current directory and generates a button for each of them. When you click a button the corresponding python program is launched via subprocess in a new gnome-terminal. I'd like to switch the button's color to red after the subprocess has finished executing on the new terminal. Unfortunately, the button is changing color almost immediately.
from Tkinter import *
import os, subprocess
root = Tk()
buttonsD = {}
def launch(ourfile):
p=subprocess.Popen(["gnome-terminal","-e","python " + ourfile], shell=False)
buttonsD[ourfile].configure(bg='red')
dirlist=os.listdir(os.getcwd())
for fname in dirlist:
if fname.endswith('py') and fname != 'gui2.py':
buttonsD[fname] = Button(root,text=fname,command=lambda i=fname: launch(i))
buttonsD[fname].pack(side=TOP,expand=YES,fill=BOTH)
root.mainloop()
Almost immediately means that I can wait while p.poll == None, and see that it takes a moment for gnome-terminal to be created. But as soon as the terminal is created the button goes red, even though a process is still running in the new terminal. I can't create a new gnome-terminal and then communicate the process I'd like to run either. It seems gnome-terminal just creates a new instance of bash and then returns done, so there's a pipe error if I try to communicate to its stdin.
I believe gnome terminal is doing a double fork, in order to detach itself from the process group of its parent -- so what's actually your subprocess terminates almost immediately, as you observe, and everything is happening in a further descendant that you have no direct access to.
Unfortunately I don't believe gnome terminal offers any way to disable this double fork behavior; so, to find out when the "further descendant" is finished, you'll have to identify that process and monitor it periodically. Interacting directly with it is also a pretty tall order -- no easier than interacting with any "random" process you're not related to:-(.
There are two questions here: what command line to use to launch a Python program in gnome-terminal, and how to use subprocess in a Tkinter app. I only know about the latter.
subprocess.Popen returns immediately, which is why the button is turning red immediately. I think you probably need to make a list of which programs are running. Then write a function poll_processes which calls poll() on each running process, and when the result is not None, removes it from the list and turns the button red.
Then all you have to do is arrange for Tkinter to periodically call that function, which you can do by calling frame.after(msec, poll_processes) to schedule the first call to poll_processes and then having poll_processes do the same thing to schedule the next call.