为什么下面的例子不起作用?在
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)
class TestViewController():
def __init__(self, view):
view.btn.clicked.connect(self.buttonClicked)
view.show()
def buttonClicked(self):
print 'clicked'
def main():
app = QtGui.QApplication(sys.argv)
view = TestView()
TestViewController(view)
app.exec_()
if __name__ == '__main__':
main()
这个例子应该表示一个MVC结构(类似于Figure 4中没有模型的结构),其中控制器(TestViewController
)接收对视图(TestView
)的引用,并将视图按钮view.btn
的点击信号连接到其函数self.buttonClicked
。在
我确信view.btn.clicked.connect(self.buttonClicked)
行已执行,但显然,它没有任何效果。有人知道怎么解决这个问题吗?在
更新(糟糕的解决方案):
在示例中,如果我替换行
^{pr2}$与
view.clicked = self.clicked
view.btn.clicked.connect(view.clicked)
它起作用了。我还是不满意。在
它不起作用的原因是,在您可以为它单击任何东西之前,控制器类正在被垃圾回收。在
当你准备好查看。单击= 自我点击,您实际上要做的是使控制器中的一个对象持久化在视图对象上,这样它就永远不会被清理掉——这不是真正的解决方案。在
如果您将控制器存储到变量,它将保护它不被收集。在
因此,如果您将上面的代码改为:
你会准备好的。在
也就是说-你到底想做什么,我不确定…似乎你在尝试为Qt设置一个MVC系统-但是Qt已经有了一个很好的系统,使用Qt设计器将接口组件从控制器逻辑(QWidget子类)中分离成UI(视图/模板)文件。再说一次,我不知道你想做什么,这可能是一个愚蠢的版本,但我建议你把它做成一个类,像这样:
^{pr2}$编辑:澄清Qt的MVC
因此,上面的例子实际上并没有动态加载ui并创建控制器/视图分离。在这里表现有点难。最好学习一些基于Qt/Designer的示例/教程-我在这里有一个http://bitesofcode.blogspot.com/2011/10/introduction-to-designer.html,但是很多可以在网上找到。在
简单的回答是,loadUi方法可以替换为PyQt4.uic动态加载(有许多不同的方法来设置它),这样您的代码最终会读取如下内容:
编辑2:存储UI引用
如果更容易可视化此概念,还可以存储对生成的UI对象的引用:
相关问题 更多 >
编程相关推荐