Refresh Main Window When Secondary Window Is Closed PyQt5

Question:

In PyQt5, I have a window which reads from a database and adds that information to a widget. There is also a second window, which, when opened, adds a new table to the database. What I’m trying to do is reload the main window when the secondary window is closed. I don’t want to change the secondary window to a QDialoge and need to use .show(), not .exec_(). Is there any way I could do this.

There is my code:

import sys
import sqlite3
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QListWidget, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt

class SecondWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(SecondWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle("App 2")

        label = QLabel("INSERTED VALUES")

        label.setAlignment(Qt.AlignCenter)
        
        self.setCentralWidget(label)

        #Open Database
        self.conn = sqlite3.connect("connections.db")
        self.cursor = self.conn.cursor()

        #Add New Table To Database
        self.cursor.execute('''CREATE TABLE `New`
                     (name text, GD text)''')

        self.conn.commit()
        self.conn.close()

class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        self.setWindowTitle("App")
        
        self.list = QListWidget()

        self.cursorCount = 0

        #Open Database
        self.conn = sqlite3.connect("connections.db")
        self.cursor = self.conn.cursor()

        try:
            #Try To Create A Table If It Doesn't exit
            self.cursor.execute('''CREATE TABLE `Default`
                     (name text, GD text)''')
        except:
            pass

        #Get A List Of All The Tables
        self.cursor.execute('SELECT name FROM sqlite_master WHERE type= "table"')

        for table in self.cursor.fetchall():
            self.list.insertItem(self.cursorCount, table[0])
            self.cursorCount += 1

        self.conn.commit()
        self.conn.close()

        self.list.item(0).setSelected(True)
        

        self.btn = QPushButton()
        self.btn.setText("click me!")
        self.btn.clicked.connect(self.openWin)

        winWidget = QWidget()
        self.setCentralWidget(winWidget)

        layout = QVBoxLayout()
        layout.addWidget(self.list)
        layout.addWidget(self.btn)

        winWidget.setLayout(layout)

    def openWin(self):
        self.win = SecondWindow()
        self.win.show()


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec_()

Any help would be appreciated

Asked By: user14993843

||

Answers:

I am not sure I got your problem right but I think you could use signals from PyQt5 and the closeEvent method. Basically, you should create a signal in the second window that will be emitted when the close event happens, and connect this signal to a slot in the first window.

import with:

from PyQt5.QtCore import pyqtSignal

when declaring the second window class, before init, declare your signal:

class SecondWindow(QMainWindow):
    window_closed = pyqtSignal()

create a method named closeEvent that will be called when you close the window, and when it happens it should emit the signal you previously declared:

def closeEvent(self, event):
    self.window_closed.emit()
    event.accept()
    # event.ignore() # if you want the window to never be closed

and modify the MainWindow openWin method to connect the signal from the second window to the method you want to be called:

def openWin(self):
    self.win = SecondWindow()
    self.win.window_closed.connect(self.do_something)
    self.win.show()

def do_something(self):
    print("You closed the second window!")

Edit:

The entire code should be something like this (I removed the parts database related to test myself, seems to be working fine).

import sys
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QListWidget, QVBoxLayout, QWidget
from PyQt5.QtCore import Qt, pyqtSignal

class SecondWindow(QMainWindow):

    window_closed = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super(SecondWindow, self).__init__(*args, **kwargs)
        self.setWindowTitle("App 2")
        label = QLabel("INSERTED VALUES")
        label.setAlignment(Qt.AlignCenter)
        self.setCentralWidget(label)

    def closeEvent(self, event):
        self.window_closed.emit()
        event.accept()
        # event.ignore() # if you want the window to never be closed

class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        self.setWindowTitle("App")
        self.btn = QPushButton()
        self.btn.setText("click me!")
        self.btn.clicked.connect(self.openWin)
        winWidget = QWidget()
        self.setCentralWidget(winWidget)
        layout = QVBoxLayout()
        layout.addWidget(self.btn)
        winWidget.setLayout(layout)

    def openWin(self):
        self.win = SecondWindow()
        self.win.window_closed.connect(self.do_something)
        self.win.show()

    def do_something(self):
        print("You closed the second window!")

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.