通过上下文菜单为 PyQt 中的 QTableView 和 QTableWidget 传递一个实例

Posted

技术标签:

【中文标题】通过上下文菜单为 PyQt 中的 QTableView 和 QTableWidget 传递一个实例【英文标题】:Pass an instance via Context menu for QTableView and QTableWidget in PyQt 【发布时间】:2016-11-08 00:38:43 【问题描述】:

嗯,好的,朋友们,现在我正在尝试为我的应用程序中的每个表格添加“导出到 Excel”功能,如下所示:

...
def update_exportable_tables(self, *window):
    """
    Please don't ask why, here 'I know what I'm doing'
    """
    if not window:
        window = self.window

    for obj in window.__dict__:
        objname = obj.title().lower()
        the_object_itself = window.__dict__[obj]

        if isinstance(the_object_itself, (QTableWidget, QTableView)):
            the_object_itself.setContextMenuPolicy(Qt.CustomContextMenu)
            the_object_itself.customContextMenuRequested.connect(self.TableContextEvent)


def TableContextEvent(self, event):
    menu = QMenu()
    excelAction = menu.addAction(u"Export to Excel")
    excelAction.triggered.connect(self.export)
    action = menu.exec_(QCursor.pos())

def export(self):
    print 'Here I should do export'
...

是的,它工作正常,但是....问题是我应该如何将点击的表格实例传递给我的 export() 函数?

【问题讨论】:

您可以使用变量来记住“活动”表。您可以在TableContextEvent 中查看event 参数中的内容, @furas 事件是 PyQt4.QtCore.QPoint(),仅此而已。 【参考方案1】:

有几种不同的方法可以解决这个问题。这是一种方法:

def update_exportable_tables(self):
    for widget in QtGui.qApp.allWidgets():
        if isinstance(widget, QTableView):
            widget.setContextMenuPolicy(Qt.CustomContextMenu)
            widget.customContextMenuRequested.connect(self.showContextMenu)

def showContextMenu(self, pos):
    table = self.sender()
    pos = table.viewport().mapToGlobal(pos)
    menu = QtGui.QMenu()
    excelAction = menu.addAction("Export to Excel")
    if menu.exec_(pos) is excelAction:
        self.export(table)

def export(self, table):
    print 'Here I should do export:', table

(注意:QTableWidgetQTableView 的子类)。

【讨论】:

再次感谢您的帮助!就像一个魅力一样,除了菜单出现在远离实际点击和主窗口之外的奇怪坐标处。我应该如何解决该故障并关闭问题? ^_^ 固定鼠标位置:def showContextMenu(self, pos): pos = QCursor().pos() @pmus。是的,抱歉 - pos 需要映射到全局坐标。使用QCursor 并不理想,因为它不会提供适当的键盘支持。我已经相应地更新了我的答案。【参考方案2】:

好的,感谢Eli Bendersky,我用谷歌搜索了一种方法。

if isinstance(the_object_itself, (QTableWidget, QTableView)):
    the_object_itself.setContextMenuPolicy(Qt.CustomContextMenu)
    tricky = lambda: self.TableContextEvent(the_object_itself)
    the_object_itself.customContextMenuRequested.connect(tricky)
...

def TableContextEvent(self, table_instance):
    print table_instance
    #     ^^^^^^^^^^^^^ And yes, we have it!

upd1:还是错了,因为只连接了一个实例(到处都是最后一个表实例)

【讨论】:

以上是关于通过上下文菜单为 PyQt 中的 QTableView 和 QTableWidget 传递一个实例的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 (Python):通过 contextmenu 从 qpushbutton 获取值

PyQt 上下文菜单

QComboBox的PyQt右键菜单

使用 PyQt5 创建上下文菜单

上下文菜单未使用 PyQt5 显示正确的语言

PyQt 上下文菜单快捷方式