I'm new to creating GUI's in Python and can't seem to get over the first hurdle.
I'm using Anaconda - Spyder and I normally run all (mainly mathematical) code through this (and the IPython console?).
My issue is that when I run the code below I'm expecting it to display a simple blank window but nothing happens.
Is Spyder/IPython not the best way to do this or is there an issue with my code?
I've tried using the command prompt by typing "python TestScript.py" whilst in the correct directory but I get an error saying 'Python is not recognised as a internal or external command'. Do I need to set up cmd to use Anaconda?
import sys
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
w.resize(250,150)
w.move(30,30)
w.setWindowTitle('Simple Window')
w.show
sys.exit(app.exec_())
Clearing this one up, as the answer was posted in the comments by Patrick Artner.
Simply adding () after w.show solved the problem.
Related
Right at the beginning I would like to say that I am a very beginner when it comes to writing GUI applications and this is the topic of this question.
I am using Anaconda 4.1.1 as my Python distribution and Spyder as my IDE. I was trying to write a very simple window application using PyQt4 (already installed in Anaconda) or - to be precise - I copied some examples form the Internet and try to make some "experiments" with them. The results are really surprising for me.
The thing is that when I am running the following example in the IPython console:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
everything seems to be OK - I can close the window of an application whenever I want and it successfully opens once again when I am running the code once again. But when I make a small modification in the code, namely - getting rid of the main function:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
then I can run my program only once, because when I close it and try to run it once again - the IPython console displays the following message:
It seems the kernel died unexpectedly. Use 'Restart kernel' to continue using this console.
repeating every few seconds. The Kernel itself displays something like that:
QWidget: Must construct a QApplication before a QPaintDevice
I don't really understand how can it happen because for me these two pieces of code should work exactly the same since the only difference between them is presence of the main function which (I believe) is not necessary to make this program work. Why does it give an error the second way?
I have installed 32bit Python 3.4 and 3.5 and PyQt5 on our windows 7 work machine via the executable available from https://sourceforge.net/projects/pyqt/, however I now find that when I run my simple drag and drop test code it is very sluggish moving the first element (the ui freezes for about 4-5 seconds before completing the move). All subsequent drag and drop operations happen without that delay.
By "ui freezes" I mean that the selection remains highlit and in its original place when i move the cursor away and the drag and drop guide graphics (a line appearing where the items would move to if i let the mouse button go at that time, the mouse cursor changing to a different icon to indicate that drag and drop is occuring) do not appear. If I release the mouse button during this time the selected elements are moved to that location but not until the 4-5 second wait time has elapsed.
The code is as follows:
from PyQt5.QtWidgets import QMainWindow, QApplication, QListView, QAbstractItemView
from PyQt5.QtGui import QStandardItemModel, QStandardItem
def createModel():
model = QStandardItemModel()
for i in range(0,101):
item = QStandardItem(str(i))
item.setText(str(i))
item.setEditable(False)
item.setDropEnabled(False)
model.appendRow(item)
return model
class TestListView(QMainWindow):
def __init__(self, parent=None):
super(TestListView, self).__init__(parent)
self.listView = QListView()
self.setCentralWidget(self.listView)
self.listView.setModel(createModel())
self.listView.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.listView.setDragEnabled(True)
self.listView.setDragDropMode(QAbstractItemView.InternalMove)
def main():
app = QApplication([])
lvt = TestListView()
lvt.show()
app.exec_()
if __name__ == '__main__':
main()
I am hoping someone can point out a foolish mistake I've made that is the cause of this issue (like when I earlier had passed ints to the QStandardItems constructor instead of strings, resulting in a crash each time I tried to drag and drop), but if that isn't the case, if anyone is able to recommend a combination of pyqt5 and 32bit (64bit is not an option for us) python components that they've found that does not exhibit this behaviour? I don't really care if it's python 3.x or python 2.x (although I haven't seen any pyqt5/python2 combinations previously), as long as it works.
I've tried the python-qt5 package that pip installs (after following the instructions here https://blogs.msdn.microsoft.com/pythonengineering/2016/04/11/unable-to-find-vcvarsall-bat/ by installing visual c++ build tools) in both 3.4 and 3.5, but the full version of this script will use .ui files from QtCreator, and the pip version of python-qt5 throws an error:
File "testReorder.py", line 2, in <module>
from PyQt5 import uic
File "c:\python35-32\lib\site-packages\PyQt5\uic\__init__.py", line 43, in <module>
from .Compiler import indenter, compiler
File "c:\python35-32\lib\site-packages\PyQt5\uic\Compiler\compiler.py", line 43, in <module>
from ..properties import Properties
File "c:\python35-32\lib\site-packages\PyQt5\uic\properties.py", line 46, in <module>
from .icon_cache import IconCache
File "c:\python35-32\lib\site-packages\PyQt5\uic\icon_cache.py", line 27, in <module>
from .port_v3.as_string import as_string
ImportError: No module named 'PyQt5.uic.port_v3'
when I include the import line
from PyQt5 import uic
in the code.
Edit: Having gotten home and tested the code on my linux machine (and seen no signs of sluggishness), I'm thinking this issue must be either specific to the combination of the pyqt, python and windows version, or something specific to that particular windows installation, and not a problem with my code.
I'd still be interested in hearing of anyone able to run the same code and not see the same issues on a windows (especially windows 7) machine, but I'm thinking it's less likely that I can assign the blame for this behaviour solely at pyqt's door.
Ran same code on another windows 7 computer with same packages installed. The issue is not seen there, so is obviously a problem with something specific to this machine rather than the code I've written/versions of python I'm using/version of pyqt.
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 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!