I am experiencing different behaviour on the same code using the python console and a python script.
The code is as follows:
import gtk
import webkit
win = gtk.Window()
win.show()
web = webkit.WebView()
win.add(web)
web.show()
web.open("http://www.google.com")
When running the code in the python console, the output is a new frame that contains the google main page.
When running the code as a script, the result is a void frame. It closes very fast but even if I use a delay function, the webkit is not added to the frame.
How is it possible?
Furthermore, using PyDev IDE it flags: "unresolved import: gtk",
but if i run the project, the program starts without problem of compilation. is it normal?
Add
gtk.main()
to the end of your script. This starts the gtk event loop.
import gtk
import webkit
class App(object):
def __init__(self):
win = gtk.Window()
win.connect("destroy", self.destroy)
web = webkit.WebView()
web.open("http://www.google.com")
win.add(web)
web.show()
win.show()
def destroy(self, widget, data = None):
gtk.main_quit()
app = App()
gtk.main()
My guess is that the console keeps the python session open, while at the end of the script the program closes. When the script closes, it takes everything it created with it.
Something to test this theory: if you type "exit" in the console do you see the interface shut down in the same manner? If so, think of some code (e.g. a pause like a raw_input) that will allow the script to stay open.
Good luck!
Related
I am running a wxPython application that does a lot of modules and packages importing at the beginning and gathering information about the computer (network interfaces, internet connection..) so it takes time, and I'm showing a logo in that time until it ends. the problem is that the logo crashes if you press on it (because the importing are on the MainThread and the GUI can't respond to events), How can I show a logo while importing without letting the GUI crash? (I don't want to let the user to click on the Logo anyway)
Inspired by Tim Roberts in this wxPython-users thread I first tried to spin off the splash screen in a separate thread, which did not work (wxwidgets complains it it not in the main thread). So I did the only obvious thing which I should have done in the first place: make the long running at startup a separate thread.
Side effect: As the splash screens now can react to events, it will disappear when clicked on.
import wx
class long_running(object):
def __init__(self):
bitmap = wx.EmptyBitmap(300, 150, 127)
self.mainframe = wx.Frame(None, -1, 'mainframe')
self.splash = wx.SplashScreen(bitmap, wx.SPLASH_TIMEOUT, 20000, self.mainframe)
def start(self):
import time
# mimicking something taking very long time on startup
for i in range(20):
time.sleep(0.5)
print i
wx.CallAfter(self.continue_)
def continue_(self):
#Destroy the splash screen.
if self.splash:
self.splash.Hide()
# self.splash.Destroy()
self.mainframe.Show()
if __name__ == '__main__':
import thread
app = wx.App()
long_rnn = long_running()
# Begin loading the application.
thread.start_new_thread(long_rnn.start, ())
# Application loaded.
app.MainLoop()
In a recent project (on Windows7 and wxPython 2.9.5.1): For displaying a wx.SplashScreen while modules are importing we did the following:
We have a main module, which does import wx in the beginning, create the wx.App and display the splash screen. Only after showing the splash screen we begin to import the "heavy" modules. The very first startup will take 40 seconds. In fact the app will crash if the user clicks on the splash screen. Better said, Windows displays a message box (EDIT2) with "Python.exe has stopped working." If the user clicks "Terminate" the app will in fact terminate/crash. If the user does nothing, the app will start up normally. So on Windows there is no "real" crash. It will also not happen when starting the second time (because things are cached)? On subsequent starts startup time is 5 seconds. Sorry, no real answer but too long for a comment also.
EDIT: Minimum working example added: Click every one or two seconds on the splash while it is displayed to make Windows show the "Python has stopped working" dialog. The dialog will simply go away when long_running() has returned.
# -*- coding: utf-8 -*-
def long_running():
import time
time.sleep(10)
# does not show "Python ... stopped working ..."
#for _ in range(20):
# time.sleep(0.5)
# wx.Yield()
if __name__ == '__main__':
import wx
app = wx.App()
bitmap = wx.EmptyBitmap(300, 150, 127)
splash = wx.SplashScreen(bitmap, wx.SPLASH_TIMEOUT, 20000, None)
# Begin loading the application.
long_running()
# Application loaded.
#Destroy the splash screen.
splash.Hide()
splash.Destroy()
app.MainLoop()
I did a small script on python to do some stuff, and I want to ask user input first. This is my current code:
import sys
from PySide import QtGui
app = QtGui.QApplication(sys.argv)
gui = QtGui.QWidget()
text, ok = QtGui.QInputDialog.getText(gui, "question",
"""please put the thing I need from you""")
print(text, ok)
if ok:
app.exit()
else:
app.exit()
app.exec_()
print ("I'm aliveeeee'")
The dialog pop-ups exactly as I want, but app.exec_() never ends so the rest of the code is never executed (and the process never finish) I tried to kill it with app.exit(), app.quit(), I also try to show() and close() the QWidget, but nothing is working.
If I do gui.show() before calling the QInputDialog and then close the widget manually, the app closes successfully. However, this is not the behavior I want.
Can you guide me on which is the best way to close the exec loop after I got my data?
PD: This is going to be a windows app (with py2exe) and using the shell is not an option.
Just don't call app.exec_()
The problem here is that this is a toy example. In real life, usually you will show some UI and then call app.exec() to let the user interact with it.
I am fairly new to python and have made a simple UI using pyside. When run from inside the anaconda IDE the UI works fine, but when I run it using anaconda from the command line \python.exe 'runquacker.py' the UI flashes up and disappears immediately.
The initial script is:
from PySide.QtCore import *
from PySide.QtGui import *
import sys
import quacker
class MainDialog(QDialog, quacker.Ui_Dialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
self.setupUi(self)
app = QApplication(sys.argv)
form = MainDialog()
form.show()
The rest of the UI is in quacker.py which collects a bunch of variables from the user, before executing a further analysis.py program using a subprocesscall. The variables are all passed in this way because thats the only way I could get pyside to work with my script!
e.g. For two variables 'plots' and 'block':
subprocess.call([sys.executable, 'd:\\py\\anaconda\\analysis.py', str(plots), str(block)], shell=True)
Ive tried putting a raw_input('Blah..') in a few places but it just causes the program to hang or nothing at all.
Using \python.exe -i runquacker.py also causes the program to hang.
Thanks
You need to add this line at the end of your script: app.exec_()
That's because you need to actually execute your Qt application if you whant to see something.
I'm not pretty sure why it works in Anaconda but if you are using some IDE like Spyder I think it works because Spyder is already running in Qt (so it called QApplication.exec_ before).
i have a strange problem. I created a GUI program which runs in "spyder" with WinPython-64bit-3.3.2.3 with no problems, now i want to run it without the console to pop up and i try to use pythonw.exe.
When i save my GUI as gui.pyw i can open it with PythonWin by right clicking and use edit with PythonWin but simply double-clicking will make my GUI pop up for less than a second and exit the program afterwards.
Does this have to do with my GUI programming?
the "structure" is this one:
import sys
from PyQt4 import QtGui, QtCore, Qt
from Main_Window_v2 import Ui_Dialog as Dlg
class MeinDialog(QtGui.QDialog, Dlg):
def __init__(self):
QtGui.QDialog.__init__(self)
self.setupUi(self)
self.connect(self.buttonOK,
QtCore.SIGNAL("clicked()"), self.onOK)
self.connect(self.buttonAbbrechen,
QtCore.SIGNAL("clicked()"), self.onClose)
self.connect(self.buttonsql,
QtCore.SIGNAL("clicked()"), self.onsql)
def onsql(self):
login=self.login_text_box.toPlainText()
from calc import get_variables #sql query
self.get_variables=get_variables(login)
#calls a class´ __init__ in another file in my direcotry
def onOK(self):
login=self.login_text_box.toPlainText()
self.get_variables.plot(login)
#calls another function in my class "calc"
def onClose(self):
print("bye!")
self.close()
app = QtGui.QApplication(sys.argv)
dialog = MeinDialog()
dialog.show()
I also tried to get an .exe using cx_freeze and after trying to making build as described here Cx_Freeze: I have the same problem: The Main-Window of the GUI
pops up and disappears again
Just add app.exec_() at the end of your code. Your code was running well in Spyder because Spyder uses PyQt and had the main loop of events already running.
You should add app.exex_() at the end of your code, it is used to dispatch all PyQt GUI threads message or other threads info message.
I am using wxPython to build the GUI for my application. I built the GUI using wxFormBuilder. But when bring the code into my python application, and launch it the window pops up then closes instantly. I am using the XRC for my GUI as well. I am given no error message in the console either while using PyDev with Eclipse.
Python code to launch GUI: http://pastebin.com/jBYWerd9
XRC code: http://pastebin.com/QVEcuX0i
I think you just need
def main():
app = VisualController(redirect=False)
app.MainLoop() #you need this
return #after calling Mainloop you will not get here until your main window is destroyed
The problem is two-fold. As Joran mentioned, you need to actually create an instance of your App class and call the MainLoop() method. The second piece is that you need to actually load the frame from the XRC file and Show it. Change your code to something like this:
import wx
from wx import xrc
class VisualController(wx.App):
def OnInit(self):
self.res = xrc.XmlResource('data/GUI.xrc')
frame = self.res.LoadFrame(None, "MyFrame1")
frame.Show()
return True
def main():
app = VisualController(redirect=False)
app.MainLoop()
if __name__ == '__main__':
main()
If you don't load the frame and show it, then the app doesn't do anything and just exits when it finishes running the OnInit() method. Here are a few links on using XRC:
http://www.blog.pythonlibrary.org/2010/05/11/wxpython-an-introduction-to-xrc/
http://wiki.wxpython.org/XRCTutorial
http://wiki.wxpython.org/UsingXmlResources