Help Me: Loading Qt dialogs from python Scripts - python

im a novice into developing an application using backend as Python (2.5) and Qt(3) as front end GUI designer. I have 5 diffrent dialogs to implement the scripts. i just know to load the window (main window)
from qt import *
from dialogselectkernelfile import *
from formcopyextract import *
import sys
if __name__ == "__main__":
app = QApplication(sys.argv)
f = DialogSelectKernelFile()
f.show()
app.setMainWidget(f)
app.exec_loop()
main dialog opens on running. i have a set of back,Next,Cancel buttons pusing on each should open the next or previous dialogs. i use the pyuic compiler to source translation.how can i do this from python. please reply i`m running out of time.i dont know how to load another dialog from a signal of push button in another dialog. Help me pls
Thanks a Lot

Are you connecting the button click signals to handler functions?
If you are able to get one dialog to open, getting the other dialogs to open should be as simple as instantiating the new dialog and calling the .show() method in the first dialog's button handler.
Maybe you could upload your code somewhere so we can see more of it. What you have above doesn't really help much.

def displayNextForm(self):
self.close()
self.extr=FormMakeImage(self,"FormMakeImage",1,Qt.WStyle_DialogBorder)
self.extr.exec_loop()
def displayPrevForm(self):
from DialogSelectFile import *
self.close()
self.ext=DialogSelectKernelFile(self,"SelectKernel",1,Qt.WStyle_DialogBorder)
self.ext.exec_loop()
This did work smooth. I was able to implement the Next back feature. Possible warnings are occuring on Imports. but no problem on running.
Thanks all

Related

How to debug sporadic freezing of PyQt5 application after exiting?

I'm developing PyQt5 application of medium complexity. It has various widgets (both native and third-party) and Qthreads. It woks fine most of the time, but once in about 5 times the application hangs in the background after I exit it.
Here is how I define closeEvent:
def closeEvent(self, event):
qApp.quit()
And I also have defined a quit_action and connected it to the qApp.quit() like this:
self.quit_action.triggered.connect(qApp.quit)
I launch the PyQt5 application the standard way:
app = QApplication([])
window = GUIWindow()
window.show()
sys.exit(app.exec())
I have no idea how to debug such strange error. It happens only once in a few times and I can't reproduce the error.
I run the application in the console:
python main.py
and usually I can close the application without a problem. But once in a few times after I close the application (either by clicking on "x" button of the window or by triggering the quit_action in the menu) the window disappears and the process hangs in the background. I have to press "Ctlr+Z" and then kill the process.
What is the strategy to debug such strange error? How can find what exactly causes the freezing of the application?
This kind of bugs are hard to isolate. It looks like my particular bug emerges as a result of combination of several widgets of the app and it's hard to even provide a minimal working example that reproduces the error. Not to mention the error only happens once in a few runs.
It looks like I've found the main culprit for the bug by inspecting the hanging process through the gdb (see the question from stackoverflow Is there a way to attach a debugger to a multi-threaded Python process?).
When my application has frozen again - I attached to the process via the gdb, investigated threads and found the problematic thread.
EDIT: A temporary solution to make PyQt application close even when qApp.quit() doesn't help:
def closeEvent(self, event):
qApp.quit()
sys.exit()

Window contents not loaded when opening from another window PyQt5 (2 classes in one .py) [duplicate]

I'm working with PyQt (as a Python beginner).
I need to be able to take screenshots of a website on a headless system.
I was using PhantomJS earlier for another project, but they dropped Flash support in 1.5 and I don't want to rely on a deprecated 1.4 version for my new project.
So I'm using PyQt to do my stuff on my own.
I'm able to take a screenshot of a website with a given url, no problem.
But I keep having the "blue dice" flash plugin icon on flash placeholder (yes, javascript and plugins are activated)
self.settings.setAttribute(QtWebKit.QWebSettings.PluginsEnabled,True)
self.settings.setAttribute(QtWebKit.QWebSettings.JavascriptEnabled,True)
I'm making some test on a Youtube video page, here is an example of my issues:
The second part, that may be related to the first one:
How can I tell PyQt to wait few seconds before taking the screenshot ?
As you can see on the example, images on the right are still unloaded, because they are loaded using javascript and data attribute and in my script, I take the screenshot on the loadFinished signal (onLoad() javascript equivalent)).
My first guess was simply to
time.sleep(2)
Before calling my capture method, but it's not working. I'm assuming that the Webkit loading is also asleep during this sleep time, preventing anything to load on the page.
I tried to create a custom signal, but then I still don't know how to trigger it without sleeping.
My last guess is that I need to thread my application. Am I right?
If you have any hint/script to help me displaying flash content and/or to add a setTimeout like signal, I would be really grateful!
Thanks in advance for you help.
EDIT:
Just a quick edit to add my solution:
timeoutTimer = QTimer()
timeoutTimer.setInterval(3000) # wait for 3secs
timeoutTimer.setSingleShot(True)
timeoutTimer.timeout.connect(theMethodToCallOnTimeout)
About the flash thing: it looks like the flash player is broken on OSX (maybe related to a 32/64 bits issue).
If you time.sleep you are freezing the whole application, instead, you can use a QTimer, QEventLoop, QThread, etc. Here is the PyQt4 version:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
class browser(QWebView):
def __init__(self, parent=None):
super(browser, self).__init__(parent)
self.timerScreen = QTimer()
self.timerScreen.setInterval(2000)
self.timerScreen.setSingleShot(True)
self.timerScreen.timeout.connect(self.takeScreenshot)
self.loadFinished.connect(self.timerScreen.start)
self.load(QUrl("http://www.google.com/ncr"))
def takeScreenshot(self):
image = QImage(self.page().mainFrame().contentsSize(), QImage.Format_ARGB32)
painter = QPainter(image)
self.page().mainFrame().render(painter)
painter.end()
image.save(self.title() + ".png")
sys.exit()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = browser()
app.exec_()
I recommend using selenium. It is made for doing web automation, screenshots, and testing. Because it uses firefox it is very easy to have full flash support. It can also be run in a headless mode. The code below works at taking a screenshot of a web page with flash like the youtube video you had. You can see the screenshot it took below. A few things to keep in mind. selenium has a save_screenshot method which you can see is commented out in the code. I didn't use it because it wasn't taking proper screenshot of flash components, you can correct this by using the technique in Taking screenshot of flash object using Selenium with Webdriver. I chose though to just take a screenshot of the screen using the imagemagic import command. This is a screenshot tool that works in Linux. You can check out Take a screenshot via a python script. [Linux] and Get screenshot on Windows with Python? for other approaches of taking screenshots.
code
import time, selenium.webdriver, subprocess
browser = selenium.webdriver.Firefox()
browser.get('http://www.youtube.com/watch?v=bFEoMO0pc7k')
time.sleep(6)
#browser.save_screenshot('test.png')
subprocess.check_output('import -window root screen.png', shell=True)
browser.quit()
screenshot

Showing and hiding multiple windows in PyQt5

I'm working on a project with UI and I started to do it with PyQt5. So far I watched lots of videos read some tutorials and have progress on the project. Since PyQt is a binding of C++ for Python, there are not so many documents for complex UI with lots of windows.(or I couldn't find it and also looked examples of PyQt5). My project contains lots of windows. I'm trying to take some arguments from a user and due to user arguments optimization algorithm will work. So the project contain's these windows
Login Window(Qwidgets) {first view}
Login Sign up Window (Qwidgets) {if user don't have an account second view}
If user logs into system Tabwidget will be shown with 4 subtab view and these tabs will take arguments from a user. In this widget, there is already 2 subtab have already values that user can choose but also there are buttons which open new Qwidget class windows with OK and CANCEL button. One tab for choosing a file directory and I used QfileDialog class here. And last tab taking last arguments from a user and opening the file that user has chosen in 3rd tab.
After Tab view, I opened a Plotview, with the file that user have chosen, and in that window user by drawing some polygons giving argument on plot.{Im using Pyqtgraph library here}
Optimization Algorithm will work it's not connected with Pyqt
I have used Qt Designer mostly while designing UI. But later changed it adding some methods to take arguments from a user and for connecting other tabs or other windows.
By defining methods in the class (window) I can open other windows but I cant hide or close an already opened window. if I try to close them all process goes down but I want to make the only that window close. I have that problem in Login Signup window, popup windows for taking extra arguments from a user in 1st and 2nd tabview. My main starts with Login Window. After that in Loginwindow if login success it goes to tabview window. I have been successful by typing mainwindow.hide() and showing tabview window. But after that in all popup windows, I cant close the popup windows that takes arguments from a user.
Since the code is so long I will just put here interested parts.
class LoginUp(object):
def setupUi(self,LoginUp):
self.Buton1.clicked.connect(self.signup)
self.Buton2.clicked.connect(self.tabview)
def signup(self):
# here it shows but user cant close it by just clicking on OK button
# He must click on x button to close which I dont want.
self.signupshow = QtWidgets.QWidget()
self.ui = LoginSignUp()
self.ui.setupUi(self.signupshow)
self.signupshow.show()
def tabview(self): # Here its works
self.tabviewshow = QtWidgets.QWidget()
self.ui_tabview = TabView()
self.ui_tabview.setupUi(self.tabviewshow)
MainWindow.close()
self.tabviewshow.show()
class TabView(object):
def setupUi(self,Form):
self.button3.clicked.connect(self.addargument)
def addargument(self):
# same problem.. after that it popups window that user can give inputs but cant close the window AddArgument class
self.Add = QtWidgets.QWidget()
self.addargumentshow = AddArgument()
self.addargumentshow.setupUi(self.Add)
self.addargumentshow.show()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QWidget()
ui = LoginUp()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
One way to solve this is to use another class as a controller for all of the windows you want to show.
In each window you will send a signal when you want to switch windows and it is up to this controller class to decide how to handle the signal when received and decide which window to show. Any arguments that you need passed can be passed through the signals.
Here is a simplified complete working example.

Python Kernel crashes after closing an PyQt4 Gui Application

Ok here is my problem:
I want to create a PyQt4 Gui, which can be executed from a python console (tested with IDLE, Spyder Console and IPython Console) and then allows the user to change and view variables. After closing the app the user should be able to do further work with the variables in the console. But by closing the Gui the Kernel crashes and it is not possible to make any new input to the console.
I'm working with Python 2.7 and PyQt4. I am using the following code to start an close the application:
app=QtGui.QApplication(sys.argv)
MainApp=plottest()
MainApp.show()
sys.exit(app.exec_())
The easy solution here https://www.reddit.com/r/learnpython/comments/45h05k/solved_kernel_crashing_when_closing_gui_spyder/
only put
if __name__ == "__main__":
app=0 #This is the solution
app = QtGui.QApplication(sys.argv)
MainApp = Dice_Roller()
MainApp.show()
sys.exit(app.exec_())
What you need to do is:
Check that there isn't already a QApplication instance when trying to create a new one
Ensure that the QApplication object is deleted after it's been closed
(See simple IPython example raises exception on sys.exit())
# Check if there's a pre-existing QApplication instance
# If there is, use it. If there isn't, create a new one.
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
# Ensure that the app is deleted when we close it
app.aboutToQuit.connect(app.deleteLater)
# Execute the application
MainApp = plottest()
MainApp.show()
sys.exit(app.exec_())
Using this code you can rerun the application as many times as you want in IPython, or anywhere else. Every time you close your Qt application, the app object will be deleted in python.
I do not think you mean a kernel crash. Rather, I think you are talking about exiting the python console. This is caused by sys.exit(app.exec_()). For example try (for example in spyder) the following two codes:
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.setWindowTitle('simple')
widget.show()
#sys.exit(app.exec_())
Here you should get an empty window and the python console will stay alive. The second one, where sys.exit(app.exec_()) is included, will exit the python console at the end and the window disappears:
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.setWindowTitle('simple')
widget.show()
sys.exit(app.exec_())
I hope this helps.
I still don't know the issue and solution. None of the above worked for me. Currently I am coding in the spyder GUI and running on "cmd" by giving 'python' command. In CMD, it is working fine.
Update the solution if I get it. :-)
I think that your problem is that python console closes (its not kernel crash). For example in Spyder python icon on top of console window becomes grey and you cant do anything besides running another console.
Anyway, you should write app.exec() instead of sys.exit(app.exec()).
I believe sys.exit(app.exec()) passes exit code to console and closes it. Using simple app.exec() won't close console.
Concluding your code should look like:
app=QtGui.QApplication(sys.argv)
MainApp=plottest()
MainApp.show()
app.exec_()
I hope it helps.
hdunn's answer worked for me. Have deleted sys.exit() to avoid exiting the application totally. Performing the first step alone, as suggested by others in github forum, solved part of the problem but window never showed up, nor any error message. Performing the second part solved everything like a charm! Thans, hdunn!
# Check if there's a pre-existing QApplication instance
# If there is, use it. If there isn't, create a new one.
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
# Ensure that the app is deleted when we close it
app.aboutToQuit.connect(app.deleteLater)
# Execute the application
MainApp = plottest()
MainApp.show()
app.exec_()

Execute Python code from within PyQt event loop

I am testing a gui built using PyQt and I would like the ability to interact with the gui using python code that is executed after the PyQt event loop starts (app.exec_()). Another way of saying this is I would like the call to app.exec_ to return immediately as if the gui were modeless, followed by further python code which interacts with the gui.
I found this example of running the PyQt loop in a thread but don't want to do something so unconventional. Is there any way to get the PyQt message loop to continue processing messages while also executing python code in the main thread after exec_ has been called?
One option here is to use a QtCore.QTimer.singleShot() call to start your python code after calling `exec_()'.
For example:
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
# Setup the GUI.
gui = MyGui()
gui.showMainWindow()
# Post a call to your python code.
QtCore.QTimer.singleShot(1000, somePythonFunction)
sys.exit(app.exec_())
This will execute the function somePythonFunction() after 1 second. You can set the time to zero to have the function added immediately queued for execution.
As a possible easy answer, try not calling app.exec_() in your script and running your PyQt program using python -i My_PyQt_app.py.
For example:
## My_PyQt_app.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget
app = QApplication(sys.argv)
window = QWidget()
window.show()
# Don't start the event loop as you would do normally!
# app.exec_()
Doing this should allow you to run the GUI through the terminal and interact with it in the command line.
I got it. I can execute the test script line-by-line from the main thread using exec and then run the gui from a worker thread.
Not exactly sure what you wanna do. Are you looking for something like Py(known as PyCrust) for PyQt?
The easiest way is to use IPython:
ipython --gui=qt4
See ipython --help or the online documentation for more options (e.g. gtk, tk, etc).

Categories

Resources