PyQt5: How to open a new window and close the current window? - python

I would like to ask, as I write in the title, how to open a new window and close (completely) the current window?
There are two .py files. They are independent from each other, that means, each of them can be run on its own.
In MyApp.py there is a button. If the button is clicked, I want to close the current window/file and open the new window/file.
In my code below I can open the new window/file, but the old window is not closed. And if I close the second window, the old window will be closed as well. I have tried some methods with my knowledge/search, but none of them worked fine.
Here is the code for MyApp.py
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import NewApp
# NewApp.py in the same folder
# in NewApp.py there is a class NewApp
qtCreatorFile_MyApp = "F:\\MyApp.ui"
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
uic.loadUi(qtCreatorFile_MyApp, self)
self.show()
self.btn_inMyApp.clicked.connect(self.closeMyApp_OpenNewApp)
def closeMyApp_OpenNewApp(self):
self.Open = NewApp.NewApp()
self.Open.show()
# My Problem: How to close the MyApp completely and open NewApp?
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
sys.exit(app.exec_())
NewApp.py has similar code structure. For the purpose of integrity of this quesiton, I paste the code as follows.
qtCreatorFile_NewApp = "F:\\NewApp.ui"
class NewApp(QWidget):
def __init__(self):
super(NewApp, self).__init__()
uic.loadUi(qtCreatorFile_NewApp, self)
self.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = NewApp()
sys.exit(app.exec_())
Thank you for the help!

Related

open a secondary window from button , from two .ui files

I created two .ui files with Qtdesigner: the first "interface.ui" which is the main interface and the second "param.ui" a secondary window. I'm trying to boot directly from file.ui without converting the file to python format..
I'm starting the program from main.py and the problem starts when I try to open "param.ui" with a button (called "puls") present in "interface.ui".
The secondary window is not going to open after pressing "puls". I can not understand where is the problem ... If someone wants to help me I thank him in advance.
from PyQt5 import QtWidgets, uic
class ParamWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
uic.loadUi("param.ui", self)
print("ParamWindow init")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("interface.ui", self)
self.puls = self.findChild(QtWidgets.QPushButton, "puls")
self.puls.clicked.connect(self.openParamWindow)
print("MainWindow init")
def openParamWindow(self):
paramWindow = ParamWindow()
paramWindow.show()
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()

PYQT6 and QT designer, after opening second window, buttons wont work

