Qtimer and closing out an applicaiton after 15 seconds have passed - python

Evening. I am having a bit of a hard time both understanding QTimer and how it works as well as getting the below code to work. As much as I hate copy/pasting, I just cannot figure it out. The goal of this is to run the program for 15 seconds and then exit out completely. Everything else works, but when I try to integrate QTimer to count how many seconds have passed, it does nothing or just simply does not work regardless of the variations I try. Below is the latest code:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QMovie
from PyQt5.QtCore import QTimer
import winsound
import time
import sys
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(321, 249)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(0, 0, 320, 248))
self.label.setFrameShape(QtWidgets.QFrame.Box)
self.label.setOpenExternalLinks(False)
self.label.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
#Plays the movie in the Label
movie = QMovie("giphy.gif")
self.label.setMovie(movie)
movie.start()
#Plays the sound with the movie
winsound.PlaySound("magicwrd.wav", winsound.SND_ASYNC|winsound.SND_LOOP)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
#Borrowed and modified from here: https://stackoverflow.com/questions/46656634/pyqt5-qtimer-count-until-specific-seconds
#Goal is to run the application for 15 seconds and then exit out completely.
def start_timer(self, slot, count=1, interval=1000):
counter = 0
def handler():
nonlocal counter
counter += 1
slot(counter)
if counter >= count:
timer.stop()
timer.deleteLater()
timer = QtCore.QTimer()
timer.timeout.connect(handler)
timer.start(interval)
def timer_func(self, count):
if count >= 5:
sys.exit(app.exec_())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
Ui_MainWindow.start_timer(Ui_MainWindow.timer_func, 5)
app.exec_()

If you want to finish the application in T seconds then you must use a QTimer::singleShot() so that when it is triggered then QCoreApplication::quit() is invoked:
QtCore.QTimer.singleShot(T * 1000, QtCore.QCoreApplication.quit)
In the example that you link, it has another objective: to print some information every T seconds and after repeating K times the application is closed, and therefore uses a complicated logic that you do not need.
Considering the above and the PyQt5 recommendation, the solution is:
import sys
import winsound
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(321, 249)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(0, 0, 320, 248))
self.label.setFrameShape(QtWidgets.QFrame.Box)
self.label.setOpenExternalLinks(False)
self.label.setTextInteractionFlags(QtCore.Qt.NoTextInteraction)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
# Plays the movie in the Label
movie = QtGui.QMovie("giphy.gif")
self.label.setMovie(movie)
movie.start()
# Plays the sound with the movie
winsound.PlaySound("magicwrd.wav", winsound.SND_ASYNC | winsound.SND_LOOP)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
QtCore.QTimer.singleShot(15 * 1000, QtCore.QCoreApplication.quit)
sys.exit(app.exec_())

Related

How to open MainWindow from a SplashScreen without button in Pyqt5?

