2012-11-25 12 views
6

私はPySideにちょっと新しいです。一度に1つのウィジェットを表示するメインウィンドウオブジェクトがあります。私は、ボタンを押したときにウィンドウ内に表示されているウィジェットを置き換えるために、QMainWindowクラスの中央ウィジェットを変更しようとしていました。問題は、押されたボタンがメインウィンドウクラスではなく、ウィジェットクラスにあることです。MainWindowのCentralWidgetを置き換えます。

言う...

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)を削除します。 loginButtonlogin_screenウィジェット内)を押すと、メインウィンドウの中央ウィジェットとして別のウィジェット(例:logged_in_screen)を取得するにはどうすればよいですか?

ログインメソッドは、メインウィンドウクラス内にある必要がありますか?もしそうなら、どうすればlogin_screenで押されたボタンをメインウィンドウの方法で接続できますか?

答えて

10

セントラルウィジェットとして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の方法は、それが依存する必要があります。おそらく、特定のセントラルウィジェットを追加/削除/表示するためのメインウィンドウ用の単純なインタフェースを定義し、それをloginメソッドから呼び出すと、LoginScreenとなるでしょう。このようにしてLoginScreenクラスは、中央ウィジェットが実際にQStackedWidgetであるかどうかなどの実装の詳細を知る必要はありません。あるいは、このことは別の方法で行われます。

+1

**はQStackedWidget **ことをしました。また、私は 'self.parent()。login'については考えませんでした。私のOOPで作業しなければならないだろうと思う。どうもありがとうございました! –

+0

中央ウィジェットとして設定すると、QMainWindowはそのウィジェットの所有権を取得します。他のウィジェットを中央のウィジェットとして設定すると、最初のウィジェットが破壊されてしまいますが、これは悪いことです。 –

+0

@HrvojeTそうですね、私の答えは 'QStackedWidget'を使用しています。ハックではないので、正しく動作させるには醜いコードが必要になるでしょう。 – Bakuriu

-2

あなたは(繰り返し)これを行うには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_()) 
+0

これは可能な回避策ですが、最後のcentral_widgetのdestryoingはひどい副作用です... –

関連する問題