So i am making a GUI to identify seagulls.
I have made some QMainWindow's and would like the user to nagviate through these using buttons.
The first window works fine, and the user gets to the next page.
However, when clicking on buttons on page 2, nothing works, not even printing a simple statement. I am new to this and i am doing something wrong. I tried messing with init but am at a loss.
I am using a function
def openNewPage(self,b):
NewPage = b.text()
uic.loadUi(f"{NewPage}.ui",self)
self.show
to open a new page by having the buttons clicked on by the user have the name of the next file to be opened.
For example: the button for white head has the text "WhiteHead"
and will the open the file WhiteHead.ui
example:
self.bWhiteHead.clicked.connect(lambda:self.openNewPage(self.bWhiteHead))
Please help me understand why buttons work in one window and not in the next, thank you.
Here is the code:
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtGui import QIcon
from PyQt6.QtCore import Qt
from PyQt6 import uic
import time
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("SeagullPage1.ui",self)
self.setWindowTitle("SEAGULL IDENTIFIER")
self.bBlackHead.clicked.connect(lambda:self.openNewPage(self.bBlackHead))
self.bWhiteHead.clicked.connect(lambda:self.openNewPage(self.bWhiteHead))
def openNewPage(self,b):
NewPage = b.text()
uic.loadUi(f"{NewPage}.ui",self)
self.show
class WhiteHead(QMainWindow):
def __init__(self):
super().__init__
self.setWindowTitle("SEAGULL IDENTIFIER2")
self.BlackFeetButton.clicked.connect(lambda:self.openNewPage(self.BlackFeetButton))
self.PinkFeetButton.clicked.connect(lambda:self.openNewPage(self.PinkFeetButton))
self.YellowFeetButton.clicked.connect(lambda:self.openNewPage(self.YellowFeetButton))
def openNewPage(self,b):
print("hey")
NewPage = b.text()
uic.loadUi(f"{NewPage}.ui",self)
self.show
class YellowFeet(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("SEAGULL IDENTIFIER3")
self.RedBeakButton.clicked.connect(lambda:self.openNewPage(self.RedBeakButton))
self.NonReadBeakButton.clicked.connect(lambda:self.openNewPage(self.NonReadBeakButton))
def openNewPage(self,b):
print("hey")
NewPage = b.text()
uic.loadUi(f"{NewPage}.ui",self)
self.show
if __name__ == "__main__":
app = QApplication(sys.argv)
myApp = MyApp()
myApp.show()
app.exec()
#sys.exit(app.exec_())

In python, how do I open a new window by clicking a button in a main window using .py files created from .ui files made in QtDesigner?

I have two .py files created from .ui files made in QtDesigner. One is a main window for the program, and the other is a widget that allows users to input information and I'm calling it the "evaluation" widget.
I have a button in the main window called "btn_StartNew", which is meant to open the widget window to allow the user to start a new evaluation. I'm having troubles with opening the main window, and adding the function to the "btn_StartNew" button that opens the "evaluation" widget.
The code I have right now opens both the main window and the evaluation widget in the same window when I run the code:
import sys
from PyQt4 import QtCore, QtGui
from wid_Main import Ui_wid_Main
from wid_Eval_v2 import Ui_wid_Eval
class Win_Eval(QtGui.QWidget):
def __init__(self, parent=None):
super(Win_Eval, self).__init__(parent)
self.ui=Ui_wid_Eval()
self.ui.setupUi(self)
class Win_Main(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Win_Main, self).__init__(parent)
self.ui=Ui_wid_Main()
self.ui.setupUi(self)
#RUN "start new eval" button
self.ui.btn_StartNew.clicked.connect(self.btn_StartNew_click)
self.dialog = Win_Eval(self)
def btn_StartNew_click(self):
self.dialog.show()
def main():
app = QtGui.QApplication(sys.argv)
main = Win_Main()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Where wid_Main and Ui_wid_Main are the main window file and the main window class, respectively. And wid_Eval_v2 and Ui_wid_Eval are the evaluation widget file and class, respectively.
Any help would be much appreciated!
You must change:
self.dialog = Win_Eval(self)
to
self.dialog = Win_Eval()

show Qwidget window without MainWindow

I am having problems showing a QWidget window for the user to input some data.
My script has not GUI, but I just want to show this small QWidget window.
I created the window with QtDesigner, and now I am trying to show the QWidget window like this:
from PyQt4 import QtGui
from input_data_window import Ui_Form
class childInputData(QtGui.QWidget ):
def __init__(self, parent=None):
super(childInputData, self).__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.setFocus(True)
self.show()
And then, from my main class, I am doing like that:
class myMainClass():
childWindow = childInputData()
That gave me the error:
QWidget: Must construct a QApplication before a QPaintDevice
So now I am doing, from my main class:
class myMainClass():
app = QtGui.QApplication(sys.argv)
childWindow = childInputData()
Now there is no error, but the window is showed twice and the script does not wait until the data is entered, it just shows the window and continues without waiting.
What is wrong here?
It's perfectly normal that the window is shown and the script goes on: you never told the script to wait for the user to answer. You just told it to show a window.
What you would like is the script to stop until the user is done and the window is closed.
Here's one way to do it:
from PyQt4 import QtGui,QtCore
import sys
class childInputData(QtGui.QWidget):
def __init__(self, parent=None):
super(childInputData, self).__init__()
self.show()
class mainClass():
def __init__(self):
app=QtGui.QApplication(sys.argv)
win=childInputData()
print("this will print even if the window is not closed")
app.exec_()
print("this will be print after the window is closed")
if __name__ == "__main__":
m=mainClass()
The exec() method "Enters the main event loop and waits until exit() is called" (doc):
the script will be blocked on the line app.exec_() until the window is closed.
NB: using sys.exit(app.exec_()) would cause the script to end when the window is closed.
An other way is to use QDialog instead of QWidget. You then replace self.show() by self.exec(), which will block the script
From the doc:
int QDialog::exec()
Shows the dialog as a modal dialog, blocking until the user closes it
Finally, this answer of a related question advocates not to use exec, but to set the window modality with win.setWindowModality(QtCore.Qt.ApplicationModal). However this doesn't work here: it blocks inputs in other windows, but do not block the script.
you dont need the myMainClass...do something like this:
import sys
from PyQt4 import QtGui
from input_data_window import Ui_Form
class childInputData(QtGui.QWidget):
def __init__(self, parent=None):
super(childInputData, self).__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.setFocus(True)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
win = childInputData()
win.show()
sys.exit(app.exec_())

How to make a window that occupies the full screen without maximising?

I'm writing in python using Qt
I want to create the application window (with decorations) to occupy the full screen size. Currently this is the code I have:
avGeom = QtGui.QDesktopWidget().availableGeometry()
self.setGeometry(avGeom)
the problem is that it ignores window decorations so the frame is larger... I googled and what not, found this:
http://harmattan-dev.nokia.com/docs/library/html/qt4/application-windows.html#window-geometry
which seems to indicate I need to set the frameGeometry to the avGeom however I haven't found a way to do that. Also, in the comments in the above link it says what I'm after may not be even possible as the programme can't set the frameGeometry before running... If that is the case I just want confirmation that my problem is not solvable.
EDIT:
So I played around with the code a bit and this gives what I want... however the number 24 is basically through trial and error until the window title is visible.... I want some better way to do this... which is window manager independent..
avGeom = QtGui.QDesktopWidget().availableGeometry()
avGeom.setTop(24)
self.setGeometry(avGeom)
Now I can do what I want but purely out of trial and error
Running Ubuntu, using Spyder as an IDE
thanks
Use QtGui.QApplication().desktop().availableGeometry() for the size of the window:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from PyQt4 import QtGui, QtCore
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonClose = QtGui.QPushButton(self)
self.pushButtonClose.setText("Close")
self.pushButtonClose.clicked.connect(self.on_pushButtonClose_clicked)
self.layoutVertical = QtGui.QVBoxLayout(self)
self.layoutVertical.addWidget(self.pushButtonClose)
titleBarHeight = self.style().pixelMetric(
QtGui.QStyle.PM_TitleBarHeight,
QtGui.QStyleOptionTitleBar(),
self
)
geometry = app.desktop().availableGeometry()
geometry.setHeight(geometry.height() - (titleBarHeight*2))
self.setGeometry(geometry)
#QtCore.pyqtSlot()
def on_pushButtonClose_clicked(self):
QtGui.QApplication.instance().quit()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())
I've always found inheritting from the QMainWindow class to be particularly useful. Like this:
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class Some_APP(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
### this line here is what you'd be looking for
self.setWindowState(Qt.WindowMaximized)
###
self.show()
def main():
app = QApplication(sys.argv)
some_app = Some_APP()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

Categories