Replace CentralWidget in MainWindow

I'm a little new to PySide.I have a main window object that shows one widget at a time. I am trying to change the central widget of the QMainWindow class to replace the visible widget in the window when a button is clicked. The problem is that the pressed button is in the Widget class, and not in the main window class.

let's say ...

 class App(QtGui.QMainWindow): def __init__(self): super(App, self).__init__() self.initUI() def initUI(self): self.statusBar().showMessage('Listo.') #Status Bar self.login_screen = LoginScreen() self.logged_in_screen = LoggedInScreen() self.setCentralWidget(self.login_screen) self.setGeometry(300, 300, 450, 600) #Window Size self.setWindowTitle('PyTransactio - Client') #Window Title self.setWindowIcon(QtGui.QIcon('icon.png')) #App Icon self.show() 

The pressed button is in the login_screen instance. The method called when the button is clicked is inside the LoginScreen class:

 def login(self): """ Send login data to the server in order to log in """ #Process self.setParent(None) 

Setting the parent widget to None removes the widget ( login_screen ) from the main window. What should I do to get the next widget (e.g. logged_in_screen ) as the central widget of the main window when loginButton pressed (inside the login_screen widget)?

Maybe the login method should be inside the main window class? If so, how can I connect the buttons pressed in login_screen using the main window method?

+6
source share
2 answers

You can use the QStackedWidget as a central widget and add a login screen and "login" to it.

Usage example:

 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_() 

If you do not want to use this widget, I think you will have to call QMainWindow.setCentralWidget every time you change the center widget.

As for the login method, it depends. You could probably define a simple interface for your main window to add / remove / show certain central widgets and call it from the login LoginScreen method. Thus, the LoginScreen class LoginScreen not need to know about the implementation details, for example, if the central widget is actually a QStackedWidget , otherwise it is done in a different way.

+10
source

You can use QMainWindow.setCentralWidget for this (repeatedly):

 #! /usr/bin/env python3 from PySide import QtGui from PySide import QtCore import sys app = QtGui.QApplication(sys.argv) mw = QtGui.QMainWindow() w2 = QtGui.QWidget() pb = QtGui.QPushButton('push me', w2) l1 = QtGui.QLabel('orig') l2 = QtGui.QLabel('changed') mw.setCentralWidget(l1) pb.clicked.connect(lambda: mw.setCentralWidget(l2)) mw.show() w2.show() sys.exit(app.exec_()) 
-2
source

All Articles