Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python QAction知道在QTableView中触发包含它的上下文菜单的项目_Python_Pyqt - Fatal编程技术网

Python QAction知道在QTableView中触发包含它的上下文菜单的项目

Python QAction知道在QTableView中触发包含它的上下文菜单的项目,python,pyqt,Python,Pyqt,我有一个QTableView/QAbstractTableModel框架,我在其中实现了一个上下文菜单,最多有2个操作,这取决于请求菜单的索引。对于这两个操作中的一个,一旦触发,我希望在请求上下文菜单的位置发出索引。我有一个可行的解决方案,但我不喜欢 守则: class MyModel(QAbstractTableModel): ... def _restore_all(self): print('restore all') def _restore

我有一个QTableView/QAbstractTableModel框架,我在其中实现了一个上下文菜单,最多有2个操作,这取决于请求菜单的索引。对于这两个操作中的一个,一旦触发,我希望在请求上下文菜单的位置发出索引。我有一个可行的解决方案,但我不喜欢

守则:

class MyModel(QAbstractTableModel):

    ...

    def _restore_all(self):
        print('restore all')

    def _restore_index(self, index):
        print('restore index at: row = ' , index.row(), ', column = ', index.column())
    ...

class _ItemAwareAction(QAction):

    _mytriggered = pyqtSignal('QModelIndex')

    def __init__(self, *args, index=None, **kwargs):
        super().__init__(*args, **kwargs)
        self._index = index
        self.triggered.connect(self._emit_index)

    def _emit_index(self):
        self._mytriggered.emit(self._index)

class MyTableView(QTableView):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        model = MyModel(self)
        self.setModel(model)
        # Attributes
        restore_all_action = QAction('Restore all values', self)
        self._restore_all_action = restore_all_action
        self._menu = QMenu(self)
        # Connexions
        self.customContextMenuRequested.connect(self._item_context_menu)
        restore_all_action.triggered.connect(model._restore_all)

    def _item_context_menu(self, pos):
        menu = self._menu
        menu.clear()
        index = self.indexAt(pos)
        model = self.model()
        originals = model._originals
        if not originals:
            return
        menu.addAction(self._restore_all_action)
        references = model._index_to_references(index)
        if references in originals:
            action = _ItemAwareAction(
                'Restore this value', parent=self, index=index
            )
            action._mytriggered.connect(model._restore_index)
            menu.addAction(action)
        menu.popup(self.viewport().mapToGlobal(pos))
    ...

我发现我的
\u ItemAwareAction
类是一个不必要的循环。也许您可以给我指出一个更简单、更直接的解决方案。

更简单的解决方案是使用lambda或partials:

def\u项目上下文菜单(self,pos):
# ...
如果参考文件为原件:
action=QAction('恢复此值',父级=self)
action.triggered.connect(lambda:model.\u restore\u index(索引))
# ...
由于您没有执行排序循环,您甚至可以只检查触发的操作是否应该重置,这是通过使用
exec()
(在触发/关闭菜单之前阻止)而不是立即返回来完成的:

def\u项目上下文菜单(self,pos):
# ...
如果参考文件为原件:
restoreAction=QAction('Restore this value',parent=self)
其他:
#取消菜单不返回任何内容,我们需要与其他内容进行比较
restoreAction=-1
if menu.exec(self.viewport().mapToGlobal(pos))==恢复操作:
模型。还原索引(索引)
另一种选择是使用操作的,然后连接到菜单
triggered
action

类MyTableView(QTableView):
定义初始化(self,*args,**kwargs):
# ...
self.\u菜单=QMenu(self)
自我菜单触发连接(自我菜单触发)
def_菜单_已触发(自身、动作):
如果isinstance(action.data(),QtCore.QModelIndex):
self.model().\u restore\u索引(action.data())
定义项目上下文菜单(自身、位置):
# ...
如果参考文件为原件:
action=QAction('恢复此值',父级=self)
action.setData(索引)
# ...

Use,它同步执行,并返回单击的操作(或无)。这样,
索引在当前范围内仍然可用。或者执行
action.triggered.connect(lambda:model.\u restore\u index(index))
。您好,非常感谢您的建议。我不太喜欢使用
exec
执行匿名函数或同步执行。因此,我选择执行
操作.setData(index)
,但我没有实现您的
\u菜单\u触发的
方法,而是从
MyModel.\u restore\u index
方法中删除了index参数,只保留
self
,要获取索引,我要执行
index=self.sender().data()<代码> > @ J.Frango认为,“代码> Exc/<代码>只对来自CutExtMeCin事件的调用(这是触发<代码> CuutTraceMeNeURQuest<<代码>信号)的阻塞,但不会阻止主QT循环的事件处理(它实际上执行一个私有的QEventLoop,就像Q对话)一样;事实上,即使在Qt源中也很常见。还要注意,使用
self.sender()
并不总是安全的(但是,至少在这个简单的场景中,只要不涉及线程,它应该是安全的)。@musicamente您完全正确,我没有意识到这一点,文档中已经明确说明了这一点,谢谢。