Python中文
首页
教程
问答
标签
搜索
登录
注册
奇怪的发射行为。执行emit时无法调用slot
回答此问题可获得
20
贡献值,回答如果被采纳可获得
50
分。
<p>我对PySide/Qt有这种奇怪的情况。在</p> <p><strong>编辑:最后,我添加了一个小的“可以运行”代码来测试经验丰富的行为。如果你愿意,你可以跳过唠叨,通过实际的代码来看看我在说什么。根据信号/插槽机制,它的行为应该出乎意料</strong></p> <p>快速展示设计。我有一个主窗口,里面有两个视图,两个控制器和两个模型。在</p> <p>这两个视图是在主窗口中创建的,如下所示</p> <pre><code> ui.listView = views.ListView(ui.hSplitter) ui.threeDView = views.ThreeDView(ui.hSplitter) </code></pre> <p>没什么特别的。模型是在ui之后创建的</p> ^{pr2}$ <p>第一个包含实际数据。第二个包含选择,因此3D视图可以检查选择是否已更改(通常通过用户单击listView)并在3D中打印实体</p> <p>最后,控制器是这样创建的</p> <pre><code>threeDController = ThreeDController(threeDView=self._ui.threeDView, listModel=listModel, listSelectionModel=listSelectionModel) listController = ListController(listView = self._ui.listView, listModel = listModel, listSelectionModel=listSelectionModel) </code></pre> <p>然后我在listModel中添加一些模拟项,以便单击一些内容。在</p> <p>其思想是列表应该显示项目,当您单击时,三维视图将显示它们。我这样做了:ListView就是这样定义的</p> <pre><code>class ListView(QtGui.QWidget): itemActivated = QtCore.Signal() def __init__(self, parent): super(ListView, self).__init__(parent) self._ui = self._createUi() self._ui.qListWidget.itemActivated.connect(self._itemActivatedSlot) def _createUi(self): ui = UIElems() hLayout = QtGui.QHBoxLayout(self) ui.qListWidget = QtGui.QListWidget(self) hLayout.addWidget(ui.qListWidget) return ui def _itemActivatedSlot(self, listitem): # I CONFIRM THIS LINE IS EXECUTED # SO THE EMIT IS CORRECTLY PERFORMED self.itemActivated.emit() </code></pre> <p>注意我是如何为ListView定义itemActivated信号的。我截获QListWidget(注意Q)itemActivated,将其重定向到受保护的ListView插槽,然后发出一个ListView信号,它将被外部监听。我这样做是因为我想让ListView完全包装它的内部控件。在</p> <p>谁正在收听此ListView itemActivated事件?ListController是,它应该获得这个信号,并相应地设置选择,以便3d控制器可以更新3d视图。在</p> <p>这是ListController</p> <pre><code>class ListController(QtCore.QObject): def __init__(self, listView, listModel, selectionModel): super(ListController, self).__init__() self._listView = listView self._listModel = listModel self._selectionModel = selectionModel self._listModel.changed.connect(self._listModelChanged) # HERE IS THE PROBLEM self._listView.itemActivated.connect(self._listViewItemActivated) # PLACEHOLDER def _listModelChanged(self): self._listView.setItems(self._listModel.items()) def _listViewItemActivated(self): ### ... AND HERE identifier = self._listView.currentSelectedId() self._selectionModel.setSelected(identifier) </code></pre> <p>如您所见,在控制器中,我连接到ListView的信号itemActivated,并期望看到正确的插槽被调用。不幸的是,这并没有发生。但是,如果我在占位符处添加以下行</p> <pre><code> self._listView.itemActivated.emit() </code></pre> <p>也就是说,我在“从外部”连接后立即强制发射(我在控制器中,我发出在视图中定义的信号),我开始接收事件,一切都按预期工作:每次我单击项目时,都会调用ListController.\u listViewItemActivated,并因此更新3d视图。在</p> <p>我试着在一个较小的程序中复制这个案例,但是我总是得到一些有用的东西。在这一点上,你是我唯一的希望,因为我的行为没有任何意义。在</p> <p><strong>编辑</strong></p> <p>此代码显示了相同的行为,只是现在即使是强制发射也无法解决。尝试单击listview中的“hello”元素。它会打印信息,但不会发出“胜利!”将不打印行。在</p> <pre><code>import sys from PySide import QtGui, QtCore class ListView(QtGui.QWidget): itemActivated = QtCore.Signal() def __init__(self, parent): super(ListView, self).__init__(parent) qlistview = QtGui.QListWidget(self) qlistview.addItem("hello") qlistview.itemActivated.connect(self._itemActivatedSlot) def _itemActivatedSlot(self, listitem): print "Activated "+ listitem.text() # this is printed. self.itemActivated.emit() # Why not emitted or received ?!?! class ListController(QtCore.QObject): def __init__(self, listView): super(ListController, self).__init__() self._listView = listView self._listView.itemActivated.connect(self._listViewItemActivated) # self._listView.itemActivated.emit() # uncomment to see that the signal is actually connected and the mechanism works def _listViewItemActivated(self): print "_listViewItemActivated activated!!! Victory!" class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() listView = ListView(self) listController = ListController(listView) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) app.setApplicationName("Test") mw = MainWindow() mw.show() sys.exit(app.exec_()) </code></pre>
0 条评论
分类:
Python问答
请先
登录
后评论
默认排序
时间排序
1 个回答
匿名
1天前
擅长:python、mysql、java
<p>好吧,这个问题很微妙,我是个傻瓜,没有意识到这一点,因为它毕竟是基本的python。你必须将控制器存储在主窗口对象的某个地方,否则一旦<strong>init</strong>结束,它们就会超出范围并消失,因此它们不再监听信号。在</p>
请先
登录
后评论
针对此问题:
更多的回答
关注
89
关注
收藏
1
收藏,
216
浏览
网友 提问于 2天前
相关Python问题
如何添加虚拟方法
2 回答
如何添加表示整数的擦边字符串?
2 回答
如何添加要在Bokeh中使用的新font.ttf文件?
1 回答
如何添加要显示的矩阵XY轴编号和XY轴
9 回答
如何添加计数?
6 回答
如何添加计数器函数?
3 回答
如何添加计数器列来计算数据帧中另一列中的特定值?
1 回答
如何添加计数器来跟踪while循环中的月份和年份?
1 回答
如何添加计数并删除countplot的顶部和右侧脊椎?
3 回答
如何添加计时器wx.应用程序更新窗口对象的主循环?
8 回答
如何添加评论到帖子?PostDetailVew,Django 2.1.5
9 回答
如何添加评论拉梅尔亚姆
1 回答
如何添加诸如矩阵Python/Pandas之类的数据帧?
8 回答
如何添加谷歌地点自动完成到Flask?
8 回答
如何添加超时、python discord bot
9 回答
如何添加超过1dp的检查
4 回答
如何添加距离方法
7 回答
如何添加跟随游戏的敌人精灵
1 回答
如何添加路径以便python可以找到程序?
10 回答
如何添加身份验证/安全性以使用happybase访问HBase?
6 回答