Why does my app close when opening a new window in PyQt5? - python

~EDIT (original question still below)~ when I remove the self.setGeometry() call in the new window it works as it should. Why is that? I'm still building out the UI for it, but once I do I hope I don't continue to have this problem...
~EDIT 2~ Just realized it should be self.resize() not self.setGeometry()...
self.solved()
:(
I'm just learning PyQt5 and just doing a little messing around. For some reason when I try to open a new window from the main application window, the whole thing closes. Putting in some print statements to track progress shows that it's not actually creating the new window either.
Main Window code:
import sys
from PyQt5.QtWidgets import QMainWindow, QAction, QApplication
from newLeague import *
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
newLeagueAction = QAction('Create New League', self)
newLeagueAction.setShortcut('Ctrl+N')
newLeagueAction.setStatusTip('Create a new league from scratch')
newLeagueAction.triggered.connect(self.createNewLeague)
openLeagueAction = QAction('Open Existing League', self)
openLeagueAction.setShortcut('Ctrl+E')
openLeagueAction.setStatusTip('Continue with a previously started league')
openLeagueAction.triggered.connect(self.openExistingLeague)
exitAction = QAction('Quit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Quit the application...')
exitAction.triggered.connect(self.close)
self.statusBar()
mainMenu = self.menuBar()
fileMenu = mainMenu.addMenu('&File')
fileMenu.addAction(newLeagueAction)
fileMenu.addAction(openLeagueAction)
fileMenu.addAction(exitAction)
self.resize(1920, 1080)
self.setWindowTitle("Brackets")
def createNewLeague(self):
'''shows dialog to create a new league'''
self.newLeague = CreateLeague()
self.newLeague.show()
print('New League being created...')
def openExistingLeague(self):
print('Existing League opening...')
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Here is the second window:
from PyQt5.QtWidgets import QMainWindow
class CreateLeague(QMainWindow):
def __init__(self):
super(CreateLeague, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry(600, 500)
self.setWindowTitle('Create A New League')
I've looked at other examples such as this, and this, and I'm not seeing what it is I'm doing different. I've experimented with using parent as an argument in the constructors and the result is no different.

Your Main Window code is ok, but you should remove CreateLeague, self arguments from the super parameters in your second window, then, your code should work fine.
See below:
from PyQt5.QtWidgets import QMainWindow
class CreateLeague(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(600, 500)
self.setWindowTitle('Create A New League')

Related

Pyside2 second window(QDialog) closes the main one

import sys
from PySide2.QtCore import QFile
from PySide2.QtWidgets import QApplication, QMainWindow
from PySide2.QtUiTools import QUiLoader
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
loader = QUiLoader()
self.ui = loader.load("mainWindow.ui", self)
self.ui.pushButton_call_dialog.clicked.connect(self.call_dialog)
self.ui.close()
self.ui.show()
def call_dialog(self):
loader = QUiLoader()
self.dialog = loader.load("dialog.ui")
self.dialog.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyMainWindow()
window.show
sys.exit(app.exec_())
Hi everyone,
any idea why the second (dialog) window closes the entire application?
Of course, it is not a crash since i'm getting a message saying:
Process finished with exit code 0
Thanks for your help
You could handle your QDialog on a separate class, and then make them interact only, the structure might change a bit, but you can see if it's a viable answer:
import sys
from PySide2.QtWidgets import *
class MyWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
button = QPushButton("Dialog")
button.clicked.connect(self.open_dialog)
self.setCentralWidget(button)
def open_dialog(self):
dialog = MyDialog()
dialog.show()
dialog.exec_()
class MyDialog(QDialog):
def __init__(self):
QDialog.__init__(self)
button = QPushButton("Close")
button.clicked.connect(self.close_dialog)
layout = QHBoxLayout()
layout.addWidget(button)
self.setLayout(layout)
def close_dialog(self):
self.close()
if __name__ == "__main__":
app = QApplication()
m = MyWindow()
m.show()
sys.exit(app.exec_())
Just notice that you should include the setUp step on each class.
Hope it helps.
To put the dialog into a separate class didn't work for either.
Every time the Dialog.close() event was called, it closes the whole application.
What worked for me, was to use hide() instead

Python PyQt4 open from QDialog new QWidget window

By pressing a QPushButton in my QDialog window I want to open a new QWidget window.
My code:
from PyQt4 import QtGui
import sys
class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("Main Window")
class FirstWindow(QtGui.QDialog):
def __init__(self, parent=None):
super(FirstWindow, self).__init__(parent)
self.createWindow()
def createWindow(self):
btn = QtGui.QPushButton('Open New Window', self)
btn.move(10, 10)
self.openNewWindow = MainWindow(self)
btn.clicked.connect(self.openMainWin)
self.setGeometry(250,250, 150,50)
self.setWindowTitle("First Window")
self.show()
def openMainWin(self):
self.openNewWindow.show()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
firstwin = FirstWindow()
sys.exit(app.exec_())
When I run the code nothing happens by pressing the button.
But when I change the class from
class MainWindow(QtGui.QWidget) to
class MainWindow(QtGui.QDialog) or class MainWindow(QtGui.QMainWindow)
it works!
What am I doing wrong?! Please assist me.
When you instantiate MainWindow you pass in a parent. Qwidget only makes a new window if you don't specify a parent.
This is of course deliberate. If QWidgets with parents were shown in new windows, then you could never build a GUI. Imagine having every widget in it's own window!
QMainWindow and QDialog are specifically designed to both have a parent, and create a new window. You should use them.

How to make one window to block another without using .setModal(True)

If main window right-clicked a QInputDialog shows up. I want QInputDialog to block main window while it is open. How to achieve this?
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
class AppWindow(QtGui.QMainWindow):
def __init__(self):
super(AppWindow, self).__init__()
mainWidget=QtGui.QWidget()
self.setCentralWidget(mainWidget)
mainLayout = QtGui.QVBoxLayout()
mainWidget.setLayout(mainLayout)
frame=QtGui.QFrame()
frame.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
frame.connect(frame, QtCore.SIGNAL("customContextMenuRequested(QPoint)" ), self.up)
mainLayout.addWidget(frame)
self.modal=QtGui.QInputDialog()
def up(self, QPos):
self.modal.move(QtGui.QCursor.pos())
self.modal.show()
self.modal.raise_()
window=AppWindow()
window.show()
sys.exit(app.exec_())
OK, This solution can be solve by use method QWidget.setWindowModality (self, Qt.WindowModality windowModality) . A modal window is one that blocks input to other windows. Note that windows that are children of a modal window are not blocked.
Add this line in your initial method;
self.modal.setWindowModality(QtCore.Qt.ApplicationModal)
Completed code is;
import sys
from PyQt4 import QtCore, QtGui
class AppWindow (QtGui.QMainWindow):
def __init__ (self):
super(AppWindow, self).__init__()
mainWidget = QtGui.QWidget(self)
self.setCentralWidget(mainWidget)
mainLayout = QtGui.QVBoxLayout()
mainWidget.setLayout(mainLayout)
frame = QtGui.QFrame()
frame.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
frame.connect(frame, QtCore.SIGNAL("customContextMenuRequested(QPoint)" ), self.up)
mainLayout.addWidget(frame)
self.modal = QtGui.QInputDialog(self)
self.modal.setWindowModality(QtCore.Qt.ApplicationModal)
def up (self, QPos):
self.modal.move(QtGui.QCursor.pos())
self.modal.show()
self.modal.raise_()
app = QtGui.QApplication([])
window = AppWindow()
window.show()
sys.exit(app.exec_())
Reference method : http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html#setWindowModality
Reference enum : http://pyqt.sourceforge.net/Docs/PyQt4/qt.html#WindowModality-enum
Regards,
In a nut shell, this is the basic approach. I have created a second window (a Frame), containing a table widget, and the name of my class is TableWindow. Import that in your main window file. On a button click, I call the below function.
def call_table_window(self):
self.frame = QtGui.QFrame()
self.window_table = TableWindow()
self.window_table.setupUi(self.frame)
#This stops the user to switch to the main window. He has to close
#the 2nd window first.
self.frame.setWindowModality(QtCore.Qt.ApplicationModal)
self.frame.show()
Especially when working with PyQt5, you can set inside the __init__
self.setWindowModality(QtCore.Qt.ApplicationModal)

PyQt Window No Show

Upon calling the show method on simple the simple window does not show. Why doesn't my Simple window show. :(
import sys
from PyQt4 import QtGui
class Widget(QtGui.QWidget):
def __init__(self):
super(Widget, self).__init__()
simple = Simple()
button = QtGui.QPushButton("Button", self)
button.clicked.connect(simple.show)
self.show()
class Simple(QtGui.QWidget):
def __init__(self):
super(Simple, self).__init__()
self.setGeometry(300, 250, 250, 150)
self.setWindowTitle("Simple Widget")
if __name__ =="__main__":
app = QtGui.QApplication(sys.argv)
widget = Widget()
sys.exit(app.exec_())
Please Help!
The problem with your code is that, simple in __init__ method of class Widget is a local variable, so as soon as the __init__ method finishes execution, the simple object is destroyed by the python Garbage Collector, thus the window does not appear because the object does not exist in the memory. To solve your problem, just add self at the starting of the simple variable to make it member variable.
...
self.simple = Simple()
button = QtGui.QPushButton("Button", self)
button.clicked.connect(self.simple.show)
...

How do I switch layouts in a window using PyQt?? (Without closing/opening windows)

I am currently attempting to create a program using python and PyQt4 (not Qt Designer).
I created a login class (QDialog) and a Homepage class (QMainWindow). However, because my program will consist of loads of pages (the navigation through the program will be large) i wanted to know how to switch layouts in QMainWindow rather than constantly creating new windows and closing old ones. For example, i would have the MainWindow ('HomePage') layout set as the default screen once logged in and would then have a subclass within MainWindow which allows me to navigate to user settings (or any other page). Instead of creating a new window and closing MainWindow, is there a way for me to swap the MainWindow layout to the User Setting layout?? (apologies if this doesnt make sense, im new to PyQt).
An example code is shown below (V.Basic code)
----------------------------------------------------------------------------------
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class MainWindow(QMainWindow):
#Constructor
def __init__(self):
super(MainWindow, self).__init__() #call super class constructor
button1 = QPushButton("User Settings", self)
button1.clicked.connect(UserSelection)
button1.resize(50,50)
button1.move(350,50)
self.show()
class UserSelection(?):
...
def main():
app = QApplication(sys.argv) #Create new application
Main = MainWindow()
sys.exit(app.exec_()) #Monitor application for events
if __name__ == "__main__":
main()
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.central_widget = QtGui.QStackedWidget()
self.setCentralWidget(self.central_widget)
login_widget = LoginWidget(self)
login_widget.button.clicked.connect(self.login)
self.central_widget.addWidget(login_widget)
def login(self):
logged_in_widget = LoggedWidget(self)
self.central_widget.addWidget(logged_in_widget)
self.central_widget.setCurrentWidget(logged_in_widget)
class LoginWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(LoginWidget, self).__init__(parent)
layout = QtGui.QHBoxLayout()
self.button = QtGui.QPushButton('Login')
layout.addWidget(self.button)
self.setLayout(layout)
# you might want to do self.button.click.connect(self.parent().login) here
class LoggedWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(LoggedWidget, self).__init__(parent)
layout = QtGui.QHBoxLayout()
self.label = QtGui.QLabel('logged in!')
layout.addWidget(self.label)
self.setLayout(layout)
if __name__ == '__main__':
app = QtGui.QApplication([])
window = MainWindow()
window.show()
app.exec_()

Categories