自定义QTextEdit中的位置敏感上下文菜单

1 投票
3 回答
1153 浏览
提问于 2025-04-17 09:14

我正在尝试调整QTextEdit中的右键菜单。我已经成功获取并显示了默认菜单,代码如下:

class LinkTextBrowser(QTextBrowser):
    def contextMenuEvent(self, event):
        menu = self.createStandardContextMenu(event.pos())
        # do stuff to menu here
        menu.popup(event.globalPos())

不过,这个方法在某些特定位置的点击上不太管用。比如在QTextBrowser中,右键点击链接时会出现“复制链接地址”这个选项,但只有在你真的点击了链接时,这个选项才会变得可用。我一直无法让它变得可用。我怀疑是我传给createStandardContextMenu的位置不对,但我找不到正确的位置。

我试过使用event.globalPos()和event.pos(),但都不行。我也查看了QTextEdit的源代码,但没有找到解决办法。它到底期待什么位置呢?

更新一下:问题似乎出在TextBrowser的滚动上;如果我把窗口滚到最上面,然后使用event.pos(),它就能正常工作了。我还没有写出可用的代码,但调整滚动位置是解决办法。

具体来说,我想断开“复制链接地址”这个动作发出的信号,然后连接到我自己的函数,这样我就可以在复制到剪贴板之前调整URL,让链接变得绝对等等,而我并不想重新编写已经能用的部分。

3 个回答

0

也许你可以试试下面这样的代码:

QMenu *menu = new QMenu();
menu->addAction(...);
menu->exec(textEdit->mapToGlobal(pos));

这段代码是用C++写的,但我相信你可以很容易地把它转换成Python。

0

试试用 self.mapToGlobal(event.pos()),这样可以考虑到滚动条的位置。

1

这里是坐标转换的有效代码:

class LinkTextBrowser(QTextBrowser):
    def contextMenuEvent(self, event):
        self.link_pos = event.pos()
        # correct for scrolling
        self.link_pos.setX(self.link_pos.x() + self.horizontalScrollBar().value())
        self.link_pos.setY(self.link_pos.y() + self.verticalScrollBar().value())
        menu = self.createStandardContextMenu(self.link_pos)

        # do stuff to menu

        menu.popup(event.globalPos())

撰写回答