Open second window with QTDesigner 5 in Python 3 - python

I have problem with QTDesigner 5, which should be trivial, but I just can't figure out the problem.
What I want to do is to open a second Window when clicking on a button:
I have designed the Main Window and the secondary one with QTDesigner (PyQT5!) and converted them with pyuic to .py files. The Main Window opens without problems with the following Code:
from PyQt5 import QtGui, QtWidgets, QtCore, uic
import UI14 as UIImport
import GIPrompt as GIImport
class MainWindow(UIImport.Ui_MainWindow):
def __init__(self, window):
UIImport.Ui_MainWindow.__init__(self)
self.setupUi(window)
self.radioButtonGI.clicked.connect(self.openGIPrompt)
def openGIPrompt(self):
windowGI = QtWidgets.QDialog()
Gi = GIPrompt(windowGI)
windowGI.show()
class GIPrompt(GIImport.Ui_GIPrompt):
def __init__(self, windowGI):
GIImport.Ui_GIPrompt.__init__(self)
self.setupUi(windowGI)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
prog = MainWindow(window)
window.show()
sys.exit(app.exec_())
If I add the following to the main function, the "GiPrompt" Window opens as well along with the Main Window:
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
prog = MainWindow(window)
window.show()
"""Open secondWindow"""
windowGI = QtWidgets.QDialog()
Gi = GIPrompt(windowGI)
windowGI.show()
sys.exit(app.exec_())
If I try to open the second window via the openGIPrompt function, nothing happens. I do not get an error message, and no window appears. A print command however tells me that the init_function of the second Window is called...
Has someone an idea, what the problem could be?
Thanks in advance!

I have figured out the problem:
Apparently, the initialized Window is disposed of by garbage collection, as the variables are not declared as self:
This fixed the problem:
from PyQt5 import QtGui, QtWidgets, QtCore, uic
import UI14 as UIImport
import GIPrompt as GIImport
class MainWindow(UIImport.Ui_MainWindow):
windowGI=None
Gi=None
def __init__(self, window):
UIImport.Ui_MainWindow.__init__(self)
self.setupUi(window)
self.radioButtonGI.clicked.connect(self.openGIPrompt)
def openGIPrompt(self):
self.windowGI = QtWidgets.QDialog()
self.Gi = GIPrompt(self.windowGI)
self.windowGI.show()
class GIPrompt(GIImport.Ui_GIPrompt):
def __init__(self, windowGI):
GIImport.Ui_GIPrompt.__init__(self)
self.setupUi(windowGI)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
prog = MainWindow(window)
window.show()
sys.exit(app.exec_())

Related

Blank Third window opening up with Second Window PyQt

Ok I'm having an issue where when I click a button on my first window to open up the second window, a third blank window is opening up with it. I've been trying to figure out where in the code this is initializing the 3rd. hoping someone can help.
Here is the code for the first main window...
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets
from PyQt5 import uic
from PyQt5 import QtCore
import sys
class GuitarSpec_ViewWindow(QMainWindow):
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
def __init__(self):
super(GuitarSpec_ViewWindow, self).__init__()
uic.loadUi("guitarSpecViewLayout.ui", self)
self.click = self.findChild(QPushButton, "click_pushButton")
self.click.clicked.connect(self.openEditWindow)
self.show()
def openEditWindow(self):
from guitarSpecEditorTestDelete import Ui_GuitarSpec_EditorWindow
self.window = QMainWindow()
self.Ui = Ui_GuitarSpec_EditorWindow()
self.Ui.setupUi(self.window)
self.window.show()
app = QtWidgets.QApplication(sys.argv)
UIWindow = GuitarSpec_ViewWindow()
app.exec_()
sys.exit(app.exec_())
The Second window when it opens automatically opens up a blank third window. here is that code...
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5 import uic
class Ui_GuitarSpec_EditorWindow(QMainWindow):
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
def setupUi(self, GuitarSpec_EditorWindow):
GuitarSpec_EditorWindow.setObjectName("GuitarSpec_EditorWindow")
uic.loadUi("guitarSpecEdit.ui", self)
self.show()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
GuitarSpec_EditorWindow = QtWidgets.QMainWindow()
ui = Ui_GuitarSpec_EditorWindow()
ui.setupUi(GuitarSpec_EditorWindow)
GuitarSpec_EditorWindow.show()
sys.exit(app.exec_())
Any Help would be greatly appreciated! I am new to this so it's probably a fairly simple solution.

How to save a gui created with qt and python as an image

