それが機能しない理由は、コントローラークラスが何かをクリックする前にガベージコレクションされているためです。
view.clicked = self.clickedを設定すると、実際に実行しているのは、コントローラーのオブジェクトの1つをビューオブジェクトに保持して、クリーンアップされないようにすることです。これは実際には解決策ではありません。
コントローラを変数に保存すると、コントローラが収集から保護されます。
したがって、上記のコードを次のように変更すると、次のようになります。
ctrl = TestViewController(view)
これですべての設定が完了します。
そうは言っても、ここで何をしようとしているのか、よくわかりません... Qt用にMVCシステムをセットアップしようとしているようですが、Qtには、QtDesignerを使用して分離するためのかなり優れたシステムがすでにあります。コントローラーロジック(QWidgetサブクラス)からUI(ビュー/テンプレート)ファイルへのインターフェイスコンポーネント。繰り返しになりますが、私はあなたが何をしようとしているのかわかりません。これはそれのばかげたバージョンかもしれませんが、私はそれを次のようにすべて1つのクラスにすることをお勧めします:
from PyQt4 import QtGui
import sys
class TestView(QtGui.QWidget):
def __init__(self):
super(TestView, self).__init__()
self.initUI()
def initUI(self):
self.btn = QtGui.QPushButton('Button', self)
self.btn.resize(self.btn.sizeHint())
self.btn.move(50, 50)
self.btn.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print 'clicked'
def main():
app = QtGui.QApplication(sys.argv)
view = TestView()
view.show()
app.exec_()
if __name__ == '__main__':
main()
編集:QtのMVCを明確にする
したがって、この上記の例では、実際にUIを動的にロードして、コントローラー/ビューの分離を作成することはありません。ここに表示するのは少し難しいです。Qt /Designerベースの例/チュートリアルを実行するのが最適です-ここに1つありますhttp://bitesofcode.blogspot.com/2011/10/introduction-to-designer.htmlが、多くはオンラインで見つけることができます。
簡単に言うと、loadUiメソッドをPyQt4.uic動的ロードに置き換えることができます(これを設定するにはさまざまな方法があります)。これにより、コードは最終的に次のようになります。
from PyQt4 import QtGui
import PyQt4.uic
import sys
class TestController(QtGui.QWidget):
def __init__(self):
super(TestController, self).__init__()
# load view
uifile = '/path/to/some/widget.ui'
PyQt4.uic.loadUi(uifile, self)
# create connections (assuming there is a widget called 'btn' that is loaded)
self.btn.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print 'clicked'
def main():
app = QtGui.QApplication(sys.argv)
view = TestController()
view.show()
app.exec_()
if __name__ == '__main__':
main()
編集2:UI参照の保存
この概念を視覚化する方が簡単な場合は、生成されたUIオブジェクトへの参照を保存することもできます。
from PyQt4 import QtGui
import PyQt4.uic
import sys
class TestController(QtGui.QWidget):
def __init__(self):
super(TestController, self).__init__()
# load a view from an external template
uifile = '/path/to/some/widget.ui'
self.ui = PyQt4.uic.loadUi(uifile, self)
# create connections (assuming there is a widget called 'btn' that is loaded)
self.ui.btn.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print 'clicked'
def main():
app = QtGui.QApplication(sys.argv)
view = TestController()
view.show()
app.exec_()
if __name__ == '__main__':
main()