Заменить CentralWidget в главном окне

Я немного ново для PySide.У меня есть объект главного окна, который показывает один виджет за раз. Я пытался изменить центральный виджет QMainWindow класс для замены видимого виджета в окне при нажатии кнопки. Проблема в том, что нажатая кнопка находится в классе виджета, а не в классе главного окна.

сказать...

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

нажатая кнопка находится в login_screen экземпляра. Метод вызывается при нажатии кнопки внутри LoginScreen класс:

def login(self):
        """ Send login data to the server in order to log in """

        #Process

        self.setParent(None)

установка родительского виджета в None удаляет виджет (login_screen) из главного окна. Что мне делать, чтобы получить другой виджет (например,logged_in_screen) в качестве центрального виджета главного окна, когда loginButton (внутри login_screen виджет) нажата?

может быть, метод входа должен быть внутри класса главного окна? Если да, то как я могу подключить кнопки, нажатые в login_screen С методом главного окна?

2 ответов


вы можете использовать QStackedWidget как центральный виджет и добавьте к нему экран входа в систему и экран" вход в систему".

пример использования:

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

если вы не хотите использовать этот виджет, то я думаю, вам придется позвонить QMainWindow.setCentralWidget каждый раз, когда вы меняете Центрального виджета.

, где login метод должен быть, это зависит. Возможно, вы могли бы определить простой интерфейс для вашего mainwindow для добавления / удаления / отображения определенных центральных виджетов, и позвоните ему из login метод LoginScreen. Таким образом,LoginScreen класс не должен знать о деталях реализации, таких как, если центральный виджет на самом деле QStackedWidget или это делается другим способом.


вы можете использовать QMainWindow.setCentralWidget для этого (неоднократно):

#! /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_())