I am trying to use qt creator and python to generate flowcharts with values. I want to save the generated flowchart as an image after, but I cannot figure out how to do it. Here is my attempt:
import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtGui import *
from mainwindow import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, obj=None, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.setupUi(self)
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
screen = app.primaryScreen()
screenshot = screen.grabWindow(window)
screen.save('screenshot.png', 'png')
The fact that the show method is called does not imply that it is shown instantly, but rather that this method notifies the OS so that the window is created. A possible solution is to use a QTimer, on the other hand the grabWindow method grabs a window using the associated WID, in this case it is better to use the grab method:
from functools import partial
def take_screenshot(widget):
pixmap = widget.grab()
if not pixmap.isNull():
pixmap.save("/fullpath/of/screenshot.png", "PNG")
QApplication.quit()
def main():
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
QTimer.singleShot(500, partial(take_screenshot, window))
app.exec_()
if __name__ == "__main__":
main()

How to reboot PyQt5 application

I'm trying to restart my application after an update from the client side. I was able to achieve till the auto update part. I tried to surf on How to restart PyQt application?. There are few similar questions earlier, but none of them have good explanation or example with a button click event. Could you guys help me understand on how to reboot a PyQt application. Basically I want to restart the application from if __name__ == '__main__': everytime there is an update.
Note: AppLogin is my private module I created to handle application login. So basically that would be the landing QDialog once application is opened.
from PyQt5.QtWidgets import *
import sys
import AppLogin
class App:
def __init__(self):
btn = QPushButton(main_window)
btn.setText('close')
btn.pressed.connect(self.restart)
main_window.show()
def restart(self):
# Here goes the code for restart
pass
if __name__ == '__main__':
appctxt = QApplication(sys.argv)
log_in = AppLogin.Login()
if log_in.exec_() == QDialog.Accepted:
main_window = QMainWindow()
ui = App()
exit_code = appctxt.exec_()
sys.exit(exit_code)
The logic is to end the eventloop and launch the application an instant before it closes:
import sys
from PyQt5 import QtCore, QtWidgets
def restart():
QtCore.QCoreApplication.quit()
status = QtCore.QProcess.startDetached(sys.executable, sys.argv)
print(status)
def main():
app = QtWidgets.QApplication(sys.argv)
print("[PID]:", QtCore.QCoreApplication.applicationPid())
window = QtWidgets.QMainWindow()
window.show()
button = QtWidgets.QPushButton("Restart")
button.clicked.connect(restart)
window.setCentralWidget(button)
sys.exit(app.exec_())
if __name__ == "__main__":
main()
A solution is to close (or forget) the QMainWindow and recreate it.
If you just "show()" a single widget, the same idea works fine.
import sys
import uuid
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
class MainWindow(QMainWindow):
singleton: 'MainWindow' = None
def __init__(self):
super().__init__()
btn = QPushButton(f'RESTART\n{uuid.uuid4()}')
btn.clicked.connect(MainWindow.restart)
self.setCentralWidget(btn)
self.show()
#staticmethod
def restart():
MainWindow.singleton = MainWindow()
def main():
app = QApplication([])
MainWindow.restart()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

Ui_MainWindow has no attribute 'show'

I'm writing a program which will have multiple windows. I have a main program (attached) that calls the Ui files (that have been converted into .py). The main window and customise window open correctly (the first two listed) but neither the third or fourth windows open correctly, giving me the error
'Ui_MainWindow' object has no attribute 'show'
The main program;
from PyQt4 import QtCore, QtGui
import sys
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwin = main_menu_ui.Ui_MainWindow()
mainwin.show()
sys.exit(app.exec_())
def openCustomise(self):
customiseOpen = question_set_menu_ui.Ui_MainWindow()
customiseOpen.show()
sys.exit(app.exec_())
def openQuiz(self):
quizOpen = quiz_window_ui.Ui_MainWindow()
quizOpen.show()
sys.exit(app.exec_())
def addNewSet(self):
addNewOpen = question_set_edit_ui.Ui_MainWindow()
addNewOpen.show()
sys.exit(app.exec_())
Sorry if I'm missing something obvious, I'm learning Qt/Python for college.
The auto-generated UI class that you are importing extends object and doesn't have a show method (open up the .py file for yourself and verify this).
In general, you should structure your GUIs like this:
from PyQt4 import QtCore, QtGui
import sys
from layout_file import main_menu_ui
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = main_menu_ui()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainwin = MyForm()
mainwin.show()
sys.exit(app.exec_())
You import your UI from your autogenerated UI file. You have a class that contains your GUI logic. It then sets up your UI layout from your imported UI in its __init__() method.

Basic Widget Interaction with PyQt

Please can someone tell me what im doing wrong here with respect to calling pwTxt.text.
#!/usr/bin/python
import sys
from PyQt4 import QtCore, QtGui
from mainwindow import Ui_MainWindow
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def on_pwExtract_pressed(self):
print self.pwTxt.text
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
The line print self.pwTxt.text fails because it can't find the widget, pwTxt is a QLineEdit defined on the main window. I just made it in QTDesigner and generated python code with pyuic4.
How do I correctly reference other widgets on the same window, in this case I just want to get the text from a QLineEdit named pwTxt when the QPushButton pwExtract is pressed.
Thanks a lot.
Try:
print self.ui.pwTxt.text()

Categories