I am trying to create a loading screen because my MainWindow takes over 10 seconds to open, which is ok as long as I have a loading screen.
Here I have some code and when i run it, it will open a loading screen.
After the loading screen pops up i want it to immediately try to open the MainWindow. (On my actual app this would take 10 seconds to open)
I have used time.sleep to simulate the time my actual programme would take to open as this is just smaller code for you to read. However my real code will not include any sleep it will just naturally take 10 seconds to load.
How can I make it so once my loading screen is visible it will immediately open MainWindow? Currently I have not asked it to do anything, the loading screen just opens and that's it.
What extra code do I need to make it open MainWindow?
Ideally I would like to update the progress bar as this happens but that is not nessecary for now I just want to know how to open MainWindow immediately from the loading screen, thanks.
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class Ui_SplashScreen(object):
def setupUi(self, SplashScreen):
SplashScreen.setObjectName("SplashScreen")
SplashScreen.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(SplashScreen)
self.centralwidget.setObjectName("centralwidget")
self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
self.progressBar.setGeometry(QtCore.QRect(190, 220, 461, 91))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
SplashScreen.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(SplashScreen)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
SplashScreen.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(SplashScreen)
self.statusbar.setObjectName("statusbar")
SplashScreen.setStatusBar(self.statusbar)
self.retranslateUi(SplashScreen)
QtCore.QMetaObject.connectSlotsByName(SplashScreen)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
time.sleep(10)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(310, 180, 341, 161))
font = QtGui.QFont()
font.setPointSize(40)
self.label.setFont(font)
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "MY APP"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
SplashScreen = QtWidgets.QMainWindow()
ui = Ui_SplashScreen()
ui.setupUi(SplashScreen)
SplashScreen.show()
sys.exit(app.exec_())
You should not modify the code generated by pyuic so you must recreate those files that for my solution will be splash_ui.py and main_ui.py.
The idea is that the time consuming task should not run in the main thread but in a secondary thread and emit signals when it starts and ends that show and hide the splashscreen.
import threading
import sys
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow
from main_ui import Ui_MainWindow
from splash_ui import Ui_SplashScreen
def long_running_function():
import time
time.sleep(10)
class Worker(QObject):
started = pyqtSignal()
finished = pyqtSignal()
def start(self):
threading.Thread(target=self._execute, daemon=True).start()
def _execute(self):
self.started.emit()
# FIXME
long_running_function()
self.finished.emit()
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
class SplashScreen(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_SplashScreen()
self.ui.setupUi(self)
def main():
app = QApplication(sys.argv)
splash_screen = SplashScreen()
main_window = MainWindow()
worker = Worker()
worker.started.connect(splash_screen.show)
worker.finished.connect(splash_screen.close)
worker.finished.connect(main_window.show)
worker.start()
sys.exit(app.exec_())

Why my QThread class drastically slows PyQT5 app?

I'm facing the problem with Threads. I'm displaying current CPU usage with progress bar and it seems to be working well but the performance of whole window is terrible. Can't even click the button without laggy behavior. Is there any simple solution to fix it?
Here is my main code
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal
import progressBarUI
import sys
import sysnfo
class MainWindow(QtWidgets.QMainWindow, progressBarUI.Ui_MainWindow):
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start()
self.threadclass.signal.connect(self.updateProgressBar)
def updateProgressBar(self):
current_percentage = sysnfo.getCpuPercentage()
self.progressBar.setValue(current_percentage)
class ThreadClass(QThread):
signal = pyqtSignal(int)
def __init__(self, parent=None):
super(ThreadClass, self).__init__(parent)
def run(self):
while True:
current_percentage = sysnfo.getCpuPercentage()
self.signal.emit(current_percentage)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainAppWin = MainWindow()
mainAppWin.show()
app.exec_()
Here is sysnfo module:
import psutil as ps
def getCpuPercentage():
return ps.cpu_percent(interval=1)
And UI file (converted to .py file):
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(787, 203)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
self.progressBar.setGeometry(QtCore.QRect(370, 20, 381, 111))
self.progressBar.setProperty("value", 0)
self.progressBar.setObjectName("progressBar")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(20, 50, 151, 41))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 787, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Click me"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
When you use the "interval" parameter you are indicating that it measures the information during that time and calculates the average causing the execution of that function to take "interval" seconds, and the correct thing is to execute it in another thread, but you make the mistake of executing it too in the updateProgressBar method that lives in the main thread blocking it, instead use the information that sends you the signal:
#QtCore.pyqtSlot(int)
def updateProgressBar(self, percentage):
self.progressBar.setValue(percentage)

Change QLabel text dynamically not working

