2012-11-25 10 views
6

Sono un po 'nuovo in PySide.ho un oggetto finestra principale che mostra un widget alla volta. Ho provato a cambiare il widget centrale della classe QMainWindow per sostituire il widget visibile nella finestra quando si preme un pulsante. Il problema è che il pulsante premuto si trova nella classe Widget, non nella classe della finestra principale.Sostituisci CentralWidget in MainWindow

dire ...

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

Il tasto premuto è nell'istanza login_screen. Il metodo chiamato quando viene cliccato il pulsante è all'interno della classe LoginScreen:

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

     #Process 

     self.setParent(None) 

Impostazione del widget di genitore di None rimuove il widget (login_screen) dalla finestra principale. Cosa devo fare per ottenere un altro widget (ad esempio logged_in_screen) come il widget centrale della finestra principale quando viene premuto loginButton (all'interno del widget login_screen)?

Forse il metodo di accesso dovrebbe essere all'interno della classe della finestra principale? In tal caso, come posso collegare i tasti premuti in login_screen con il metodo della finestra principale?

risposta

10

È possibile utilizzare uno QStackedWidget come widget centrale e aggiungere sia la schermata di accesso che la schermata "connesso".

Un esempio d'uso:

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

Se non si desidera utilizzare questo widget, allora penso che dovrete chiamare QMainWindow.setCentralWidget ogni volta che si cambia il widget di centrale.

Quanto a dove deve essere il metodo login, dipende. Probabilmente potresti definire una semplice interfaccia per la tua finestra principale per aggiungere/rimuovere/mostrare specifici widget centrali e chiamarla dal metodo login di LoginScreen. In questo modo la classe LoginScreen non deve conoscere dettagli di implementazione come se il widget centrale è in realtà un QStackedWidget o questa cosa viene eseguita in un altro modo.

+1

** ** QStackedWidget fatto la cosa. Inoltre, non ho mai pensato a 'self.parent(). Login'. Credo che dovrò lavorare sul mio OOP. Grazie mille! –

+0

Quando si imposta come widget centrale, QMainWindow assume la proprietà di quel widget. Quando si imposta l'altro widget come widget centrale, il primo viene distrutto, il che è negativo. –

+0

@HrvojeT Sì, ecco perché la mia risposta usa 'QStackedWidget' e non quell'hack, che probabilmente richiede un po 'di brutto codice per funzionare correttamente. – Bakuriu

-2

È possibile utilizzare QMainWindow.setCentralWidget per fare questo (più volte):

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

So che questa è una soluzione possibile, ma il destryoing dell'ultimo central_widget è un terribile effetto collaterale ... –

Problemi correlati