Closing all window instances when MainWindow() is closed
-
How can I get the program to completely shut down and close all window instances when MainWindow() is closed?
I used to have a separate close button which did the job but I don't any longer. For reference, here's my code if you want to see what I mean.
By right clicking anywhere on the webpage, you can open a new window. This new window is the NewWindow() class.from PyQt5.QtCore import QUrl, QSize, Qt from PyQt5.QtWidgets import QAction, QMenu, \ QPushButton, QToolBar, QApplication, QMainWindow, QTabWidget, QLineEdit from PyQt5.QtGui import QFont from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineSettings import sys currenturl = None emptytab = QUrl("http://duckduckgo.com") class WebEnginePage(QWebEnginePage): print("ree") class Tabs(QTabWidget): def __init__(self): super().__init__() class Browser(QWebEngineView): def __init__(self, MainWindow): super().__init__() self.MainWindow = MainWindow settings = QWebEngineSettings.globalSettings() settings.setAttribute(QWebEngineSettings.ErrorPageEnabled, False) #disable chromium error pages def contextMenuEvent(self, event): self.menus2 = QMenu() self.menus2.setStyleSheet("background-color:rgb(209,222,235); QMenu::item::hover {text-color:rgb(30,30,30);}") action2 = QAction("OPEN NEW WINDOW", self) self.menus2.addAction(action2) self.menus2.popup(event.globalPos()) action2.triggered.connect(self.open_new_window) def open_new_window(self): self.new_window = NewWindow() #this must have "self", otherwise the new window instance is destroyed immediately class Urlbar(QLineEdit): def __init__(self, MainWindow): super().__init__() self.MainWindow = MainWindow class NewWindow(QMainWindow): def __init__(self): super().__init__() self.resize(400, 300) self.setMaximumHeight(300) self.setMaximumWidth(400) self.browser = QWebEngineView() self.browser.load(QUrl("http://duckduckgo.com")) self.setCentralWidget(self.browser) self.show() class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setMinimumHeight(680) self.setMinimumWidth(800) self.tabs = Tabs() self.setCentralWidget(self.tabs) #setting tabs as the central widget of the window self.tabs.setTabsClosable(True) self.tabs.currentChanged.connect(self.current_tab_changed) self.tabs.tabCloseRequested.connect(self.close_tab) toolbar = QToolBar() #toolbar, we'll disable the context menu it has by default QToolBar.setContextMenuPolicy(self, Qt.NoContextMenu) toolbar.setIconSize(QSize(50, 44)) toolbar.setMovable(False) self.addToolBar(toolbar) cornerwidget = QPushButton(self.tabs) #new tab button self.tabs.setCornerWidget(cornerwidget, Qt.TopLeftCorner) backbtn = QPushButton() #back button toolbar.addWidget(backbtn) forwardbtn = QPushButton() #forward button toolbar.addWidget(forwardbtn) refreshbtn = QPushButton() #refresh button toolbar.addWidget(refreshbtn) self.urlbar = Urlbar(self) #address bar font = QFont() font.setFamily("Arial") font.setPointSize(11) font.setBold(False) self.urlbar.setFont(font) toolbar.addWidget(self.urlbar) self.urlbar.returnPressed.connect(self.go_to_url) #press enter to load url cornerwidget.clicked.connect(self.add_new_tab) #button signals backbtn.clicked.connect(self.back) forwardbtn.clicked.connect(self.forward) refreshbtn.clicked.connect(self.refresh) browser = Browser(self) #start by adding a new tab self.add_new_tab(browser, emptytab) self.show() def add_new_tab(self, browser, urli=None): index = self.tabs.count() browser = Browser(self) browser.setPage(WebEnginePage(self)) #make a custom webenginepage self.tabs.addTab(browser, "") #2nd argument is title self.tabs.setCurrentIndex(index) if urli == None: browser.setUrl(emptytab) else: browser.setUrl(QUrl(urli)) browser.loadFinished.connect(lambda tabtitle: self.on_load_finished(browser)) browser.loadFinished.connect(lambda windowtitle: self.setWindowTitle(browser.page().title())) browser.urlChanged.connect(lambda url: self.update_urlbar_and_window(url, browser)) def on_load_finished(self, browser): loadedpage = browser i = self.tabs.indexOf(loadedpage) title = browser.page().title() self.tabs.setTabText(i, title) #handles tab titles def go_to_url(self): url = QUrl(self.urlbar.text()).toString() self.tabs.currentWidget().load(QUrl(url)) def update_urlbar_and_window(self, url, browser): if browser != self.tabs.currentWidget(): return windowtitle = self.tabs.currentWidget().page().title() self.setWindowTitle(windowtitle) def current_tab_changed(self): url = self.tabs.currentWidget().url() self.update_urlbar_and_window(url, self.tabs.currentWidget()) def close_tab(self, index): if self.tabs.count() > 1: self.tabs.removeTab(index) return def back(self): #button events start here self.tabs.currentWidget().back() def forward(self): self.tabs.currentWidget().forward() def refresh(self): self.tabs.currentWidget().reload() app = QApplication(sys.argv) app.setApplicationName("Extreme Browser") window = MainWindow() app.exec_()```
-
How can I get the program to completely shut down and close all window instances when MainWindow() is closed?
I used to have a separate close button which did the job but I don't any longer. For reference, here's my code if you want to see what I mean.
By right clicking anywhere on the webpage, you can open a new window. This new window is the NewWindow() class.from PyQt5.QtCore import QUrl, QSize, Qt from PyQt5.QtWidgets import QAction, QMenu, \ QPushButton, QToolBar, QApplication, QMainWindow, QTabWidget, QLineEdit from PyQt5.QtGui import QFont from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineSettings import sys currenturl = None emptytab = QUrl("http://duckduckgo.com") class WebEnginePage(QWebEnginePage): print("ree") class Tabs(QTabWidget): def __init__(self): super().__init__() class Browser(QWebEngineView): def __init__(self, MainWindow): super().__init__() self.MainWindow = MainWindow settings = QWebEngineSettings.globalSettings() settings.setAttribute(QWebEngineSettings.ErrorPageEnabled, False) #disable chromium error pages def contextMenuEvent(self, event): self.menus2 = QMenu() self.menus2.setStyleSheet("background-color:rgb(209,222,235); QMenu::item::hover {text-color:rgb(30,30,30);}") action2 = QAction("OPEN NEW WINDOW", self) self.menus2.addAction(action2) self.menus2.popup(event.globalPos()) action2.triggered.connect(self.open_new_window) def open_new_window(self): self.new_window = NewWindow() #this must have "self", otherwise the new window instance is destroyed immediately class Urlbar(QLineEdit): def __init__(self, MainWindow): super().__init__() self.MainWindow = MainWindow class NewWindow(QMainWindow): def __init__(self): super().__init__() self.resize(400, 300) self.setMaximumHeight(300) self.setMaximumWidth(400) self.browser = QWebEngineView() self.browser.load(QUrl("http://duckduckgo.com")) self.setCentralWidget(self.browser) self.show() class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.setMinimumHeight(680) self.setMinimumWidth(800) self.tabs = Tabs() self.setCentralWidget(self.tabs) #setting tabs as the central widget of the window self.tabs.setTabsClosable(True) self.tabs.currentChanged.connect(self.current_tab_changed) self.tabs.tabCloseRequested.connect(self.close_tab) toolbar = QToolBar() #toolbar, we'll disable the context menu it has by default QToolBar.setContextMenuPolicy(self, Qt.NoContextMenu) toolbar.setIconSize(QSize(50, 44)) toolbar.setMovable(False) self.addToolBar(toolbar) cornerwidget = QPushButton(self.tabs) #new tab button self.tabs.setCornerWidget(cornerwidget, Qt.TopLeftCorner) backbtn = QPushButton() #back button toolbar.addWidget(backbtn) forwardbtn = QPushButton() #forward button toolbar.addWidget(forwardbtn) refreshbtn = QPushButton() #refresh button toolbar.addWidget(refreshbtn) self.urlbar = Urlbar(self) #address bar font = QFont() font.setFamily("Arial") font.setPointSize(11) font.setBold(False) self.urlbar.setFont(font) toolbar.addWidget(self.urlbar) self.urlbar.returnPressed.connect(self.go_to_url) #press enter to load url cornerwidget.clicked.connect(self.add_new_tab) #button signals backbtn.clicked.connect(self.back) forwardbtn.clicked.connect(self.forward) refreshbtn.clicked.connect(self.refresh) browser = Browser(self) #start by adding a new tab self.add_new_tab(browser, emptytab) self.show() def add_new_tab(self, browser, urli=None): index = self.tabs.count() browser = Browser(self) browser.setPage(WebEnginePage(self)) #make a custom webenginepage self.tabs.addTab(browser, "") #2nd argument is title self.tabs.setCurrentIndex(index) if urli == None: browser.setUrl(emptytab) else: browser.setUrl(QUrl(urli)) browser.loadFinished.connect(lambda tabtitle: self.on_load_finished(browser)) browser.loadFinished.connect(lambda windowtitle: self.setWindowTitle(browser.page().title())) browser.urlChanged.connect(lambda url: self.update_urlbar_and_window(url, browser)) def on_load_finished(self, browser): loadedpage = browser i = self.tabs.indexOf(loadedpage) title = browser.page().title() self.tabs.setTabText(i, title) #handles tab titles def go_to_url(self): url = QUrl(self.urlbar.text()).toString() self.tabs.currentWidget().load(QUrl(url)) def update_urlbar_and_window(self, url, browser): if browser != self.tabs.currentWidget(): return windowtitle = self.tabs.currentWidget().page().title() self.setWindowTitle(windowtitle) def current_tab_changed(self): url = self.tabs.currentWidget().url() self.update_urlbar_and_window(url, self.tabs.currentWidget()) def close_tab(self, index): if self.tabs.count() > 1: self.tabs.removeTab(index) return def back(self): #button events start here self.tabs.currentWidget().back() def forward(self): self.tabs.currentWidget().forward() def refresh(self): self.tabs.currentWidget().reload() app = QApplication(sys.argv) app.setApplicationName("Extreme Browser") window = MainWindow() app.exec_()```
@Harborman
Do you mean callingQApplication::closeAllWindows()
orQApplication::quit()
orqApp->exit()
? -
@Harborman
Do you mean callingQApplication::closeAllWindows()
orQApplication::quit()
orqApp->exit()
?@JonB
When I had a frameless browser, there was no titlebar or a close button, so I made the button like thisclosebtn.clicked.connect(self.quit) def quit(self): QApplication.quit()
But I decided to go back to the default titlebar with default Windows buttons (minimize, maximize, close)
and need the close button to have the same functionality.
Apparently by default the close button only closes MainWindow() and nothing else.
I think both QApplication.quit() and QApplication.closeAllWindows() would get the job done, I just don't know how to tie them to the default close button.
When using closeAllWindows(), I understand the application quits when all windows have closed. -
@JonB
When I had a frameless browser, there was no titlebar or a close button, so I made the button like thisclosebtn.clicked.connect(self.quit) def quit(self): QApplication.quit()
But I decided to go back to the default titlebar with default Windows buttons (minimize, maximize, close)
and need the close button to have the same functionality.
Apparently by default the close button only closes MainWindow() and nothing else.
I think both QApplication.quit() and QApplication.closeAllWindows() would get the job done, I just don't know how to tie them to the default close button.
When using closeAllWindows(), I understand the application quits when all windows have closed.@Harborman said in Closing all window instances when MainWindow() is closed:
I just don't know how to tie them to the default close button.
I think:
- In your
MainWondow
subclassQMainWindow
and you should get (be able to override)closeEvent()
. - Or use application/main window
eventFilter
.
- In your
-
I just slapped this inside the MainWindow class and it seems to do the trick:
def closeEvent(self): sys.exit(0)
Not sure if this is a good way to do it.
@Harborman
It's a bit abrupt! "Slapped" is indeed the word.The
closeEvent()
override you have defined is fine. You ought let Qt things close down gracefully, e.g.@JonB said in Closing all window instances when MainWindow() is closed:
@Harborman
Do you mean callingQApplication::closeAllWindows()
orQApplication::quit()
orqApp->exit()
?