I am trying to change the QLabel text dymanically using QtDesigner, pyqt5.
Below is the code i am trying to use for changing the QLabel text dymanically.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label, 0, QtCore.Qt.AlignHCenter)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:28pt;\">" + self.getTime() + "</span></p></body></html>"))
def getTime(self):
time = QTime.currentTime().toString()
return time
def data(self):
time = QTime.currentTime().toString()
print("Time: " + time)
self.label.setText(time)
return time
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ex = Ui_MainWindow()
timer = QtCore.QTimer()
timer.timeout.connect(ex.data)
timer.start(1000) # 1 Second Refesh Rate
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
When i tried to run the code in QtDesigner the output window open's for a second and closed automatically. Not sure what is causing the output window to close. Please advise me to resolve the issue.
I recommend you execute your code in the terminal/CMD since many IDEs do not handle the Qt errors, if you do it you would get the following error:
Traceback (most recent call last):
File "main.py", line 33, in data
self.label.setText(time)
AttributeError: 'Ui_MainWindow' object has no attribute 'label
The error indicates that label does not exist, and that is correct because label is created after calling setupUi() but in your case "ex" does not call it. A possible solution is to first create the window and then start the timer:
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
timer = QtCore.QTimer()
timer.timeout.connect(ui.data)
timer.start(1000) # 1 Second Refesh Rate
sys.exit(app.exec_())
But a better solution is to follow the recommendations of PyQt(1) that states that you should not modify the class provided by Qt but use it as the widget interface:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label, 0, QtCore.Qt.AlignHCenter)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(
_translate(
"MainWindow",
'<html><head/><body><p><span style=" font-size:28pt;"></span></p></body></html>',
)
)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
timer = QtCore.QTimer(self)
timer.timeout.connect(self.data)
timer.start(1000)
self.data()
def data(self):
time_str = QTime.currentTime().toString()
self.label.setText(
'<html><head/><body><p><span style=" font-size:28pt;">{}</span></p></body></html>'.format(
time_str
)
)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
(1) Using the Generated Code
The problem is that you instatiate Ui_MainWindow twice: first as ex and later as ui. You connect the timer.timeout to ex, but call setupUi and show only for ui.
Try this:
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
timer = QtCore.QTimer()
timer.timeout.connect(ui.data)
timer.start(1000) # 1 Second Refesh Rate
sys.exit(app.exec_())
Qt Designer is only used for designing the UI, it does not allow running the program. Qt Creator can run programs, but only "real" Qt C++ programs.
You need to launch your .py scripts outside of Qt Designer, as if it were a normal Python script.

self.close and self.hide not working in pyqt5

I am new to python. I am using pyqt5 for GUI development. I have a main Window which should close and new dialog appears after clicking the pushButton. But it doesnot closes and neither show any error and opens the nextDialog. I also want to close nextDialog when OK button is clicked in nextDialog. Please help to check the issue. I am trying to develeop a new project but stuck on this issue. Codes are given below.
Main.py
from PyQt5 import QtCore, QtGui, QtWidgets
from nextDialog import Ui_Dialog
class Ui_MainWindow(QtWidgets.QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(370, 171)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(110, 50, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.pushButton.clicked.connect(self.opennext)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def opennext(self):
self.Dialog = QtWidgets.QDialog()
self.ui = Ui_Dialog()
self.ui.setupUi(self.Dialog)
self.Dialog.show()
self.close() #Not working
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Open"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
nextDialog.py
class Ui_Dialog(QtWidgets.QMainWindow):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(346, 182)
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(110, 80, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.exit)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def exit(self):
self.hide() #This also not working, I want either of these two to
#work
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "OK"))
Try it:
main.py
from PyQt5 import QtCore, QtGui, QtWidgets
from nextDialog import Ui_Dialog
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralwidget)
self.pushButton = QtWidgets.QPushButton("Open", self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(110, 50, 75, 23))
self.pushButton.clicked.connect(self.opennext)
def opennext(self):
self.Dialog = QtWidgets.QDialog()
self.ui = Ui_Dialog()
self.ui.setupUi(self.Dialog)
self.Dialog.show()
self.close() #Not working
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
# ui = Ui_MainWindow()
# ui.setupUi(MainWindow)
window.show()
sys.exit(app.exec_())
nextDialog.py
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(QtWidgets.QMainWindow):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(346, 182)
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(110, 80, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(Dialog.close) # <---
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "OK"))
Hi kind of difficult to understand your code, I am using just Designer to make my GUI,
in anycase I made the first part of the puzzle work for your main.py
line 4 should read class Ui_MainWindow(object):
and to close the first window about lane 25 use MainWindow.close()
added import sys too at the beginning, here the code
main.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 18 17:43:19 2020
#author: Pietro
"""
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from nextDialog import Ui_Dialog
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(370, 171)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(110, 50, 75, 23))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.pushButton.clicked.connect(self.opennext)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def opennext(self):
self.Dialog = QtWidgets.QDialog()
self.ui = Ui_Dialog()
self.ui.setupUi(self.Dialog)
self.Dialog.show()
MainWindow.close()
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Open"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
this open first window then close it when open buttton is pressed and new window appears, second part of the riddle is gonna take longer I'll try it as soon as I get some spare time
Dialog.py from answer below seems to work dont know why (dont know how main.py works too, but it is kind of more illogic to me the fact that def exit doesnt work).
nextDialog.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 18 17:43:19 2020
#author: Pietro
"""
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(QtWidgets.QMainWindow):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(346, 182)
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(110, 80, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(Dialog.close) # as answer below dont know why def exit doesnt work
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
# def exit(self):
# print('exit' *5)
# Dialog.close()
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "OK"))

