Sam
Sam

Reputation: 369

Customising location-sensitive context menu in QTextEdit

I am trying to adjust the context menu in a QTextEdit. I have succeeded in getting access to and then displaying the default menu with the following code:

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

However, this does not work for location-sensitive clicks. The case in question is the "Copy Link Location" item in a QTextBrowser's right click menu, which is only enabled if you right click on a link, for obvious reasons. I can't get it to ever be enabled. I suspect I am passing the wrong position to createStandardContextMenu, but I can't figure out the correct position to feed it.

I have tried both event.globalPos() and event.pos(), neither of which work. I also looked at the source code for QTextEdit, but didn't get anywhere. What position is it expecting?

Edit: Update: It appears the problem is the scrolling in the TextBrowser; if I scroll to the top of the window and use event.pos() it behaves. I don't have working code yet, but correcting for the scroll is the solution.

(Specifically, I want to disconnect the signal emitted by the Copy Link Location action and connect it to my own function so I can adjust the URL before copying it to the clipboard, allowing me to make links absolute and so forth before copying, and I have no particular desire to re-write the working bits.)

Upvotes: 1

Views: 1257

Answers (3)

Reg Edit
Reg Edit

Reputation: 114

Maybe you can try something like:

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

It's C++ but I'm sure that you can easy convert it to python.

Upvotes: 0

Sam
Sam

Reputation: 369

Here is the working transform of the coordinates:

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())

Upvotes: 1

reclosedev
reclosedev

Reputation: 9502

Try self.mapToGlobal(event.pos()), it should take into account scroll position.

Upvotes: 0

Related Questions