Window spawned from MainWindow doesn't fully close when closing

I have a main window which creates a second window when a button is pressed. I have two problems that occur but for now I will focus on the first one: I cannot get it to completely close the old window when I close it. It closes it visually but the window is still running in the background. To illustrate this I put in a counter. Below is generic code which illustrates this issue.
Here is my dialog window:
from PyQt5 import QtCore, QtGui, QtWidgets
from form_test import Ui_Form
class formTest(QtWidgets.QWidget, Ui_Form):
def __init__(self):
QtWidgets.QWidget.__init__(self)
flags = QtCore.Qt.Drawer | QtCore.Qt.WindowStaysOnTopHint
self.setWindowFlags(flags)
self.setupUi(self)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(507, 305)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.btnOpenForm = QtWidgets.QPushButton(self.centralwidget)
self.btnOpenForm.setGeometry(QtCore.QRect(170, 30, 93, 28))
self.btnCloseForm = QtWidgets.QPushButton(self.centralwidget)
self.btnCloseForm.setGeometry(QtCore.QRect(170, 160, 93, 28))
MainWindow.setCentralWidget(self.centralwidget)
self.btnOpenForm.clicked.connect(self.openClicked)
self.btnCloseForm.clicked.connect(self.closeClicked)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.btnOpenForm.setText(_translate("MainWindow", "Open Form"))
self.btnCloseForm.setText(_translate("MainWindow", "Close Form"))
def openClicked(self):
print('open')
self.popForm = formTest()
self.popForm.show()
def closeClicked(self):
print('close')
self.popForm.close()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Here is my spawning windows code (form_test.py):
from PyQt5 import QtCore, QtGui, QtWidgets
import time, threading
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(190, 170, 93, 28))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.pushButtonClicked)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
self.loopThread = threading.Thread(target = self.looping)
self.loopThread.daemon = True
self.loopThread.start()
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.pushButton.setText(_translate("Form", "PushButton"))
def pushButtonClicked(self):
print("clicked")
def looping(self):
count = 0
while(True):
print('looping... ' + str(count))
count = count + 1
time.sleep(1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
When I close the second window it is still running in memory. When I try to open it again another one begins running and then I have two running. Is there a different window I should use which will destroy all memory when it is closed? The second issue I am having is which my actual code (not this generic code) it causes a crash when I try to launch a second time. That issue may go away with the fixing of this issue and since I am not able to share my code online I have to stay as generic as possible for now so I am hoping to solve this issue first and maybe get resolution too.
PLEASE help ... I've worked on this FAR too long!!! Thanks, in advance, for any assistance on this.

Categories

Resources